完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>
主要内容:
1)了解SystemInit()函数及其涉及的相关寄存器。 官方资料: 《STM32中文参考手册V10》第六章 复位和时钟控制 RCC 1. 基础知识: 1.1 SystemInit()函数申明位于system_stm32f10x.h头文件中,内容在system_stm32f10x.c文件中; 1.2 因为采用STM32F10X_HD,所以SystemInit()函数中部分函数不会运行。 2. 涉及主要寄存器: 3. SystemInit()函数解读: 备注:代码中符号 / / * *…* * / / 表示该代码实际在源函数中,但是不执行。 void SystemInit(void) { /*Reset the RCC clock configuration to the default reset state(for debug purpose)*/ /*Set HSI ON bit */ RCC->CR |= (uint32_t)0x00000001; /*时钟控制寄存器(RCC_CR),内部8MHz振荡器开启*/ /*Reset SW,SWS, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */ #ifndef STM32F10X_CL RCC->CFGR &= (uint32_t)0xF8FF0000; /*因为用STM32F10X_HD,所以运行这一行代码*/ #else //** RCC->CFGR &= (uint32_t)0xF0FF0000; **// /*不执行*/ #endif /*Reset HSEON, CSSON and PLLON bits */ RCC->CR &= (uint32_t)0xFEF6FFFF; /*将HSEON, CSSON 和 PLLON置0 */ /*Reset HSEBYP bit */ RCC->CR &= (uint32_t)0xFFFBFFFF; /* 将HSEBYP置0 */ /*Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */ RCC->CFGR &=(uint32_t)0xFF80FFFF; /*将PLLSRC,PLLXTPRE,PLLMUL,USBPRE/OTGFSPRE置0 */ #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; /*CIR时钟中断寄存器*/ #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 4. SetSysClock()函数解读: static void SetSysClock(void) { #ifdef SYSCLK_FREQ_HSE SetSysClockToHSE(); #elif defined SYSCLK_FREQ_24MHz SetSysClockTo24(); #elif defined SYSCLK_FREQ_36MHz SetSysClockTo36(); #elif defined SYSCLK_FREQ_48MHz SetSysClockTo48(); #elif defined SYSCLK_FREQ_56MHz SetSysClockTo56(); #elif defined SYSCLK_FREQ_72MHz SetSysClockTo72(); /*重点函数,只执行这一条函数*/ #endif 因为: /*#define SYSCLK_FREQ_HSE HSE_VALUE */ /*#define SYSCLK_FREQ_24MHz 24000000 */ /*#define SYSCLK_FREQ_36MHz 36000000 */ /*#define SYSCLK_FREQ_48MHz 48000000 */ /*#define SYSCLK_FREQ_56MHz 56000000 */ #define SYSCLK_FREQ_72MHz 72000000 /*只有这条激活*/ #endif 5. SetSysClockTo72()函数解读: static void SetSysClockTo72(void) { __IO uint32_t StartUpCounter = 0, HSEStatus = 0; /*SYSCLK, HCLK, PCLK2 and PCLK1 configuration ------------*/ /*Enable HSE */ RCC->CR |= ((uint32_t)RCC_CR_HSEON); /*对应#define RCC_CR_HSEON ((uint32_t)0x00010000),将HSEON置1*/ /* Wait till HSE is ready and if Time out is reached exit */ do { HSEStatus = RCC->CR & RCC_CR_HSERDY; /*对应#define RCC_CR_HSERDY ((uint32_t)0x00020000),读取HSERDY值,其值为1时外部振荡器就绪*/ StartUpCounter++; } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); /*对应#define HSE_STARTUP_TIMEOUT ((uint16_t)0x0500),当HSEStatus为0时,则没准备就绪,继续循环,只有当HSEStatus为1(即HSERDY值为1),或等于HSE_STARTUP_TIMEOUT(超时)时,跳出循环。*/ if ((RCC->CR & RCC_CR_HSERDY) !=RESET) /*如果CR值不等于0*/ { HSEStatus = (uint32_t)0x01; /*则,HSEStatus值为1*/ } else { HSEStatus = (uint32_t)0x00; /*否则,HSEStatus值为0*/ } if (HSEStatus == (uint32_t)0x01) /*如果,HSEStatus值为1,即HSE准备就绪*/ { /*Enable Prefetch Buffer */ FLASH->ACR |= FLASH_ACR_PRFTBE; /*对应/#define FLASH_ACR_PRFTBE ((uint8_t)0x10),启用预取缓冲区*/ /* Flash 2 wait state */ FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY); /*对应#define FLASH_ACR_LATENCY ((uint8_t)0x03),无解释*/ FLASH->ACR |=(uint32_t)FLASH_ACR_LATENCY_2; /*对应#define FLASH_ACR_LATENCY_2 ((uint8_t)0x02),两个等待状态*/ /*HCLK = SYSCLK */ RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; /*对应#define RCC_CFGR_HPRE_DIV1 ((uint32_t)0x00000000),即对AHP预分频执行不分频命令*/ /*PCLK2 = HCLK */ RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1; /*对应#define RCC_CFGR_PPRE2_DIV1 ((uint32_t)0x00000000),即对高速APB预分频(APB2)执行不分频命令*/ /*PCLK1 = HCLK/2 */ RCC->CFGR |=(uint32_t)RCC_CFGR_PPRE1_DIV2; /*对应#define RCC_CFGR_PPRE1_DIV2 ((uint32_t)0x00000400),即对低速APB预分频(APB1)执行2分频命令*/ #ifdefSTM32F10X_CL /* Configure PLLs ------------*/ /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */ /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 8 MHz */ //**RCC->CFGR2 &=(uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL | RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC);**// //**RCC->CFGR2|=(uint32_t)(RCC_CFGR2_PREDIV2_DIV5|RCC_CFGR2_PLL2MUL8|RCC_CFGR2_PREDIV1SRC_PLL2|RCC_CFGR2_PREDIV1_DIV5);**// /* Enable PLL2 */ //**RCC->CR |= RCC_CR_PLL2ON;**// /* Wait till PLL2 is ready */ //**while((RCC->CR & RCC_CR_PLL2RDY) == 0)**// //**{**// //**}**// /* PLL configuration: PLLCLK = PREDIV1 * 9 = 72 MHz */ //**RCC->CFGR &=(uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL);**// //**RCC->CFGR |=(uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1|RCC_CFGR_PLLMULL9); **// #else /* PLL configuration: PLLCLK = HSE * 9 = 72 MHz*/ RCC->CFGR &=(uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE |RCC_CFGR_PLLMULL)); /*对应#define RCC_CFGR_PLLSRC ((uint32_t)0x00010000);#define RCC_CFGR_PLLXTPRE ((uint32_t)0x00020000);#define RCC_CFGR_PLLMULL ((uint32_t)0x003C0000)*/ RCC->CFGR |=(uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9); /*对应#define RCC_CFGR_PLLSRC_HSE ((uint32_t)0x00010000);#define RCC_CFGR_PLLMULL9 ((uint32_t)0x001C0000) */ #endif /* STM32F10X_CL */ /*Enable PLL */ RCC->CR |= RCC_CR_PLLON; /*对应#define RCC_CR_PLLON ((uint32_t)0x01000000)*/ /*Wait till PLL is ready */ while((RCC->CR & RCC_CR_PLLRDY)== 0) /*对应#define RCC_CR_PLLRDY ((uint32_t)0x02000000)*/ { } /*Select PLL as system clock source */ RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); /*对应#define RCC_CFGR_SW ((uint32_t)0x00000003)*/ RCC->CFGR |=(uint32_t)RCC_CFGR_SW_PLL; /*对应#define RCC_CFGR_SW_PLL ((uint32_t)0x00000002)*/ /*Wait till PLL is used as system clock source */ while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08)/*对应#define RCC_CFGR_SWS ((uint32_t)0x0000000C)*/ { } } else { /* If HSE fails to start-up, the application will have wrong clock configuration. User can add here some code to deal with this error */ } } #endif 6. SystemInit()函数步骤解读: 1.1 RCC_CR //Set HSION bit,或运算// xxxx xxxx xxxx xxxx | xxxx xxxx xxxx xxx1 1.2 RCC_CFGR //Reset SW, SWS, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits,与运算 // xxxx x000 xxxx xxxx | 0000 0000 0000 0000 1.3 RCC_CR //Reset HSEON, CSSON and PLLON bits,与运算 // xxxx xxx0 xxxx 0xx0 | xxxx xxxx xxxx xxxx 1.4 RCC_CR //Reset HSEBYP bit,与运算 // xxxx xxxx xxxx x0xx | xxxx xxxx xxxx xxxx 1.5 RCC_CFGR //Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits,与运算 // xxxx xxxx x000 0000 | xxxx xxxx xxxx xxxx 1.6 RCC_CIR //Disable all interrupts and clear pending bits,=运算// 0000 0000 1001 1111 | 0000 0000 0000 0000 1.7 进入到SetSysClock()函数中; 1.8 进入到SetSysClockTo72()函数中; 1.9 设__IO uint32_t StartUpCounter = 0, HSEStatus = 0; 1.10 RCC->CR |= ((uint32_t)RCC_CR_HSEON); //RCC_CR_HSEON为0x00010000,将HSEON置1// xxxx xxxx xxxx xxx1 | xxxx xxxx xxxx xxxx 1.11 HSEStatus=RCC->CR & RCC_CR_HSERDY; //RCC_CR_HSERDY为0x00020000),将HSERDY值赋给HSEStatus// 0000 0000 0000 00x0 | 0000 0000 0000 0000 1.12 //若上一步读取的HSERDY为1时,或超时,继续下一步,否则,一直循环上一步// 1.13 ** if ((RCC->CR & RCC_CR_HSERDY) != RESET)** //若RCC_CR不为 0000 0000 0000 0000 | 0000 0000 0000 0000// HSEStatus = (uint32_t)0x01; //则,HSEStatus值为0x01// else HSEStatus = (uint32_t)0x00; //否则,HSEStatus值为0x00,即5.11步骤是因为超时跳出循环的// 1.14 if (HSEStatus == (uint32_t)0x01) //若HSEStatus值为0x01,即外部振荡器就绪,则进行如下步骤// 1.15 //再次申明,以下步骤仅在HSEStatus值为0x01时运行!// 1.16 FLASH->ACR |= FLASH_ACR_PRFTBE; //FLASH_ACR_PRFTBE为0x10),启用预取缓冲区// 1.17 **FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY); ** //FLASH_ACR_LATENCY为0000 0011,取非则为 1111 1100,因此与运算后,ACR为xxxx xx00先清零// FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2; //FLASH_ACR_LATENCY_2 为0000 0010,或运算后,ACR又变为xxxx xx10,再赋值,即两个等待状态// 1.18 RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; //RCC_CFGR_HPRE_DIV1为0x00000000),其实对原CFGR值无影响 // RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1; //RCC_CFGR_PPRE2_DIV1为0x00000000),其实对原CFGR值无影响// RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2; //RCC_CFGR_PPRE1_DIV2为0x00000400),或运算后,CFGR为xxxx xxxx xxxx xxxx | xxxx x1xx xxxx xxxx // 1.19 RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL)); //RCC_CFGR_PLLSRC为0x00010000);RCC_CFGR_PLLXTPRE为0x00020000);RCC_CFGR_PLLMULL 为0x003C0000),因此三个或之后为 0000 0000 0011 1111 | 0000 0000 0000 0000,取非后为 1111 1111 1100 0000 | 1111 1111 1111 1111,与运算后为 xxxx xxxx xx00 0000 | xxxx xxxx xxxx xxxx// RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9); //RCC_CFGR_PLLSRC_HSE为0000 0000 0000 0001 | 0000 0000 0000 0000);RCC_CFGR_PLLMULL9为0000 0000 0001 1100 | 0000 0000 0000 0000),两者或之后为 0000 0000 0001 1101 | 0000 0000 0000 0000,或运算后为xxxx xxxx xxx1 11x1 | xxxx xxxx xxxx xxxx // 1.20 RCC->CR |= RCC_CR_PLLON; //RCC_CR_PLLON为0x01000000,或运算xxxx xxx1 xxxx xxxx | xxxx xxxx xxxx xxxx // 1.21 **while((RCC->CR & RCC_CR_PLLRDY)== 0) ** //RCC_CR_PLLRDY为0000 0010 0000 0000 | 0000 0000 0000 0000,与运算后0000 00x0 0000 0000 | 0000 0000 0000 0000,当x为0时,即PLL未锁定,0==0,while循环继续,当x为1时,即PLL锁定,while循环跳出// 1.22 RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); //RCC_CFGR_SW 为0x00000003,取非后1111 1111 1111 1111 | 1111 1111 1111 1100,与运算后 xxxx xxxx xxxx xxxx | xxxx xxxx xxxx xx00// RCC->CFGR |=(uint32_t)RCC_CFGR_SW_PLL; // RCC_CFGR_SW_PLL为0x00000002,或运算后xxxx xxxx xxxx xxxx|xxxx xxxx xxxx xx10,即PLL输出作为系统时钟 // while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08) //RCC_CFGR_SWS为0x0000000C,与运算后CFGR为0000 0000 0000 0000 | 0000 0000 0000 xx00,当xx为10时,则SWS显示PLL输出作为系统时钟// 1.23 #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. // 7. 在启动文件startup_stm32f10x_hd.s中,有一段汇编代码: Reset_Handler PROC EXPORT Reset_Handler [WEAK] IMPORT __main IMPORT SystemInit LDR R0, =SystemInit BLX R0 LDR R0, =__main BX R0 ENDP 该汇编代码说明,在系统重置时,会先运行SystemInit函数,再运行main函数,这就是为什么main函数里一般没有SystemInit函数的原因。 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1142 浏览1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1167 浏览1 评论
596 浏览2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
445 浏览2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1072 浏览2 评论
1638浏览9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
305浏览4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
308浏览3评论
299浏览3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
274浏览3评论
小黑屋|手机版|Archiver|德赢Vwin官网(湘ICP备2023018690号)
GMT+8, 2024-8-25 12:01, Processed in 0.829762 second(s), Total 75, Slave 60 queries .
Powered by德赢Vwin官网 网
© 2015bbs.elecfans.com
关注我们的微信
下载发烧友APP
德赢Vwin官网 观察
版权所有 © 湖南华秋数字科技有限公司
德赢Vwin官网 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号