5.STM32F407ZG时钟系统及定时器SYSTICK的使用

1.系统时钟树:

LSI:低速内部时钟(RC震荡器),32kHz,提供低功耗时钟,用于看门狗和自动唤醒单元。

LSE:低速外部时钟,外接32.768kHz的石英晶体。

HSI:高速内部时钟16MHz,RC振荡器,精度不高,可用作系统时钟或PLL输入。

HSE:高速外部时钟4~26MHz,外接石英/陶瓷谐振器或外部时钟源。

PLL:锁相环倍频输出,包括主PLL(生成高速系统时钟168MHz和生成USB等的时钟48MHz)和专用PLLI2S(生成精确时钟,在I2S接口实现高品质音频性能)。

             

总结:STM32有5个时钟来源,HSI,HSE,LSI,LSE,PLL。 系统时钟SYSCLK有3个时钟来源,HSI,HSE和PLL。

STM32时钟信号输出MCO1(PA8)和MCO2(PA9),最大输出不超过100MHz。任何一个外设在使用前必须使能相应的时钟。

2.相关库函数

a.时钟使能函数:RCC_HSICmd,RCC_LSICmd,RCC_PLLCmd等等;

b.时钟源和相关配置函数:RCC_HSEConfig,RCC_LSEConfig,RCC_PLLConfig,RCC_SYSCLKConfig等等;

c.外设复位函数:RCC_AHB1PeriphResetCmd,RCC_APB2PeriphResetCmd等等;

d.状态参数获取函数:RCC_GetSYSCLKSource,RCC_GetClocksFreq,RCC_GetFlagStatus等等;

e.RCC中断相关函数:RCC_ITConfig,RCC_GetITStatus等等。

启动文件中运行main()之前,会先运行SystemInit()进行系统时钟的初始化配置,使能HSE(在stm32f4.h中定义了外部晶振频率为HSE_VALUE   ((uint32_t)8000000)),然后进行分频系数的配置(M=8,N=336,P=2,Q=7),最终选择PLL作为系统时钟源。

初始化后: SYSCLK(系统时钟):168MHz       AHB:168MHz       APB1: 42MHz          APB2: 84MHz       PLL: 168MHz

3.SysTick时钟

SysTick属于ARM Cortex-M3内核的一个“内设”,是一个拥有24位数据宽度的倒计数定时器,通常用来做延时或实时系统的心跳时钟,节省资源。从时钟源接口获取时钟驱动,在时钟驱动下进行减一计数,减到0时触发SysTick中断。

相关函数: SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource)   选择Systick时钟源

                   SysTick_Config(uint32_t ticks)  初始化Systick并开启中断, ticks为每隔多少个周期响应一次中断。

思路:利用systick定时器为递减计数器,设定初值并使能它后,它会每个1系统时钟周期计数器减,计数到 0时,SysTick计数器自动重装初值并继续计数,同时触发中断。那么每次计数器减到0,时间经过了:系统时钟周期 *计数器初值。

采用SysTick_CLKSource_HCLK_Div8作为SysTick的时钟源,频率为21MHz,即每个周期用时1/21M。设置计数器初值为21,则每隔1/21M*21=1us就产生一次中断。

3.代码实现

delay.h

#ifndef __DELAY_H
#define __DELAY_H
#include <stm32f4xx.h>

void Delay_Init(void);
void Delay_ms(u32 nms);
void Delay_us(u32 nus);
extern void SysTick_Count(void);

#endif

delay.c

#include <delay.h>

static u32 delaytime=0;

void Delay_Init(void){	
	SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
	SysTick_Config(21);//every 1us create an interrupt
}

void Delay_ms(u32 nms){
	delaytime=nms*1000;
	while(!delaytime);
}


void Delay_us(u32 nus){
	delaytime=nus;
	while(!delaytime);
}

extern void SysTick_Count(void){
	while(!delaytime){
		delaytime--;
	}
}

每1us产生中断,调用SysTick_Handler()函数,对延时参数nus或nms进行处理。

注意在SysTick_Handler()的修改。

void SysTick_Handler(void)
{
  SysTick_Count(); 
}

                    

猜你喜欢

转载自blog.csdn.net/weixin_42480952/article/details/82596429