在前面推文的介绍中,我们知道STM32系统复位后首先进入SystemInit函数进行时钟的设置,然后进入主函数main。那么我们就来看下SystemInit()函数到底做了哪些操作,首先打开我们前面使用库函数编写的LED程序,在system_stm32f10x.c文件中可以找到SystemInit()函数,SystemInit()代码如下:void SystemInit (void){/* Reset the RCC clock configuration to the default reset state(for debug purpose) // Set HSION bit /RCC->CR |= (uint32_t)0x00000001;/ Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits /#IFndef STM32F10X_CLRCC->CFGR &= (uint32_t)0xF8FF0000;#elseRCC->CFGR &= (uint32_t)0xF0FF0000;#endif / STM32F10X_CL // Reset HSEON, CSSON and PLLON bits /RCC->CR &= (uint32_t)0xFEF6FFFF;/ Reset HSEBYP bit /RCC->CR &= (uint32_t)0xFFFBFFFF;/ Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits /RCC->CFGR &= (uint32_t)0xFF80FFFF;#ifdef STM32F10X_CL/ Reset PLL2ON and PLL3ON bits */RCC->CR &= (uint32_t)0xEBFFFFFF;/* Disable all interrupts and clear pending bits /RCC->CIR = 0x00FF0000;/ Reset CFGR2 register /RCC->CFGR2 = 0x00000000;#elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (definedSTM32F10X_HD_VL)/ Disable all interrupts and clear pending bits /RCC->CIR = 0x009F0000;/ Reset CFGR2 register /RCC->CFGR2 = 0x00000000;#else/ Disable all interrupts and clear pending bits /RCC->CIR = 0x009F0000;#endif / STM32F10X_CL /#if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (definedSTM32F10X_HD_VL)#ifdef DATA_IN_ExtSRAMSystemInit_ExtMemCtl();#endif / DATA_IN_ExtSRAM /#endif/ Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers // Configure the Flash Latency cycles and enable prefetch buffer /SetSysClock();#ifdef VECT_TAB_SRAMSCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; / Vector Table Relocation in Internal SRAM. /#elseSCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; / Vector Table Relocation inInternal FLASH. */#endif}SystemInit函数开始通过条件编译, 先复位RCC寄存器,同时通过设置CR寄存器的HSI时钟使能位来打开HSI时钟。默认情况下如果CR寄存器复位,是选择HSI作为系统时钟,这点大家可以查看RCC->CR寄存器相关位描述可以得知,当低两位配置为00的时候(复位之后),会选择HSI振荡器为系统时钟。也就是说,调用SystemInit函数之后,首先是选择HSI作为系统时钟。在设置完相关寄存器后才换成HSE作为系统时钟,接下来SystemInit函数内部会调用SetSysClock()函数。这个函数内部是根据宏定义设置系统时钟频率。函数如下:static void SetSysClock(void){#ifdef SYSCLK_FREQ_HSESetSysClockToHSE();#elif defined SYSCLK_FREQ_24MHzSetSysClockTo24();#elif defined SYSCLK_FREQ_36MHzSetSysClockTo36();#elif defined SYSCLK_FREQ_48MHzSetSysClockTo48();#elif defined SYSCLK_FREQ_56MHzSetSysClockTo56();#elif defined SYSCLK_FREQ_72MHzSetSysClockTo72();#endif}在system_stm32f10x.c文件的开头就有对此宏定义,系统默认的宏定义是72MHz,如下:#define SYSCLK_FREQ_72MHz 72000000如果你要设置为36MHz,只需要注释掉上面代码,然后加入下面代码即可:#define SYSCLK_FREQ_36MHz 36000000根据该函数内部实现过程可知,直接调用SetSysClockTo72()函数,此函数功能是将系统时钟SYSCLK设置为72M,AHB总线时钟设置为72M,APB2总线时钟设置为72M,APB1总线时钟设置为36M,PLL时钟设置为72M。函数具体实现大家可以打开库函数查看,这里我们就不截取出来。如果SystemInit内实现过程看不懂没有关系,大家只要知道SystemInit函数执行完,时钟大小设置如下:SYSCLK(系统时钟) =72MHzAHB 总线时钟(HCLK=SYSCLK) =72MHzAPB1 总线时钟(PCLK1=SYSCLK/2) =36MHzAPB2 总线时钟(PCLK2=SYSCLK/1) =72MHzPLL 主时钟 =72MHz在STM32中,这些时钟值是要熟悉的。 |
共2条
1/1 1 跳转至页
[经验] STM32入门系列-STM32时钟系统,时钟初始化配置函数
关键词: STM32 时钟 入门 初始化 系统
共2条
1/1 1 跳转至页
回复
有奖活动 | |
---|---|
【有奖活动】分享技术经验,兑换京东卡 | |
话不多说,快进群! | |
请大声喊出:我要开发板! | |
【有奖活动】EEPW网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |
打赏帖 | |
---|---|
vscode+cmake搭建雅特力AT32L021开发环境被打赏30分 | |
【换取逻辑分析仪】自制底板并驱动ArduinoNanoRP2040ConnectLCD扩展板被打赏47分 | |
【分享评测,赢取加热台】RISC-V GCC 内嵌汇编使用被打赏38分 | |
【换取逻辑分析仪】-基于ADI单片机MAX78000的简易MP3音乐播放器被打赏48分 | |
我想要一部加热台+树莓派PICO驱动AHT10被打赏38分 | |
【换取逻辑分析仪】-硬件SPI驱动OLED屏幕被打赏36分 | |
换逻辑分析仪+上下拉与多路选择器被打赏29分 | |
Let'sdo第3期任务合集被打赏50分 | |
换逻辑分析仪+Verilog三态门被打赏27分 | |
换逻辑分析仪+Verilog多输出门被打赏24分 |