标题: 定时器中断的计时问题 [打印本页]
作者: xzf586 时间: 2017-9-24 19:26
标题: 定时器中断的计时问题
定时器中断的计时问题
前些天看到一个定时器中断的计时问题,那里面采用的答案似乎是,中断执行以后才开始再次计时,对此不敢苟同,考虑以下程序,0.1秒表计时
#include<reg52.h>
unsignedchar code DuanMa[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//
unsignedchar code WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
unsignedchar miao=0;
voidDelayUs2x(unsigned char t)//大致延时(2*t+5)us
{
while(--t);
}
voidDelayMs(unsigned int t)//大致延时1mS
{
while(t--)
{
DelayUs2x(245);
DelayUs2x(245);
}
}
/*------------------------------------------------
显示函数,用于动态扫描数码管
------------------------------------------------*/
voidDisplay(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);
}
/*------------------------------------------------
主函数
------------------------------------------------*/
voidmain (void)
{
TMOD |= 0x01;
TH0=(65536-2000)/256;
TL0=(65536-2000)%256; //2ms定时
EA=1;
ET0=1;
TR0=1;
while (1)
{
Display(miao);
}
}
/*------------------------------------------------
定时器中断子程序
------------------------------------------------*/
voidTimer0_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);
}
1:定时器是2MS定时,中断里面的 延时1ms DelayMs(1),去掉与加上,对计时没有影响;
2:将中断程序改成
voidTimer0_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;
}
影响结果很大!
为了再次验证楼主的想法,干脆将中断程序改为
voidTimer0_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);
}
去掉重新赋值,计时依然,但是慢了许多!
结论:
1:定时计数满了以后,模式1就是到达65536,溢出标志TF0在进入中断服务程序后,自动清零,开始下一次中断计时,计时是从中断服务程序的第一条语句开始
2:正因为1,所以进入中断后,首先是给定时器赋值,否则其从0开始计时,所以赋值的位置不对,结果差异很大
3:在中断服务程序中是不会再次进入此中断,上面DelayMs(1)延时1MS没有影响,但是一旦改成延时2ms,结果就乱了套,因此中断服务的运行时间不能超过定时器的定时时间,除非关闭中断,最后再开启中断
以上是个人想法!
作者: xzf586 时间: 2017-9-24 19:30
从上面可以看出,使用定时器定时也会有误差,误差的来源是:1主程序任务的保存时间,2是定时器初值的赋值时间
作者: ahshmj 时间: 2017-9-25 20:09
65535+1=0
65535=0xffff
0xffff+1=0x10000
由于只有16位,只能显示0x0000.
定时器根据需要设置初值,初值+延时时间=65535,如果不重新装载初值,就会从零开始。
重装初值应在中断函数的最前面,如果延时1ms再装初值,每次中断就会延长1ms。
作者: karolyte 时间: 2020-6-30 16:04
您好,我现在有个程序,定时器设置的定时时间是1ms,中断服务的运行时间是570us,没有超过定时时间,但是实际运行时发现没有按照设定的定时时间进入中断,它自己70ms进入一次中断,目前不知道是什么原因造成的
作者: long... 时间: 2020-6-30 16:29
很好,一下就说中了要点
欢迎光临 (http://www.51hei.com/bbs/) |
Powered by Discuz! X3.1 |