求助,关于51单片机 同时使用外部中断和定时中断 会发生冲突 导致定时中断停止的问题

2019-07-15 08:13发布

       首先,版主删帖能不能说明下原因。本人是菜鸟,不太懂论坛的规矩,你说明下原因我下次可以注意。否则,帖子删了,都不知道为什么。如何改进?       本人前几天发过一个“电子时钟”的求助帖子。(不知道是不是把所有程序贴上才被删了,这次我就不贴程序了,大体编程思路说一下)

       1、编程思路说明:
             用的是单片机学习板,通过外部中断控制时间的设定,定时中断控制时间的累加;外部中断被触发时,定时中断停止。用的是动态数码管显示。

       2、遇到的问题:
             每次设定完时间以后,时钟开始运行,但是没多久(每次时长都不同)时间就不动了。显示依然是正常显示。我程序看了好几遍应该是没问题的。
       3、网上查找到的答复:
            查了下网上的相似问题。答复是外部中断时长不能太长,或者说把定时中断优先级提高。.......外部中断不长,怎么设定时间,而且边设定边秒钟自己在跳也不好啊。
       4、本人的求教:
             关于上面提到的外部中断时间不能太长。这到底是为什么?能不能有大神仔细讲解一下,单片机内部运算过程中,外部中断时长过长会产生什么问题,最终导致定时中断停止。
       5、其他:
             也可能我上面的理解不对,请大神指教。
       6、顿首!顿首!顿首!顿首!


补充内容 (2018-7-5 15:24):
程序和电路图在7、8楼 请各位大神帮忙!
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
8条回答
nbpip1
1楼-- · 2019-07-15 16:23
       昨天又试验了一下。在外部中断开始时,把定时中断的TMOD、TCON、IE全都置零。等外部中断结束,重新置1。正常运行的时间增加了。但是坚持了两个多小时还是停掉了。
       个人认为,应该是外部中断时改变了RAM中的某些值,最终导致TFx无法置1。但是,具体是一个怎么的过程就不明白了。
       请大神不吝赐教。
伏尔加的鱼
2楼-- · 2019-07-15 20:18
是你程序的问题,中断不会影响的,看看不是一些程序受中断功能影响了,比如使用IIC接口什么的中断影响了IIC通信了
人中狼
3楼-- · 2019-07-16 02:07
 精彩回答 2  元偷偷看……
nbpip1
4楼-- · 2019-07-16 06:00
S_SET BIT P1.0
M_SET BIT P1.1
H_SET BIT P1.2
MODE BIT P1.7
SECOND EQU 30H
MINUTE EQU 31H
HOUR EQU 32H
TCNT EQU 77H

ORG 00H
JMP START
ORG 03H
JMP SET_T
ORG 0BH
JMP INT_T0


START:
MOV DPTR,#TABLE
MOV SECOND,#0
MOV MINUTE,#0
MOV HOUR,#0
MOV IE,#81H
SETB TCON.0
ST1:     //这里是主循环体
CALL DISPLAY
JNB MODE,INT0_S
JMP ST1

INT0_S:       //通过按键控制外部中断P3.2产生下降沿,每次外部中断被触发后立即关闭定时中断
CALL NOSHAKE_1P7
CALL CLOSE_TIME
CLR P3.2
JMP ST1


SET_T:          //秒,分,时的设置程序,再次按MODE后,先重启定时中断,再退出
SETB P3.2
A1:
CALL DISPLAY
JNB S_SET,S1
JNB M_SET,S2
JNB H_SET,S3
JNB MODE,B1
JMP A1
S1:
CALL DELAY
JB S_SET,A1
INC SECOND
MOV A,SECOND
CJNE A,#60,J0
MOV SECOND,#0
JMP K1
S2:
CALL DELAY
JB M_SET,A1
K1:
INC MINUTE
MOV A,MINUTE
CJNE A,#60,J1
MOV MINUTE,#0
JMP K2
S3:
CALL DELAY
JB H_SET,A1
K2:
INC HOUR
MOV A,HOUR
CJNE A,#24,J2
MOV HOUR,#0
MOV MINUTE,#0
MOV SECOND,#0
JMP A1

J0:
JB S_SET,A1
CALL DISPLAY
JMP J0
J1:
JB M_SET,A1
CALL DISPLAY
JMP J1
J2:
JB H_SET,A1
CALL DISPLAY
JMP J2

B1:
CALL NOSHAKE_1P7
CALL DISPLAY
CALL OPEN_TIME      //调用定时中断开启程序
RETI

INT_T0:       //定时中断程序
CALL RESET_TIME
INC TCNT
MOV A,TCNT
CJNE A,#20,RETUNE
INC SECOND
MOV TCNT,#0
MOV A,SECOND
CJNE A,#60,RETUNE
INC MINUTE
MOV SECOND,#0
MOV A,MINUTE
CJNE A,#60,RETUNE
INC HOUR
MOV MINUTE,#0
MOV A,HOUR
CJNE A,#24,RETUNE
MOV HOUR,#0
MOV MINUTE,#0
MOV SECOND,#0
MOV TCNT,#0
RETUNE:
RETI

DISPLAY:          //显示输出程序
MOV A,SECOND
MOV B,#10
DIV AB
MOV P0,#6
MOVC A,@A+DPTR
MOV P2,A
CALL DELAY1
MOV A,B
MOV P0,#7
MOVC A,@A+DPTR
MOV P2,A
CALL DELAY1
MOV P0,#5
MOV P2,#40H
CALL DELAY1

MOV A,MINUTE
MOV B,#10
DIV AB
MOV P0,#3
MOVC A,@A+DPTR
MOV P2,A
CALL DELAY1
MOV A,B
MOV P0,#4
MOVC A,@A+DPTR
MOV P2,A
CALL DELAY1
MOV P0,#2
MOV P2,#40H
CALL DELAY1

MOV A,HOUR
MOV B,#10
DIV AB
MOV P0,#0
MOVC A,@A+DPTR
MOV P2,A
CALL DELAY1
MOV A,B
MOV P0,#1
MOVC A,@A+DPTR
MOV P2,A
CALL DELAY1
RET

TABLE:
DB 3FH,06H,5BH,4FH,66H
DB 6DH,7DH,07H,7FH,6FH

DELAY:
MOV R6,#10
D1:
MOV R7,#250
DJNZ R7,$
DJNZ R6,D1
RET

DELAY1:
MOV R6,#5
D11:
MOV R7,#250
DJNZ R7,$
DJNZ R6,D11
RET

NOSHAKE_1P7:    //消抖子程序
N1:
MOV 7FH,#250
MOV B,#1
N2:
MOV C,P1.7
CLR A
RLC A
MUL AB
MOV B,A
DJNZ 7FH,N2
CJNE A,#1,N1
RET

RESET_TIME:         //重置定时参数
MOV TH0,#3CH
MOV TL0,#0B0H
RET

OPEN_TIME:          //打开定时中断
MOV TCNT,#0
MOV TMOD,#01H
SETB ET0
CALL RESET_TIME
SETB TR0
RET

CLOSE_TIME:       //关闭定时中断各类控制参数
CLR TR0
CALL RESET_TIME
CLR ET0
MOV TMOD,#01H
MOV TCNT,#0
RET

END
nbpip1
5楼-- · 2019-07-16 11:24
各位大神:
     这个是电路连接图
未标题-1副本.jpg
人中狼
6楼-- · 2019-07-16 15:34
其实你的外部中断程序可以直接改成时间设置程序,程序不用变,把中断程序改成普通子程序就可以了。
就程序来说:
一,没有对外部中断进行设置,虽然有硬件复位后的缺省设置,不过最好还是要设置一下。
二,中断程序和子程序都没有对使用的特殊寄存器进行压栈出栈处理,特别是进行程序嵌套时容易出现改变寄存器而导致出错。
三,可以屏蔽外部中断程序,不进行时间设置,在程序里固定写入时间,来测试时间运行是否还出现问题。

一周热门 更多>