亚博智能论坛  
  
查看: 590|回复: 1

STM32时钟的两种配置方法

[复制链接]

该用户从未签到

18

主题

43

帖子

114

积分

新手上路

Rank: 1

积分
114
发表于 2017-8-17 15:50:29 | 显示全部楼层 |阅读模式
我所讲的时钟配置都是基于库函数,3.5版本的的标准库。
第一种是基于system_stm32f10x.c来配置的,这个文件就是完成时钟配置的,其他啥作用都没有。首先打开stm32的启动文件,就是那个汇编文件,定位到如下:
  1. ; Reset handler
  2. Reset_Handler   PROC
  3.     EXPORT  Reset_Handler             [WEAK]
  4.     IMPORT  __main
  5.     IMPORT  SystemInit
  6.     LDR     R0, =SystemInit
  7.     BLX     R0               
  8.    LDR     R0, =__main
  9.    BX      R0
  10.                 ENDP
复制代码
这是单片机复位处理部分,一旦复位,它首先定位到main函数部分,然后接着定位到system_stm32f10x.c里的SystemInit()函数,紧接着执行这个函数,完成时钟配置,在此之前,单片机用的都是内部高速时钟(HSI)。这个执行完后,紧接着开始执行C语言里的main函数。另外再告诉你一个小技巧,你可以将汇编语言里的main改成其他名称,让别人行不见你的主函数,当你下载了一个工程,发现里面并没有main函数,就要定位到这里看他把main改成啥了,然后再进行定位主函数。当然用这种方法配置时钟,需要在system_stm32f10x.c改一改,定位到如下代码处。

  1. #if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
  2.    /* #define SYSCLK_FREQ_HSE    HSE_VALUE */
  3.    #define SYSCLK_FREQ_24MHz  24000000
  4. #else
  5.    /*#define SYSCLK_FREQ_HSE  HSE_VALUE*/
  6.    /* #define SYSCLK_FREQ_24MHz  24000000 */
  7.    /* #define SYSCLK_FREQ_36MHz  36000000 */
  8.    /* #define SYSCLK_FREQ_48MHz  48000000 */
  9.    /* #define SYSCLK_FREQ_56MHz  56000000 */
  10.   #define SYSCLK_FREQ_72MHz  72000000
  11. #endif
复制代码
将#else下的/* #define SYSCLK_FREQ_HSE  HSE_VALUE*/取消注释,将HSE_VALUE改为外部晶振值,单位为Hz。
个别单片机要从#if defined下改,支持72M的在#else下改就可以了,比较常用的103系列在这下面改就行了。选什么时钟,就将该时钟的宏定义取消注释即可,注意只能选一个。第一种方法就介绍到这里。
第二种是基于stm32f10x_rcc.c配置的。配置方法如下:

  1. void RCC_Configuration()
  2. {
  3.     ErrorStatus HSEStartUpStatus;
  4.         RCC_DeInit();                                                         //重置时钟
  5.         RCC_HSEConfig(RCC_HSE_ON);                                            //外部晶振开
  6.         HSEStartUpStatus=RCC_WaitForHSEStartUp();
  7.         if(HSEStartUpStatus==SUCCESS)
  8.         {
  9.                 FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);             //预取值缓存使能
  10.                 FLASH_SetLatency(FLASH_Latency_2);                                //设置代码延时值
  11.                 RCC_HCLKConfig(RCC_SYSCLK_Div1);                                  //设置AHB时钟=系统时钟
  12.                 RCC_PCLK2Config(RCC_HCLK_Div1);                                   //设置APB=HCLK
  13.                 RCC_PCLK1Config(RCC_HCLK_Div2);                                   //APB1=HCLK/2
  14.                 RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9);                              //PLL频率等于外部晶振频率,倍频系数*9   72MHz
  15.                 RCC_PLLCmd(ENABLE);                                               //等待PLL初始化成功
  16.                 while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET);
  17.             RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);                         //选择PLL倍频后的时钟作为系统时钟;
  18.                 while(RCC_GetSYSCLKSource()!=0x08);                                //等待PLL倍频后的时钟作为系统时钟成功   
  19.     }
  20. }
复制代码
这个直接在主函数内调用一下,建议初始化时,main函数第一个调用它。这样方能和第一种方法统一起来。不过采用这种方法,将启动文件得要改改,就是将下面的汇编语句删除或者用分号注释掉,至于为什么这样做,理由后述。

  1. IMPORT  SystemInit
  2.                 LDR     R0, =SystemInit
  3.                 BLX     R0      
复制代码
最后说一下keil工程建立,采用第一种方法配置时钟时,工程必须包含system_stm32f10x.c和system_stm32f10x.h文件,但这种方式仅仅配置好了AHB时钟,剩下的APB等时钟还得要借用stm32f10x_rcc.c里面的函数来完成配置。
采用第二种方式,工程里不需要有system_stm32f10x.c和system_stm32f10x.h文件,只需要有stm32f10x_rcc.c文件就行了。要将汇编语言内有关 SystemInit语句注释或者删掉,要不然编译会报错,提示找不到SystemInit()。

回复

使用道具 举报

该用户从未签到

2

主题

6

帖子

16

积分

新手上路

Rank: 1

积分
16
发表于 2017-8-17 15:55:08 | 显示全部楼层
感谢楼主出山分享资料   学习了
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表