定时/计数器基本概念
定时/计数器本质是计数器,当计数达到设定要求,向cpu请求中断。作为定时器时,计数信号来源为周期性的内部时钟脉冲;作为计数器时为非周期的外部输入信号。
定时器工作原理
51单片机的定时/计数器
有2个定时/计数器T0、T1,为16位加法计数器,低8位TLx和高八位THx两个寄存器组成,最大计数值为65535。
注意:有人说是用65536减,见仁见智吧
定时器相关寄存器
TMOD只能字节寻址!
编程思路
练习内容
定时器0的中断号为1。
具体代码
#include "reg52.h"
sbit L1=P0^0;
sbit L8=P0^7;
void hc573(unsigned char channel)
{
switch(channel)
{
case 4:P2=(P2&0x1f)|0x80;break;
case 5:P2=(P2&0x1f)|0xa0;break;
case 6:P2=(P2&0x1f)|0xc0;break;
case 7:P2=(P2&0x1f)|0xe0;break;
}
}
void timer0_init()
{
TMOD=0x01;//选择模式
TH0=(65535-50000)/256;//设置初值
TL0=(65535-50000)%256;
ET0=1;//中断打开
EA=1;
TR0=1;//启动定时器
}
unsigned char count1,count2=0;
void service_timer0()interrupt 1
{
TH0=(65535-50000)/256;//重新赋值
TL0=(65535-50000)%256;
count1++;
count2++;
if(count1==10)//500ms
{
L1=~L1;
count1=0;
}
if(count2==100)//5s
{
L8=~L8;
count2=0;
}
}
void main()
{
hc573(4);
timer0_init();
while(1)
{
}
}
后续优化:减少中断函数中的操作,巧用取余
#include "reg52.h"
sbit L1=P0^0;
sbit L8=P0^7;
void hc573(unsigned char channel)
{
switch(channel)
{
case 4:P2=(P2&0x1f)|0x80;break;
case 5:P2=(P2&0x1f)|0xa0;break;
case 6:P2=(P2&0x1f)|0xc0;break;
case 7:P2=(P2&0x1f)|0xe0;break;
}
}
void timer0_init()
{
TMOD=0x01;//选择模式
TH0=(65535-50000)/256;//设置初值
TL0=(65535-50000)%256;
ET0=1;//中断打开
EA=1;
TR0=1;//启动定时器
}
unsigned char count=0;
void service_timer0()interrupt 1
{
TH0=(65535-50000)/256;//重新赋值
TL0=(65535-50000)%256;
count++;
if(count%10==0)//每500ms取反一次
{
L1=~L1;
}
if(count==100)//5s
{
L8=~L8;
count=0;
}
}
void main()
{
hc573(4);
timer0_init();
while(1)
{
}
}