在上一篇里,笔者跟大家介绍了如何使用定时器来控制输出口,这一篇里,笔者要用另一种方式来使用定时器达到控制效果。在上一篇中, 我们是在定时器配置完之后,让定时器一直开启,同时在定时器里面使用一个中断一直在计数,或许有些读者就会在想了,Time_Cnt这个变量一直在计数,他累不累啊:lol,我们能不能只有在要用到他的时候再让他计数呢?当然可以!有两种方法,一是通过控制定时器的使能标志位TR0来实现,二是通过控制用一个标志位来实现。在这里笔者就不跟大家介绍TR0的控制方式了,而是用第二种方式来实现,还是用上一讲定义的OUT_CTR这个位变量来控制吧。
程序的思路是这样的:在主函数中,当IN00有信号输入的时候,让标志位OUT_CTR置1,在定时器中断函数中,当OUT_CTR为1的时候,再让Time_Cnt开始计数;主函数中检测Time_Cnt的值,达到指定的值后(本例为1秒),开始让OUT00输出ON,同时需要将Time_Cnt计数清零;在第二次当IN00有信号输入的时候,让OUT00输出OFF,第四次的时候OUT00输出ON,第三次的时候OUT00输出OFF,……,如此循环。
那么,我们先来看定时器中断中代码的实现:
/********************* Timer0中断函数************************/
void timer0_int (void) interrupt TIMER0_VECTOR //1ms
{
if(OUT_CTR)
{
Time_Cnt ++;
}
}
这个其实是很简单的,就不再多说了,接下来看下主函数功能的实现:
void main(void)
{
OUT00 = OFF;
OUT01 = OFF;
OUT02 = OFF;
OUT03 = OFF;
OUT04 = OFF;
OUT05 = OFF;
delay_ms(1000); //延时大约1秒,等待电源稳定
Timer_config(); //定时器配置
GPIO_config(); //GPIO配置
EA = 1; //开启总中断
Time_Cnt = 0;
OUT_CTR = 0;
Num = 0;
while(1)
{
if((!IN00)&&(!OUT_CTR))
{
delay_ms(20);//20MS消抖
if((!IN00)&&(!OUT_CTR))
{
OUT_CTR = 1;
}
}
if(Time_Cnt>=1000) //1000ms
{
Time_Cnt = 0; //清除计数
if(Num == 0) //IN00第一次按下,OUT00输出ON
{
OUT00 = ON;
}
if(Num == 1) //IN00第二次按下,OUT00输出OFF
{
OUT00 = OFF;
}
OUT_CTR = 0;
Num ++;
if(Num>1) //OUT00输只有两种状态,所以不能超过1,即:Num的值只能为0或1
{
Num = 0;
}
}
}
}
然后将程序下载到控制板中,我们可以看到如下现象,源代码见附件:
源代码: