Sysclk的配置
1、时钟初始化流程
一般流程为startup_mm32f3273g.s中调用system_mm32f3273g.c中的SystemInit函数完成系统时钟的初始,而system_mm32f3273g.c中函数是空的。
原来MindSdk时钟初始化的流程放到了clock_init.c中。
2、采用外部高速时钟源
先弄清几个概念:
HSE (外部高速时钟信号)
HSI (芯片内部时钟信号)
LSE (外部低速时钟信号)
LSI (内部低速时钟信号)
PLL (锁相环)因为HSE HSI的频率都不是太高,所以ARM设计了PLL(锁相环)来进行倍频,把HSI和HSE频率拉高到百兆以上。
SycClk (系统时钟)
HCLK (AHB的时钟)
HCLK1 (APB1的时钟)
HCLK2 (APB2的时钟)
设置系统时钟SYSCLK、设置AHB分频因子(决定HCLK是多少)、设置APB2分频因子(设定PCLK2等于多少)、设置APB1分频因子(决定PCLK1等于多少);
火龙果mm32F3273开发板外接12M晶振,因此这里我们采用HSE+PLL的方式作为开发板的时钟输入信号。
3、时钟设置
关于PLL使能与设置,芯片手册上是这样写的。
而PLL输出时钟与输入时钟的关系如图:
假设我们PLLDIV设置1分频,输入时钟12M,想要获得的PLL输出时钟为120M,那么PLLMUN应为设置为19。
而PLL设置的寄存器如下:
代码中关于pll的设置如下:
/* enable HSE. */
RCC->CR |= RCC_CR_HSEON_MASK;
while ( RCC_CR_HSERDY_MASK != (RCC->CR & RCC_CR_HSERDY_MASK) )
{
}
RCC->PLLCFGR = RCC_PLLCFGR_PLLSRC(1) /* (pllsrc == 1) ? HSE : HSI. */
| RCC_PLLCFGR_PLLMUL(19) /* (12 * (19 + 1)) / 2 = 120. */
| RCC_PLLCFGR_PLLDIV(1) /*PLL分频系数*/
| RCC_PLLCFGR_PLLLDS(1) /*这个寄存器是个保留的,不设置亦可*/
| RCC_PLLCFGR_PLLICTRL(3) /*PLL Charge Pump电流控制信号*/
;
/* Enable PLL. */
RCC->CR |= RCC_CR_PLLON_MASK;
while((RCC->CR & RCC_CR_PLLRDY_MASK) == 0)
{
}
PLL设置完成,我们接下来要设置sysclk hclk hclk1 hclk2的时钟。
一般SYSCLK=PLLCLK=120MHz
HCLK,也就是AHB CLK,这里设置为1分频,即=SYSCLK=120M.
HCLK1,也就是APB1CLK,这里设置2分频,即=HCLK/2=60M。
HCLK2,也就是APB2CLK,这里设置2分频,即=HCLK/2=60M。
相关寄存器设置如图:
相关设置代码如下:
/* Setup the dividers for each bus. */
RCC->CFGR = RCC_CFGR_HPRE(0) /* div=1 for AHB freq. */
| RCC_CFGR_PPRE1(0x4) /* div=2 for APB1 freq. */
| RCC_CFGR_PPRE2(0x4) /* div=2 for APB2 freq. */
| RCC_CFGR_MCO(7) /* use PLL/2 as output. */
;
/* Switch the system clock source to PLL. */
RCC->CFGR = (RCC->CFGR & ~RCC_CFGR_SW_MASK) | RCC_CFGR_SW(2); /* use PLL as SYSCLK */
/* Wait till PLL is used as system clock source. */
while ( (RCC->CFGR & RCC_CFGR_SWS_MASK) != RCC_CFGR_SWS(2) )
{
}
至此,经过上面设置,我们将开发板设置成了120M的时钟。