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 }
SystemInit

 

 

 

  注释说的很清楚,这个函数大体分为 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 }
SetSysClock

 

 作为一个新时代四有青年,注释说的是太清楚了。不解释了

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)    收藏  举报

导航