打印

定时中断每隔1s调用一次显示程序

[复制链接]
6936|24
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
wdyang|  楼主 | 2010-7-15 17:36 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我的主程序中 有一部分是时钟,用的DS1302,且LCD1602显示。想用定时器T0中断,每隔1s调用一次显示程序。在其他时间继续执行主程序。显示子程序 用DISPLAY 或其他的符号代替即可,这部分我已经编好了。主要是1s一次中断 调显示程序的部分不会。
编写了好久也一直没有解决。定时中断总不能1s调用。求  高手帮忙解惑   用的是汇编。

相关帖子

沙发
new1988| | 2010-7-15 20:22 | 只看该作者
什么单片机能做到1S中断一次,那定时器要多少位啊??就算传统的十二分频的51,最大的中断时间也只有65.535ms啊!!
要一秒调用一次显示函数就用定时器定时一个50ms的中断。在中断里面设置个变量,没中断一次加一。在主程序里面判断这个变量有没有超过20,如果超过就执行显示函数。没超过就跳过显示函数。

使用特权

评论回复
板凳
chenyongsheng| | 2010-7-15 20:23 | 只看该作者
明天我找朋友问问,我不太会哦...

使用特权

评论回复
地板
wdyang|  楼主 | 2010-7-15 21:52 | 只看该作者

RE: 谢谢new1988 多次的指教

2# new1988
我就是用你说方法T0定时50ms,然后循环20次实现的定时1s. 但是,问题是如果这样,单片机要不断查询这个变量是否达到20,这样单片机就 不能够执行其他事情了.
时钟只是作为一部分功能。  还可以有其他的方法可以实现这样的功能吗?非常感谢....

使用特权

评论回复
5
wdyang|  楼主 | 2010-7-15 21:54 | 只看该作者
3# chenyongsheng
谢谢.....希望你们有方法能够帮我解决:lol

使用特权

评论回复
6
new1988| | 2010-7-16 07:54 | 只看该作者
if( Timer >= 20 )
{
      //显示函数
    Time = 0;
}
else
{
    //其他事情
}
这样能不能干别的事情啊???

使用特权

评论回复
7
wdyang|  楼主 | 2010-7-16 08:36 | 只看该作者

RE: 谢谢 new1988的指点

6# new1988
因为我们学过汇编,所以整体的程序都是用汇编编的。对于C51,我自学过一点,但也只是皮毛而已,运用的不是很熟练。感觉上你写的可以实现。
但是能否用 ...汇编... 解决啊......    再次谢谢您.......

使用特权

评论回复
8
chenyongsheng| | 2010-7-16 08:58 | 只看该作者
用汇编的,不会哦..

使用特权

评论回复
9
seabada| | 2010-7-16 09:43 | 只看该作者
汇编的不会啊,事实c上面说的已经很好了,我想你再想想应该可以的

使用特权

评论回复
10
wdyang|  楼主 | 2010-7-16 10:14 | 只看该作者
谢谢 楼上的两位 对本帖的关注....:)

使用特权

评论回复
11
wdyang|  楼主 | 2010-7-16 10:59 | 只看该作者

RE: 我的方法

我的想法是这样:
ORG   0000H   
LJMP   MAIN
ORG   000B
LJMP   ZD            ;  ZD 是T0中断服务程序
MAIN:  1302初始化
           1602初始化
           T0   赋初值         ;编程序时我用的50ms代替1s ,原理是一样的,只是少了20次循环而已。(测试成功后加上20次即可)
           SETB  TR0  
要执行的主干程序
.......
.......
.......  ---------当到达时50ms(1s),TF0=1,溢出中断,执行T0中断服务程序。TF0自动清零.当中断程序结束后,返回到该断点,继续执行主干程序。
.......
.......
.......-----------同上
.......
.......   ;主干程序结束
ZD:T0重新赋值         
        SETB  TR0
        LCALL DISPLAY   ;调显示程序
        RETI


我个人感觉这从理论上完全行的通啊..可结果显示,1s时并没有产生中断,并没有执行中断程序,而是执行完主干程序后,才接着执行一次中断显示程序(似乎是接着主干程序后面执行的)。然后是时钟、显示从初始化开始。
LCD总共就显示了2次,最开始和最末尾。时间和时钟对的上。只是执行主程序期间不显示时间.
疑惑啊.........

使用特权

评论回复
12
wdyang|  楼主 | 2010-7-16 11:48 | 只看该作者

RE:

我分析出现这种现象的原因之一 很可能是没有响应中断。但是书上说:
TF0:定时器T0的溢出中断申请位。TF0实际上是T0中断触发器的一个输出端,T0被允许计数以后,从初值开始加1计数,当产生溢出是置TF0=1,向CPU请求中断,直到CPU响应该中断时才由硬件清零。
但是我们的这个主程序T0中断是最高级的啊,CPU 必然响应T0中断啊。照书上说,只要TF0溢出,就响应中断。没有响应中断是不可能的啊。怎么可能没有反应呢?

请 汇编方面的 高手们  再 指教一二啊....不胜感激.......

使用特权

评论回复
13
zljzlj| | 2010-7-16 15:58 | 只看该作者
又是一个被 教科书 误导的

1. 各模块顺序在被执行,显示只是其中一个模块而已
2. 考虑到实时性,一般100ms或有变化就刷新一次
3. 注意你的系统结构,不要有较长的delay
4.避免delay的方法是利用一个硬定时器,衍生若干 软定时器
  如: 一个硬件定时器为2ms的,在它里面就可以生成 多个2ms ,以及10ms,100ms,500ms,等等(只要长度和时间允许)

5. 利用一个2ms 当期大雨50(100ms到时)  或 有显示内容变化就调用一下  显示程序


注意:这些与你的整体程序运行有关,千万不要某个程序里有类似 delay 几秒这样的东东。。。。
      想想单片机运行一圈程序大概所消耗的时间!

使用特权

评论回复
14
baiyi5219| | 2010-7-16 16:44 | 只看该作者
怎么来两个跳转到中断啊,中断时自动产生的,不需要跳转的,主程序里面开中断就行了。

使用特权

评论回复
15
wdyang|  楼主 | 2010-7-16 17:08 | 只看该作者

RE: 定时中断每隔1s调用一次显示程序

14# baiyi5219
这里出现的不止2个中断(我只是没有加入省略号),只要程序执行结束前,程序就会每间隔1s进行一次中断,调一次显示程序。而且在程序的哪个位置出现中断,我们是不知道的,所以没有办法在主程序中的某个位置写开启中断。只能靠定时器溢出判断,是否到达中断,然后停止执行主干程序,中断程序执行后(在返回前,还要重新赋值开启下次中断),返回主程序断点,继续执行。

使用特权

评论回复
16
new1988| | 2010-7-16 17:16 | 只看该作者
11# wdyang
请问你怎么定时1S的定时器中断。TH0和TL0各是多少?
        TIMER   EQU  30H
        ORG 00H
        SJMP INIT
        ORG 0BH
        SJMP ZD
INIT:
         1302初始化
         1602初始化
          T0初始化
          SETB TR0
MAIN:
         CJNE TIMER, #20, L1
          LCALL DISPLAY
          MOV  TIMER ,#0
L1:        其他事情
          SJMP MAIN
ZD:    重装T0
          INC TIMER
RETI

使用特权

评论回复
17
波波来了哦| | 2010-7-16 17:48 | 只看该作者
EA、ET0都置1了没?定时器0中断要打开这两位

使用特权

评论回复
18
wdyang|  楼主 | 2010-7-16 19:27 | 只看该作者
17# new1988
我们的想法应该是一致的,
1302初始化
1602初始化
MOV R7,#20
SETB ET0
SETB EA
MOV TMOD,#01H
MOV TH0,#3CH       ;50ms
MOV TL0,#0B0H
SETB TR0
........主干程序......
.........................
........主干程序结束.....
ZD:  CJNE R7,#00H,PE      ;没有减到0,即没有到1s 跳到PE,重新赋值,重开T0,并且R7减1.,返回。
MOV TH0,#3CH                 ;如果R7为0,到达1s,重新赋值,重开T0,调用显示程序,返回。
MOV TL0,#0B0H
SETB TR0
LCALL DISPLAY
LCALL PE1
PE:   MOV TH0,#3CH
MOV TL0,#0B0H
SETB TR0
DEC R7
PE1:  RETI

使用特权

评论回复
19
wdyang|  楼主 | 2010-7-16 19:46 | 只看该作者
18# 波波来了哦
EA、ET0都置1了,不好用,就是执行主程序,不中断显示时间。:'(

使用特权

评论回复
20
awmc_m| | 2010-7-16 20:21 | 只看该作者
lz被1s搞糊涂了。其实是否1s显示都没有关系的。不一定非要1.0000000s这么准的时间间隔就显示。
看你的程序,用到了很多sjmp不知道跨度够不够,可以先改为ljmp试试。
另外在中断程序中作显示是不可取的。就算要在里面显示,你也应该先将定时器关掉,显示完再开定时器。
修改如下:
1、将所有sjmp改为ljmp。
2、中断程序改为:
ZD:  CJNE R7,#00H,PE      ;没有减到0,即没有到1s 跳到PE,重新赋值,重开T0,并且R7减1.,返回。
MOV TH0,#3CH                 ;如果R7为0,到达1s,重新赋值,重开T0,调用显示程序,返回。
MOV TL0,#0B0H
CLR TR0
LCALL DISPLAY
SETB TR0
MOV R7,#20
LCALL PE1
PE:   MOV TH0,#3CH
MOV TL0,#0B0H
SETB TR0
DEC R7
PE1:  RETI

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

4

主题

44

帖子

1

粉丝