系统滴答定时器
1.1、简介
系统滴答定时器是属于内核的,通用、基础、高级定时器属于片上外设,今天来看的是内核的系统滴答定时器。是一个24位的向下计数器,时钟可以选择9MHZ的参考时钟和72MHZ的处理器时钟。
主要就是有三部分组成:控制计数最大值的重装载值,计数器,时钟源
核心就是计数器,根据计数器的时钟频率,一直计数,计数最大值,由重装载值决定。
比如时钟源为72MHZ时,计数器的技术频率为1秒钟记72000000个数。
此时想要定时器记录1MS的时间:重装载值72000 - 1;想要定时器记录1us的时间:重装载值 72-1,应为是从0开始计数,所以有-1操作。
1.2、系统滴答定时器相关寄存器
在这里先看一下相关的寄存器,对于理解有一定的帮助。后面是用库函数进行程序编写。
CTRL控制寄存器:用来选择时钟、控制定时器开关、以及是否产生中断,同时还有计数结束标志
第0为控制定时器的使能,第一位控制寄存器异常产生(在内核中名字不叫中断,叫异常),
第二位就是选择处理器时钟还是参考时钟。
LOAD就是设置重装载值的寄存器,也就是设置最大值。
1.3、系统定时器实现ms延时
首先进行对滴答定时器的初始化
SysTick->CTRL |= 1<<2; //设置时钟源为72Mhz的内核时钟
// SysTick->CTRL &= ~(1<<2); //设置时钟源为9Mhz的内核时钟
SysTick->CTRL |= 1<<1; //开启中断
SysTick->LOAD = 72000-1; //设置重装值
SysTick->CTRL |= 1; //开启定时器
NVIC_SetPriority(SysTick_IRQn,0xF);//设置定时器中断优先级
初始化完成后就是写ms延时函数了,首先写滴答定时器中断服务函数,因为下面只写ms级延时函数所以说中断服务函数就特别简单
uint32_t S_Time = 0;
void SysTick_Handler(void)
{
S_Time++;
}
ms延时函数,形参Time就是输入的想要延时的毫秒值。
//通过S_Time实现延时任意ms
void sysDelay_nms(uint32_t Time)
{
uint32_t Temp = Time+S_Time;
while(S_Time<Temp)
{}
}
系统滴答定时器就可以完成一些简单的非阻塞式编程,举个例子。
uint32_t S_Time = 0;
uint32_t LED_Time = 0;
uint32_t RGB_Time = 0;
uint32_t BEEP_Time = 0;
void SysTick_Handler(void)
{
BEEP_Time++;
RGB_Time++;
LED_Time++;
S_Time++;
}
在定时器文件中写入一些关于蜂鸣器,RGB灯,LED灯的相关延时,并进行外部声明。然后在主函数中写入以下操作就可完成对LED灯的非阻塞操作,
if(LED_Time >= 500)//约等于300ms执行一次
{
switch(flag)
{
case 0:LED1_ON();LED4_OFF();break;
case 1:LED2_ON();LED1_OFF();break;
case 2:LED3_ON();LED2_OFF();break;
case 3:LED4_ON();LED3_OFF();break;
}
flag++;
flag %= 4;
LED_Time = 0;
}
有兴趣的可以把蜂鸣器和RGB灯的非阻塞操作也实验一下。
系统滴答定时器的ms级延时和一些简单的非阻塞操作就分享到这里。过两天会再更新一下关于通用定时器的相关分享。