STM32的Systick滴答定时器

匿名 (未验证) 提交于 2019-12-03 00:37:01

一、Systick滴答定时器是什么东东?

Systick

MCUUCOSSTM32+UCOSSystickUCOS

Systick一般用来做延时,精确延时。

一共4个Systick寄存器

三、systick定时器原理

这个定时器是设置一个初值,然后这个初值减数到0,就是定时完成,完成之后可以产生中断,也可以不使用中断。

0位是使能位,可以使能或者使能定时器
1位是使能中断位,减数结束之后是否产生中断。
2位是时钟选择位,可以选择外部的或者内部时钟作为时钟源。
16位是标志位,减数到0之后该位被置位1,读取过后自动清清零。
------------------------------------------------------------------------------------------------------------
四、u重装载数值寄存器-LOAD

当当前值寄存器减数到0,自动会将把这个RELOAD的值赋给当前值寄存器。
if(VAL == 0)
VAL就是从初值(RELOAD)一直减一,倒数到0的时候,重新将初值(RELOAD)赋给VAL。


六、滴答定时器的实现

对于STM32,外部时钟源是HCLK(AHB总线时钟)的1/8内核时钟是HCLK时钟

1、选择时钟源

misc.c


初始化systick,时钟为HCLK,并开启中断 core_cm4.h文件中


2、编写延时函数

3、设置中断优先级分组

七、用中断的方式实现delay延时
Systick中断服务函数:void SysTick_Handler(void);



-----------------------------------------------------------------------------------------------------------------

注意:

如果使用中发现延时不一致,问题一般都是因为不同内核时钟不一样而已。修改ticks值即可。

-----------------------------------------------------------------------------------------------------------------

参考代码如下:

void init_delay(void)
{
/*我们外部晶振为8MHz,然后倍频到168M,
那么Systick时钟即为21M,也就是Systick的计数器
VAL每减1就代表过了1/21us*/

//1.选择时钟源(选择外部时钟)
//外部时钟要/8,内部始终不用
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//2.编写延时函数
//最大延时不超过798.915ms
//即(2^24)/21/1000
void delay_us(u32 nus)
{
u32 temp = 0;

//1、实现1us*nus的延时
//21外是外部时钟频率,如果选择内部时钟就是168M/8
SysTick->LOAD = 21*nus;//设置自动装载值为21(1us)
SysTick->VAL = 0x00;//设置当前初值为0
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; // 开启(使能)计数:使能SysTick定时器

do
{
//读取控制寄存器
temp = SysTick->CTRL;
}while(!(temp & (1<<16)));//等待计数时间到达(位16)

SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; // 关闭(失能)计数
SysTick->VAL = 0x00;//再设置当前初值为0,重置VAL
}
///////////////////////////////////////////////////////////////////////////////////////////
void delay_ms(u32 nms)
{
u32 temp = 0;

//1、实现1us*nus的延时
SysTick->LOAD = 21000*nms;//设置自动装载值为21(1us)
SysTick->VAL = 0x00;//设置当前初值为0
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; // 开启(使能)计数

do
{
//读取控制寄存器
temp = SysTick->CTRL;
}while(!(temp & (1<<16)));

SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; // 关闭(失能)计数
SysTick->VAL = 0x00;//再设置当前初值为0
}
//////////////////////////////////////////////////////////////////////////////////////////////////
void delay_s(u32 s)
{
while(s--)
{
delay_ms(500);
delay_ms(500);
}
}

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!