STM32F4时钟树
1. STM32 有5个时钟源:HSI、HSE、LSI、LSE、PLL。
①、HSI是高速内部时钟,RC振荡器,频率为16MHz,精度不高。可以直接作为系统
时钟或者用作PLL时钟输入。
②、HSE是高速外部时钟,可接石英/陶瓷谐振器,或者接外部时钟源,频率范围为4MHz~26MHz。
③、LSI是低速内部时钟,RC振荡器,频率为32kHz,提供低功耗时钟。主要供独立看 门狗和自动唤醒单元使用。
④、LSE是低速外部时钟,接频率为32.768kHz的石英晶体。RTC
⑤、PLL为锁相环倍频输出。STM32F4有两个PLL:
2. 系统时钟SYSCLK可来源于三个时钟源:
①、HSI振荡器时钟
②、HSE振荡器时钟
③、PLL时钟
3.STM32F4时钟信号输出MCO1(PA8)和MCO2(PC9)。
MCO最大输出时钟不超过100MHz
4.任何一个外设在使用之前,必须首先使能其相应的时钟。
5.我们的外部晶振选择 8MHz。当设置相应的分频器 M=8,倍频器倍频系数 N=336, 分频器分频系数 P=2,那么主 PLL 生成的第一个输出高速时钟 PLLP 为:
PLL=8MHz * N/ (M*P)=8MHz* 336 /(8*2) = 168MHz
STM32F4时钟初始化设置
STM32F4 时钟系统初始化是在 system_stm32f4xx.c 中的 SystemInit()函数中完成的。对于系统时钟关键寄存器设置主要是在 SystemInit 函数中调用 SetSysClock()函数来设置的。SystemInit 函数开始先进行浮点运算单元设置,然后是复位 PLLCFGR,CFGR 寄存器,同时 通过设置 CR 寄存器的 HSI 时钟使能位来打开 HSI 时钟。在设置完相关寄存器后,接下来 SystemInit 函数内部会调用 SetSysClock 函数。这段代码的流程:先使能外部时钟 HSE,等待 HSE 稳定之后,配置 AHB,APB1,APB2 时钟相关的分频因子。等待这些都配置完成之后, 打开主 PLL 时钟,然后设置主 PLL 作为系统时钟 SYSCLK 时钟源。如果 HSE 不能达到就绪状 态(比如外部晶振不能稳定或者没有外部晶振),那么依然会是 HSI 作为系统时钟。
STM32F4 时钟使能和配置
外设时钟使能函数
void RCC_AHB1PeriphClockCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState);
void RCC_AHB2PeriphClockCmd(uint32_t RCC_AHB2Periph, FunctionalState NewState);
void RCC_AHB3PeriphClockCmd(uint32_t RCC_AHB3Periph, FunctionalState NewState);
void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);
void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);
时钟源使能函数
void RCC_HSICmd(FunctionalState NewState);
void RCC_LSICmd(FunctionalState NewState);
void RCC_PLLCmd(FunctionalState NewState);
void RCC_PLLI2SCmd(FunctionalState NewState);
void RCC_PLLSAICmd(FunctionalState NewState);
void RCC_RTCCLKCmd(FunctionalState NewState);
时钟源选择和分频因子配置函数。这些函数 是用来选择相应的时钟源以及配置相应的时钟分频系数。时钟源配置函数
void RCC_LSEConfig(uint8_t RCC_LSE);
void RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource);
void RCC_HCLKConfig(uint32_t RCC_SYSCLK);
void RCC_PCLK1Config(uint32_t RCC_HCLK);
void RCC_PCLK2Config(uint32_t RCC_HCLK);
void RCC_RTCCLKConfig(uint32_t RCC_RTCCLKSource);
void RCC_PLLConfig(uint32_t RCC_PLLSource, uint32_t PLLM,
uint32_t PLLN, uint32_t PLLP, uint32_t PLLQ);
Systick滴答定时器
CTRL SysTick 控制和状态寄存器
LOAD SysTick 自动重装载除值寄存器
VAL SysTick 当前值寄存器
CALIB SysTick 校准值寄存器
SysTick 重装载数值寄存器LOAD SysTick 当前值寄存器VAL
SysTick_CLKSourceConfig() //Systick时钟源选择 misc.c文件中
SysTick_Config(uint32_t ticks) //初始化systick,时钟为HCLK,并开启中断
如果使用中发现延时不一致,问题一般都是因为不同内核时钟不一样而已。修改ticks值即可。
延时函数编写
void _delay(u32 ns)
{
SysTick->CTRL&=~(1<<2);
SysTick->VAL=0x00;
SysTick->CTRL&=~(1<<1);
SysTick->LOAD=ns*21;
SysTick->CTRL|=1<<0;
while(!(SysTick->CTRL&1<<16));
SysTick->VAL=0x00;
SysTick->CTRL&=~(1<<0);
}
void delay(u32 ns)
{
int i;
for(i=0;i<ns;i++)
_delay(1000);
}
int main(void)
{
delay_init(168);
LED_Init();
while(1)
{
PFout(9)=1;
delay_ms(1000);
PFout(9)=0;
delay(1000);
}
}
运行结果
延时函数