完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
SystemInit()函数
SystemInit(),顾名思义就是一个初始化函数,值得一提的是,我们在main函数中确从来没有主动调用过这个函数,其原因是在执行main函数的时候,他会默认先执行SystemInit函数,所以就无需去调用这个函数了。 这个函数的功能是怎么实现的,我直接先贴源码,然后把有的部分着重说明一下,其实STM32官方库中已经有英文注释了,英语好的人直接就能看懂。 Sysvoid 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_CL //我们的芯片是HD大容量芯片,通过判定下面一条语句无效,执行else RCC-》CFGR &= (uint32_t)0xF8FF0000; #else RCC-》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) || (defined STM32F10X_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) || (defined STM32F10X_HD_VL) #ifdef DATA_IN_ExtSRAM SystemInit_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_SRAM SCB-》VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */ #else SCB-》VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */ #endif } temInit()的第一条语句是RCC-》CR |= (uint32_t)0x00000001; 在之前用寄存器点亮LED灯时,也用过类似的语句,它的目的是把RCC的CR寄存器的第0位配置成1,具体实现的作用要见STM32中文参考手册,如下图所示: 通过图片可以看出第一条语句的作用是打开HSI时钟源。 紧接着下一个语句是RCC-》CFGR &= (uint32_t)0xF0FF0000; 通过&=运算,对寄存器的0-15位和24-27位置0,同样是通过对比STM32中文参考手册的CR寄存器配置,其目的就是上面的注释, Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits,如下图所示: 总之SystemInit()就是一个初始化函数,具体怎么实现的功能,可以通过STM32中文参考手册了解。 SetSysClockTo72()函数 这个函数也是,英文学得好话直接就知道,这个函数的目的是使系统时钟设为72MHz,除了72MHz,系统时钟还可以设置为其他很多频率,如下面的代码。 S#ifdef SYSCLK_FREQ_HSE static void SetSysClockToHSE(void); //系统时钟直接采用HSE时钟源,8MHz #elif defined SYSCLK_FREQ_24MHz//各种系统时钟频率的设置函数 static void SetSysClockTo24(void); #elif defined SYSCLK_FREQ_36MHz static void SetSysClockTo36(void); #elif defined SYSCLK_FREQ_48MHz static void SetSysClockTo48(void); #elif defined SYSCLK_FREQ_56MHz static void SetSysClockTo56(void); #elif defined SYSCLK_FREQ_72MHz static void SetSysClockTo72(void); #endif etSysClockTo72()的代码太长了我就不直接贴了,大致思路和 SystemInit()函数一样,也是通过对比STM32中文参考手册来了解它具体实现的功能。 首先定义了两个变量,用于等会if语句判定用的 __IO uint32_t StartUpCounter = 0, HSEStatus = 0; 其次对CR寄存器进行配置,目的是开启HSE时钟 RCC-》CR |= ((uint32_t)RCC_CR_HSEON); 这里对RCC_CR_HSEON进行了宏定义,但是通过对比STM32中文参考手册发现功能确实是开启HSE时钟 #define RCC_CR_HSEON ((uint32_t)0x00010000) 其次是判定HSE时钟是否准备就绪, RCC_CR_HSERDY仍然是一个宏定义值,同样是通过配置CR寄存器的位17来判定HSE是否准备就绪。 do { HSEStatus = RCC-》CR & RCC_CR_HSERDY; StartUpCounter++; } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); 如果准备就绪了,就对之前设定的判定变量赋值,然后进行下一条语句 if ((RCC-》CR & RCC_CR_HSERDY) != RESET) { HSEStatus = (uint32_t)0x01; } else { HSEStatus = (uint32_t)0x00; } if语句判定,继续执行,这里的flash指的是闪存时间,具体可参考《STM32F10xxx闪存编程参考手册》,这里不过多描述(其实也不重要)。后面三条语句和前面一样是通过寄存器配置,实现的功能见注释。 if (HSEStatus == (uint32_t)0x01) { /* Enable Prefetch Buffer */ FLASH-》ACR |= FLASH_ACR_PRFTBE; /* Flash 2 wait state */ FLASH-》ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY); FLASH-》ACR |= (uint32_t)FLASH_ACR_LATENCY_2; /* HCLK = SYSCLK */ RCC-》CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; /* PCLK2 = HCLK */ RCC-》CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1; /* PCLK1 = HCLK/2 */ RCC-》CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2; 这里上一张图,三条语句要实现的三个功能分别是HCLK = SYSCLK, PCLK2 = HCLK,PCLK1 = HCLK/2,所以就要AHB和APB1不分频,APB2二分频,而CFGR这个寄存器就是设定分频系数的。 这段代码同样是配置寄存器,但是要注意的是,他用了一个或运算,将很多步骤同步完成了,实现的目的是: PLL configuration: PLLCLK = HSE * 9 = 72 MHz RCC-》CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL)); RCC-》CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9); |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1621 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1546 浏览 1 评论
980 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
686 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1599 浏览 2 评论
1865浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
648浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
517浏览 3评论
534浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
506浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-23 10:55 , Processed in 1.344422 second(s), Total 78, Slave 61 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号