STM32F4第一课:时钟配置之SystemInit
OK,学习stm32f4开始的第一个笔记。好吧,先打开第一个,led和按键的程序。从main函数开始,部分代码如下
1 int main(void) 2 { 3 uint8_t ucKeyCode; /* 按键代码 */ 4 5 bsp_Init(); /* 硬件初始化 */ 6 PrintfLogo(); /* 打印例程信息到串口1 */ 7 8 printf("LED4正在闪烁(闪烁频率 = 1Hz)\r\n"); 9 printf("按下K1键点亮LED1\r\n"); 10 printf("按下K2键点亮LED2\r\n"); 11 printf("按下K3键点亮LED3\r\n"); 12 printf("操作按键和摇杆会打印按键事件\r\n"); 13 14 bsp_StartAutoTimer(0, 500); /* 启动1个500ms的自动重装的定时器 */ 15 //·························· 16 //略 17 }
疑问来了,配置时钟的函数哪里去咧?原来由于ST固件库的启动文件已经执行了SystemInit() 函数,该函数CPU系统时钟的初始化,所以不必再次重复配置系统时钟。启动文件配置了CPU主时钟频率、内部Flash访问速度和可选的外部SRAM FSMC初始化。系统时钟缺省配置为168MHz,如果需要更改,可以修改 system_stm32f4xx.c 文件。
那么接下来,我们仔细看看SystemInit()这个函数。这个函数是在抚慰以后在调用main函数前被调用的,这个调用在startup_stm32f4xx.s文件里(我都觉得自己罗嗦了)。
言归正传,如下是SystemInit的代码(点开查看哦)。
1 /** 2 * @brief Setup the microcontroller system 3 * Initialize the Embedded Flash Interface, the PLL and update the 4 * SystemFrequency variable. 5 * @param None 6 * @retval None 7 */ 8 void SystemInit(void) 9 { 10 /* FPU settings ------------------------------------------------------------*/ 11 #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) 12 SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */ 13 #endif 14 /* Reset the RCC clock configuration to the default reset state ------------*/ 15 /* Set HSION bit */ 16 RCC->CR |= (uint32_t)0x00000001; 17 18 /* Reset CFGR register */ 19 RCC->CFGR = 0x00000000; 20 21 /* Reset HSEON, CSSON and PLLON bits */ 22 RCC->CR &= (uint32_t)0xFEF6FFFF; 23 24 /* Reset PLLCFGR register */ 25 RCC->PLLCFGR = 0x24003010; 26 27 /* Reset HSEBYP bit */ 28 RCC->CR &= (uint32_t)0xFFFBFFFF; 29 30 /* Disable all interrupts */ 31 RCC->CIR = 0x00000000; 32 33 #ifdef DATA_IN_ExtSRAM 34 SystemInit_ExtMemCtl(); 35 #endif /* DATA_IN_ExtSRAM */ 36 37 /* Configure the System clock source, PLL Multiplier and Divider factors, 38 AHB/APBx prescalers and Flash settings ----------------------------------*/ 39 SetSysClock(); 40 41 /* Configure the Vector Table location add offset address ------------------*/ 42 #ifdef VECT_TAB_SRAM 43 SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */ 44 #else 45 SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */ 46 #endif 47 }
注释说的很清楚,这个函数大体分为 4 部分。
1.设置FPU,这玩意F4新加上的,浮点运算的玩意,不懂,略过·
2.重置RCC时钟配置默认的复位状态(拗口··就是恢复出厂设置 的 设置,不过这个设置你不爽可以自己修改)ps:红配绿冒傻气
NOTE①:需要注意一下,我们重启机器后,都应该使用默认时钟 HSI(F4的内置16MHz RC振荡器),让它先起振.而后如果我们需要如果需要使用 外部时钟 作为时钟源,也不是马上就能切换,需要等待对应的时钟源 是否READY 了。为啥?因为你用人家的频率,起码等待它稳定吧。这一点 就是 CR寄存器,就绪标志位存在的意义!!!
NOTE②:再看看这个小函数,假如有外部ram,就需要注意一下喽,配置FSMC用于外部SRAM,如下
1 #ifdef DATA_IN_ExtSRAM 2 SystemInit_ExtMemCtl(); 3 #endif
3.配置 System Clock 的时钟源(3个哦,HSI,HSE,PLLCLK)、PLL的倍频和分频因子、APB和AHBx的预分频系数、FLASH的设置,时序啦,延时周期和使能预取缓冲期····
好吧,这个功能是由一个函数完成的。代码如下:
1 static void SetSysClock(void) 2 { 3 /******************************************************************************/ 4 /* PLL (clocked by HSE) used as System clock source */ 5 /******************************************************************************/ 6 __IO uint32_t StartUpCounter = 0, HSEStatus = 0; 7 8 /* Enable HSE */ 9 RCC->CR |= ((uint32_t)RCC_CR_HSEON); 10 11 /* Wait till HSE is ready and if Time out is reached exit */ 12 do 13 { 14 HSEStatus = RCC->CR & RCC_CR_HSERDY; 15 StartUpCounter++; 16 } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); 17 18 if ((RCC->CR & RCC_CR_HSERDY) != RESET) 19 { 20 HSEStatus = (uint32_t)0x01; 21 } 22 else 23 { 24 HSEStatus = (uint32_t)0x00; 25 } 26 27 if (HSEStatus == (uint32_t)0x01) 28 { 29 /* Select regulator voltage output Scale 1 mode, System frequency up to 168 MHz */ 30 RCC->APB1ENR |= RCC_APB1ENR_PWREN; 31 PWR->CR |= PWR_CR_VOS; 32 33 /* HCLK = SYSCLK / 1*/ 34 RCC->CFGR |= RCC_CFGR_HPRE_DIV1; 35 36 /* PCLK2 = HCLK / 2*/ 37 RCC->CFGR |= RCC_CFGR_PPRE2_DIV2; 38 39 /* PCLK1 = HCLK / 4*/ 40 RCC->CFGR |= RCC_CFGR_PPRE1_DIV4; 41 42 /* Configure the main PLL */ 43 RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) | 44 (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24); 45 46 /* Enable the main PLL */ 47 RCC->CR |= RCC_CR_PLLON; 48 49 /* Wait till the main PLL is ready */ 50 while((RCC->CR & RCC_CR_PLLRDY) == 0) 51 { 52 } 53 54 /* Configure Flash prefetch, Instruction cache, Data cache and wait state */ 55 FLASH->ACR = FLASH_ACR_PRFTEN |FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS; 56 57 /* Select the main PLL as system clock source */ 58 RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); 59 RCC->CFGR |= RCC_CFGR_SW_PLL; 60 61 /* Wait till the main PLL is used as system clock source */ 62 while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL); 63 { 64 } 65 } 66 else 67 { /* If HSE fails to start-up, the application will have wrong clock 68 configuration. User can add here some code to deal with this error */ 69 } 70 71 }
作为一个新时代四有青年,注释说的是太清楚了。不解释了
4.设置 Vector(中断向量表?)的位置,就是重定向。关于重定向的问题,是 CORTEX-M4内核的知识。
1 #ifdef VECT_TAB_SRAM 2 SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */ 3 #else 4 SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */ 5 #endif
需要注意的是。 system_stm32f4xx.c是可以修改的。这在开篇就说过了。所以我们需要什么功能需要按照我们的意愿修改。
下面的几点是 在 stm32f4 的 1.01库里面的。无论是上面说的还是没说的,不想翻译了。留个记号。以后看
1. This file provides two functions and one global variable to be called from
* user application:
* - SystemInit():
* - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
* by the user application to setup the SysTick
* timer or configure other parameters.
*
* - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
* be called whenever the core clock is changed
* during program execution.
*
* 2. After each device reset the HSI (16 MHz) is used as system clock source.
* Then SystemInit() function is called, in "startup_stm32f4xx.s" file, to
* configure the system clock before to branch to main program.
*
* 3. If the system clock source selected by user fails to startup, the SystemInit()
* function will do nothing and HSI still used as system clock source. User can
* add some code to deal with this issue inside the SetSysClock() function.
*
* 4. The default value of HSE crystal is set to 25MHz, refer to "HSE_VALUE" define
* in "stm32f4xx.h" file. When HSE is used as system clock source, directly or
* through PLL, and you are using different crystal you have to adapt the HSE
* value to your own configuration.
*
完工,好累。明天写stm32f4的 GPIO····
posted on 2013-09-07 21:06 イケメンおっさん_汪汪 阅读(3092) 评论(0) 收藏 举报
浙公网安备 33010602011771号