STM32时钟系统,延时函数

 STM32F4时钟树

6b170c581c4c4727ac51f21e9248573b.png

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:

主PLL(PLL)由HSE或者HSI提供时钟信号,并具有两个不同的输出时钟。
第一个输出PLLP用于生成高速的系统时钟(最高168MHz)
第二个输出PLLQ用于生成USB OTG FS的时钟(48MHz),随机数发生器的时钟和SDIO时钟。
专用PLL(PLLI2S)用于生成精确时钟,从而在I2S接口实现高品质音频性能。

 2. 系统时钟SYSCLK可来源于三个时钟源:
        ①、HSI振荡器时钟

        ②、HSE振荡器时钟

        ③、PLL时钟

3.STM32F4时钟信号输出MCO1(PA8)和MCO2(PC9)。

MCO1:用户可以配置预分频器(1~5)向MCO1引脚PA8输出4个不同的时钟源:
HIS,LSE,HSE,PLL
MCO2:用户可以配置预分频器(1~5)向MCO2引脚PC9输出4个不同的时钟源:
HSE,PLL,SYSCLK,PLLI2S

  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滴答定时器

Systick定时器常用来做延时,或者实时系统的心跳时钟。这样可以节省MCU资源,不用浪费一个定时器。
Systick定时器就是系统滴答定时器,一个24 位的倒计数定时器,计到0 时,将从RELOAD 寄存器中自动重装载定时初值。只要不把它在SysTick 控制及状态寄存器中的使能位清除,就永不停息,即使在睡眠模式下也能工作。
SysTick定时器被捆绑在NVIC中,用于产生SYSTICK异常(异常号:15)。
Systick中断的优先级也可以设置。
Systick的四个寄存器:

CTRL             SysTick 控制和状态寄存器 
LOAD             SysTick 自动重装载除值寄存器 
VAL                SysTick 当前值寄存器 
CALIB            SysTick 校准值寄存器

SysTick 控制和状态寄存器CTRL
532e1f6f03bb46c9b300aebd6608313a.png

SysTick 重装载数值寄存器LOAD0fb568f82f6c414798494ade643461b5.png SysTick 当前值寄存器VALb7b6c63d5b09471b935c5284b4c8f719.png

    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);
	}
}

运行结果

延时函数

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值