普中开源电子分享网

 找回密码
 立即注册
搜索
查看: 2966|回复: 4

关于定时器中断的计时问题

 关闭 [复制链接]

15

主题

196

帖子

503

积分

高级会员

Rank: 4

积分
503
发表于 2017-9-24 18:53:30 | 显示全部楼层 |阅读模式
前些天看到一个定时器中断的计时问题,那里面采用的答案似乎是,中断执行以后才开始再次计时,对此不敢苟同,考虑以下程序,
#include<reg52.h>

unsigned char code DuanMa[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//
unsigned char code WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
unsigned char miao=0;

void DelayUs2x(unsigned char t)//大致延时(2*t+5)us
{   
     while(--t);
}

void DelayMs(unsigned int t)//大致延时1mS
{     
     while(t--)
     {         
          DelayUs2x(245);
          DelayUs2x(245);
     }
}


/*------------------------------------------------
显示函数,用于动态扫描数码管
------------------------------------------------*/
void Display(unsigned char dat)
{
     P1=0xff;
     P0=DuanMa[dat%10];
     P1=0x7f;
     DelayMs(3);

     P1=0xff;
     P0=DuanMa[(dat/10)%10]|0x80;
     P1=0xbf;
     DelayMs(3);

     P1=0xff;
     P0=DuanMa[(dat/100)%10];
     P1=0xdf;
     DelayMs(3);

}

/*------------------------------------------------
                    主函数
------------------------------------------------*/
void main (void)
{         
     TMOD |= 0x01;                               
     TH0=(65536-2000)/256;                  
     TL0=(65536-2000)%256;   //2ms定时
     EA=1;            
     ET0=1;         
     TR0=1;                              

     while (1)        
     {         
          Display(miao);
     }
}



/*------------------------------------------------
                 定时器中断子程序
------------------------------------------------*/
void Timer0_isr(void) interrupt 1
{
     static unsigned char count=0;
     TH0=(65536-2000)/256;                  //重新赋值 2ms
     TL0=(65536-2000)%256;
     count++;
     if(count==50)
     {
           miao++;
           count=0;
     }
//     DelayMs(1);   
}

0.1秒表,
回复

使用道具 举报

15

主题

196

帖子

503

积分

高级会员

Rank: 4

积分
503
 楼主| 发表于 2017-9-24 18:55:53 | 显示全部楼层
本帖最后由 xzf586 于 2017-9-24 19:14 编辑

2MS定时,中断里面的 延时1ms DelayMs(1);去掉与加上,对计时没有影响
回复 支持 反对

使用道具 举报

15

主题

196

帖子

503

积分

高级会员

Rank: 4

积分
503
 楼主| 发表于 2017-9-24 18:57:25 | 显示全部楼层
将中断程序改成
void Timer0_isr(void) interrupt 1
{
     static unsigned char count=0;
     
     count++;
     if(count==50)
     {
           miao++;
           count=0;
     }
     DelayMs(1);   
TH0=(65536-2000)/256;                  //重新赋值 2ms
     TL0=(65536-2000)%256;
}
影响结果很大!
回复 支持 反对

使用道具 举报

15

主题

196

帖子

503

积分

高级会员

Rank: 4

积分
503
 楼主| 发表于 2017-9-24 19:02:23 | 显示全部楼层
为了再次验证楼主的想法,干脆将中断程序改为
void Timer0_isr(void) interrupt 1
{
     static unsigned char count=0;
     //TH0=(65536-2000)/256;                  //重新赋值 2ms
     //TL0=(65536-2000)%256;
     count++;
     if(count==50)
     {
           miao++;
           count=0;
     }
     DelayMs(1);   
}
去掉重新赋值,计时依然,但是慢了许多!
回复 支持 反对

使用道具 举报

15

主题

196

帖子

503

积分

高级会员

Rank: 4

积分
503
 楼主| 发表于 2017-9-24 19:13:28 | 显示全部楼层
结论:
1:定时计数满了以后,模式1就是到达65536,溢出标志TF0在进入中断服务程序后,自动清零,开始下一次中断计时,计时是从中断服务程序的第一条语句开始
2:正因为1,所以进入中断后,首先是给定时器赋值,否则其从0开始计时,所以赋值的位置不对,结果差异很大
3:在中断服务程序中是不会再次进入此中断,上面DelayMs(1)延时1MS没有影响,但是一旦改成延时2ms,结果就乱了套,因此中断服务的运行时间不能超过定时器的定时时间,除非关闭中断,最后再开启中断
以上是个人想法!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

Archiver|手机版|小黑屋|普中开源电子分享网 粤ICP备16123577号-2

GMT+8, 2024-4-20 16:50 , Processed in 0.095802 second(s), 30 queries .

Powered by 论坛搭建 X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表