电子说
STM32处理器有一个24位的系统滴答定时器SysTick,它从重新加载值开始倒数到0,然后在下一个时钟边缘重新加载(包装到)STK_LOAD寄存器中的值,然后在随后的时钟上倒数。
计数标志位COUNTFLAG在系统控制和状态寄存器STK_CTRL的16位,当计时器减计数到0时,返回1。
时钟源选择位CLKSOURCE在系统控制和状态寄存器STK_CTRL的2位,赋值为0时为8分频,赋值为1时为1分频。想要计数速度更快可以选择1分频的时钟源。
SysTick异常请求允许位TICKINT在系统控制和状态寄存器STK_CTRL的1位,赋值为0时禁止异常请求,赋值为1时允许异常请求。软件可以使用COUNTFLAG来判断SysTick是否曾经被计数为零。
计数使能位在系统控制和状态寄存器STK_CTRL的0位,赋值0时禁止计数,赋值1时使能计数。
重装载值RELOAD在SysTick重载值寄存器STK_LOAD的0~23位,加载寄存器指定在启用计数器时和计数器达到0时加载到当前值寄存器STK_VAL的起始值。
当前的计数器值CURRENT在当前值寄存器STK_VAL的1~23位。前值寄存器STK_VALSysTick计数器的当前值。读取返回SysTick计数器的当前值。任何值的写入都会将字段清除为0,并将STK_CTRL寄存器中的COUNTFLAG位清除为0。
查询us、ms延时函数
void Systick_Delayus(u32 us)
{
SysTick- >CTRL &=~ (1< < 2); //选择时钟源,8分频
SysTick- >LOAD = 21*us - 1; //赋值装载值
SysTick- >VAL = 0; //清除当前值
SysTick- >CTRL |= 1< < 0; //使能计数器
while((SysTick- >CTRL & (1< < 16)) == 0); //判断计数是否结束
SysTick- >CTRL &=~ (1< < 0); //禁止计数器
}
void Systick_Delayms(u16 ms)
{
Systick_Delayus(ms * 1000);
}
从时钟树可以知道,系统时钟168Mhz,8分频后得到滴答定时器时钟为21Mhz,装载值(需要延时时间)可根据时钟频率计算求得,每秒可计数21000000次,每微秒可计数21次。装载值和当前值都是24位,最大为16777215,最大微秒定时798915us,最大毫秒定时798ms。
结合LED灯和Systick定时让LED灯500ms闪烁一次,主函数为
#include "stm32f4xx.h"
#include "led.h"
#include "delay.h"
int main()
{
LED_Init(); //初始化LED灯
while(1) //点亮或熄灭LED灯
{
GPIOH- >ODR &=~ (0x01< < 10); //输出为0,led灯亮
GPIOH- >ODR &=~ (0x01< < 11); //输出为0,led灯亮
Systick_Delayus(500000);
GPIOH- >ODR |= (0x01< < 10); //输出为1,led灯灭
GPIOH- >ODR |= (0x01< < 11); //输出为1,led灯灭
Systick_Delayms(500);
}
}
编译成功后将程序烧入,LED每500ms闪烁一次,Systick查询定时成功。
全部0条评论
快来发表一下你的评论吧 !