demo:查询法实现发光二极管LED灯闪烁 (50ms闪一次和1s的流水灯)
控制寄存器 :
TCON的低4位用于控制外部中断;高4位用于控制定时/计数器的启动和中断申请。
原理
定时计数器本质上是个加1的加法器,每经过一个机器周期都会加1,通过设定初值 TH0 TL0,然后一直自增到溢出,用TF0判断溢出。
①设置TMOD的 M0=1 M1=0 C/T=0 GATE=0 下面低位全为0 , 这样TMOD =0x01;这样就设置好了工作方式1 ,16位的定时计数器
②然后TH0 TL0 分别为高四位和低四位,赋予一个初值,这个初值就是延时多长的意思,比如要延时50ms,则65536-50000=15536,再把15536用除以和取余的方法算得高四位和低四位赋予TH0 和TL0,相当于桶底事先装了15536的水,然后过了50000后,就是过了50ms后,达到65536溢出。
③然后再打开TR0=1,这样定时器就开始工作了。
④当计数器达到50ms时,TF0会置1,此时可以用 TF0==1 ?查询是否达到50ms
贴上代码
void timer0_Iint()
{
//设置TMOD确定工作方式 定时 工作方式1 GATE 0
TMOD=0x01; //GATE C/T M1 M0 GATE C/T M1 M0 就只设置最后M1 M0 位
//2、确定初值的计算 50ms 12M
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
//3、打开定时/计数器
TR0=1;
TF0=0; //初始化时清除TF0标志
}
void timer0_dingshi()
{
if(TF0==1) //当计数器达到50ms时,TF0会置1,此时可以用TF0查询是否达到50ms
{
TF0=0; //达到50ms时,手动清零
TH0=(65536-50000)/256; //重新赋初值,高8位
TL0=(65536-50000)%256; //重新赋初值,低8位
LED_2=~LED_2; //LED灯状态取反,则亮或灭一次
}
}
记得看注释!
当然也可以软件写个软件定时1s
贴上代码
unsigned char timerCnt;
unsigned char temp=0xfe;
void timer0_dingshi1s()
{
if(TF0==1) //当计数器达到50ms时,TF0会置1,此时可以用TF0查询是否达到50ms
{
TF0=0; //达到50ms时,手动清零
TH0=(65536-50000)/256; //重新赋初值,高8位
TL0=(65536-50000)%256; //重新赋初值,低8位
timerCnt++;
if(timerCnt>=50) //1s=1000ms/20ms = 50次
{
timerCnt=0; //当达到1s时,手动清零,再重新开始
P2=temp; //流水灯
temp=_crol_(temp,1); //流水灯
}
}
}
最后贴上在main函数里的调用!
void main()
{
timer0_Iint(); //这个初始化的函数在main函数外只需定义一次即可
while(1)
{
timer0_dingshi(); //此函数一直在while函数里循环,一旦达到TF0==1,则执行if语句里的语句
}
}