51单片机定时器可用两种方式处理:查询和进入中断处理。
1.查询方式
void Init_T0 (void) 定时器初始化
{
TMOD = 0x01;//计时器模式
TH0 = (65535-65000) /256;//初装值为65536-65000,逐步+1,最后加到65535,溢出TF0=1
TL0 = (65535-65000) %256;
EA = 0;//关闭全局中断
ET0 = 0;//关闭定时器中断
TR0 = 1;//启动定时器
}
void Main() 主函数
{
Init_T0 ();
Speak1 =1;
while(1)
{
if(TF0==1) 查询中断标志
{
Speak1=~Speak1;
//TH0 = (65535-65000) /256;
//TL0 = (65535-65000) %256;
TF0=0;//对于查询方式,一定要手动清除中断溢出标志。
}
}
}
2.进入中断处理
void Init_T0 (void) 定时器初始化
{
TMOD = 0x01;
TH0 = (65535-65000) /256;
TL0 = (65535-65000) %6;
EA = 1;
ET0 = 1;
TR0 = 1;
}
void Time0_Int() interrupt 1 中断处理函数
{
Speak1=~Speak1;
//TH0 = (65535-65000) /256;
//TL0 = (65535-65000) %256;
//TF0=0;//中断处理方式,硬件会自动清除中断溢出标志。
}
void Main() 主函数
{
Init_T0 ();
Speak1 =1;
while(1); 等待中断
}
对于查询方式,一定要手动清楚中断标志。
上面2段程序,我屏蔽了,中断时重新装计数初值的语句,程序都可正常运行,所以我认为无论对于那种处理方式,重装初值都不必要。
初始化时,可定义输出口的初始状态。而在处理中断时,一定要用取反语句。手动置0或1,程序将不能正常运行。
对于方式2,开始main中没写最后的while(1),程序不正常运行。
上述定时位宽为16位,最大计数为65535,由于频率为1MHz,约1us,最大计时约65ms。如果计时大于此,可在中断中处理。
程序如下:
int a;
void Time0_Int() interrupt 1
{
if(a++==20)
{ a=0;
Speak1=~Speak1;
}
}
最后说明:51单片机只有溢出中断,将导致标志位TFX置1;而STM32就比较复杂,有许多种定时器中断类型,如更新、触发、匹配捕获。