之前一直做STM32,写程序有个习惯,打框架的时候肯定都会留一个硬件定时器,拿来做系统心跳.
例如留了定时器Timer5.设置该定时器每10ms中断一次
然后另外建立一对叫HeartBeat.c以及HeartBeat.h的文件,然后在里面写一个叫void HeartBeat_IRQ_FUN(void)的函数
这个函数每10ms都会被Timer5的定时器中断运行一次,然后我就在这个函数里做一些功能的实现,拿一个点LED灯举例:
首先我会针对LED这个功能建立一对叫LED.c以及LED.h的文件,里面对外主要提供以下几个函数:
void LED_Init(void)//初始化LED,主要是对硬件的初始化,例如pin的相关设置
void LED_Set_Status(unsigned char status)//用于设置接下来LED的工作状态
void LED_HeartBeat_IRQ(void)//LED心跳处理函数
例如要实现LED闪烁指定次数,正常情况简单实现应该类似于:
void LED_Twinkle(unsigned char time)
{
for(unsigned char i=0;i<time;i++)
{
LED_ON();//点亮LED
delay_ms(200);//延时200ms
LED_ON();//熄灭LED
delay_ms(200);//延时200ms
}
}

但是如果使用系统心跳的方法,就可以这样:
unsigned char LED_Twinkle_Cnt=0;//LED闪烁次数计数
unsigned char LED_Status=0;//LED当前状态(点亮或熄灭)
unsigned char LED_HeartBeat_Time_Cnt=0;//LED的系统心跳时间计数(主要用于分频)
void LED_Twinkle(unsigned char time)
{
LED_Status=0;//假设0代表熄灭,1代表点亮
LED_OFF();//设置LED最初的状态
LED_Twinkle_Cnt=time;//设置剩余的闪烁次数
}

void LED_HeartBeat_IRQ(void)
{

/***************这一部分完成200ms的延时*****************/
if(LED_HeartBeat_Time_Cnt==20)//如果当前计数已经达到了
{
LED_HeartBeat_Time_Cnt=0;//清空计数
}
else
{
LED_HeartBeat_Time_Cnt++;//增加计数
return;
}
/*************************************************************/
if(LED_Twinkle_Cnt)//如果剩余的闪烁次数不等于0,说明有活干了
{
if(LED_Status)//如果当前LED是点亮的
{
LED_OFF();//熄灭LED
LED_Status=0;
}
else
{
LED_ON();//点亮LED
LED_Status=1;
}
LED_Twinkle_Cnt –;//减少一次剩余闪烁计数(这样实际上闪消耗两个计数,如果不想这样,最简单的方式可以在设置计数的时候X2来解决)
}
}

这样,把void LED_HeartBeat_IRQ(void)这个函数放入void HeartBeat_IRQ_FUN(void)中每10ms执行一次
然后在需要闪烁LED的时候调用void LED_Twinkle(unsigned char time)即可,因为这个命令是非阻塞的,所以灵活方便很多.