51定时中断

wxiang168 2009-08-20 01:13:30
一个关于定时器中断的问题:
下面是关于定时中断的代码,请高手指点迷津:

uint ondisp_time;
uint offdisp_time; // 声明全局变量

void timer0(void) interrupt 1
{
if(ondisp_time) ondisp_time--;
if(offdisp_time) offdisp_time--;
flag = 1;
}

void main()
{
ondisp_time = 30;
offdisp_time = 40;
TMOD=0X01; // 定时器0方式1
EA = 1; // 允许所有中断
ET0 = 1; // 开定时器0中断
TR0 = 1; // Timer0开始计数

Seq:while(1)
{
if(bCurrDisp_state)
{
bCurrDisp_state = 0;
ET0 = 1;
TR0 = 1;
if(flag == 1)
//if(ondisp_time == 0)
{
lcd_partclear();
offdisp_time = 6000;
flag = 0;
}
}
else
{
bCurrDisp_state = 1;
ET0 = 1;
TR0 = 1;
if(flag == 1)
//if(offdisp_time == 0)
{
flag = 0;
lcd_disp16_16hanzi(4,16,kai);
lcd_disp16_16hanzi(4,32,shi);
disp_num++;
if(disp_num == 15)
break;
else
ondisp_time = 6000;
goto Seq;
}
}
if(P1_2)
break;
}
}

代码中用ondisp_time和offdisp_time两个变量做定时器,通过调试上面的代码也可以进入中断,但是我不明白
在中断里ondisp_time、offdisp_time怎么没有做减法运算啊,如果做了减法运算,在主程序中我判断这两个变量是否为0时,
是应该显示“开始”两字的,但是现在不显示;判断'flag',可以显示“开始”两字
不知问题处在哪,请高手指教!













...全文
324 18 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
abo77281 2009-08-24
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 wxiang168 的回复:]
程序里面没有看到你设置计数初值,TH0和TL0的设置呢?还是你没有贴出来?

这里我用的两个变量做定时器,没有使用TH0和TL0,效果跟使用TH0和TL0一样的吧!?
[/Quote]

是不一样的 ,而且在你中断处理完了后,TH0和TL0要重新赋值。看定时器原理。
snakeloveist 2009-08-22
  • 打赏
  • 举报
回复
flag也要声明为 volatile
wxiang168 2009-08-22
  • 打赏
  • 举报
回复
加入你是12兆晶振,那么最大延时就是65.536毫秒,这样6000多次的话,要大约6.5分钟才能减到0

系统中用6MHz晶振,每一个机器周期的时间是2us,最大延时131.072ms,赋初值6000的话,应该是6000*2us= 12ms,即初值6000的话,延时12ms,我觉得应该这样计算!如果真的是6.5分钟的话,单片机的复位电路也不允许这么长的延时时间!!

一直苦闷中,我肯定中断是进去了,就是没有做减法!?还请指教
wxiang168 2009-08-22
  • 打赏
  • 举报
回复
楼主程序逻辑上有问题吧,我觉得你offdisp_time和ondisp_time永远不会为0,因为每次进入时钟中断,flag都会为1,在主程序中几乎每循环两次,offdisp_time和ondisp_time都会被重新赋新值6000.是不是中断程序有问题啊?

如果进入中段,offdisp_time和ondisp_time变量做了减法,offdisp_time和ondisp_time就会为0,
每次都给offdisp_time和ondisp_time重新赋初值6000,类似于给TH0,TL0自动重装初值,timer0工作方式2不就是这种用法吗!重新赋初值也是中断延时必须的啊,不然中断函数里不就没有减法运算了,达不到延时的效果!
wxiang168 2009-08-22
  • 打赏
  • 举报
回复
程序里面没有看到你设置计数初值,TH0和TL0的设置呢?还是你没有贴出来?

这里我用的两个变量做定时器,没有使用TH0和TL0,效果跟使用TH0和TL0一样的吧!?
churenxh 2009-08-22
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 zhoushunda960 的回复:]
楼上说的对,关键是TH0和TL0没有赋初值。要在开始运行和时钟中断中都要赋值!
[/Quote]
\
支持
zhoushunda960 2009-08-22
  • 打赏
  • 举报
回复
楼上说的对,关键是TH0和TL0没有赋初值。要在开始运行和时钟中断中都要赋值!
fendou_mo 2009-08-22
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 wxiang168 的回复:]
楼主程序逻辑上有问题吧,我觉得你offdisp_time和ondisp_time永远不会为0,因为每次进入时钟中断,flag都会为1,在主程序中几乎每循环两次,offdisp_time和ondisp_time都会被重新赋新值6000.是不是中断程序有问题啊?

如果进入中段,offdisp_time和ondisp_time变量做了减法,offdisp_time和ondisp_time就会为0,
每次都给offdisp_time和ondisp_time重新赋初值6000,类似于给TH0,TL0自动重装初值,timer0工作方式2不就是这种用法吗!重新赋初值也是中断延时必须的啊,不然中断函数里不就没有减法运算了,达不到延时的效果!

[/Quote]
你中断一次才减一啊,可是说不定没有减多少次又重新赋值了,怎么减到0啊,你要在中断处理里面重新赋值啊
zhoushunda960 2009-08-22
  • 打赏
  • 举报
回复
在你使用的模式下,TH0和TL0是每个时钟周期都会加一,加到0xffff时便会溢出,并产生时钟中断,而这个中断间隔时间就取决于TH0和TL0的初值了。
如果TH0和TL0没有初值,那就相当于从0x0000开始算起,你说一次中断有多长?
zhoushunda960 2009-08-22
  • 打赏
  • 举报
回复
这里我用的两个变量做定时器,没有使用TH0和TL0,效果跟使用TH0和TL0一样的吧!?


效果肯定不一样。建议楼主看看定时器原理吧。!


zhoushunda960 2009-08-22
  • 打赏
  • 举报
回复
我的意思是你要6分多的时间,offdisp_time和ondisp_time才会减到0,并不是说你的中断没进去。其实要进6000次中断,你相应的程序才会运行,而每次进中断的时间太长了。
abo77281 2009-08-21
  • 打赏
  • 举报
回复
程序里面没有看到你设置计数初值,TH0和TL0的设置呢?还是你没有贴出来?
凤朝凰 2009-08-21
  • 打赏
  • 举报
回复
仿真调试看看
wxiang168 2009-08-21
  • 打赏
  • 举报
回复
schlafenhamster
你好
按照你的方法我编译调试了,ondisp_time变量还是没有做减法,就是说if(offdisp_time == 0)不成立,导致“开始”不显示。
郁闷中。。。
zhoushunda960 2009-08-21
  • 打赏
  • 举报
回复
加入你是12兆晶振,那么最大延时就是65.536毫秒,这样6000多次的话,要大约6.5分钟才能减到0
zhoushunda960 2009-08-21
  • 打赏
  • 举报
回复
而且没看到给定时器计数器赋初值,那么每次中断时间为当前模式可中断最大时间。不知道符不符合楼主要求。
zhoushunda960 2009-08-21
  • 打赏
  • 举报
回复
楼主程序逻辑上有问题吧,我觉得你offdisp_time和ondisp_time永远不会为0,因为每次进入时钟中断,flag都会为1,在主程序中几乎每循环两次,offdisp_time和ondisp_time都会被重新赋新值6000.是不是中断程序有问题啊?
schlafenhamster 2009-08-20
  • 打赏
  • 举报
回复
uint volatile ondisp_time;
uint volatile offdisp_time; // 声明全局变量

27,511

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 单片机/工控
社区管理员
  • 单片机/工控社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧