使用中断让七段数码管单击计数

Tech沉思录 2018-01-18 11:47:25

这个就直接不变只显示一个初值0
这是代码
不明白这个中断怎么返回的
求大神赐教
...全文
743 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
Tech沉思录 2018-01-22
  • 打赏
  • 举报
回复
引用 14 楼 tianxj001 的回复:
判断和加减有冲突,应该修改为

INTT0:
    PUSH ACC    ;  为了不覆盖A只堆入不弹出  但是程序也不可以 按下按钮后数码管无变化
    INC R5
    CJNE R5,#10H,CLOSE
    MOV R5,#09H
CLOSE:
    POP ACC
    RETI
  
INTT1:
    PUSH ACC       ;为了不覆盖A只堆入不弹出  但是程序也不可以 按下按钮后数码管无变化
    DEC R5
    CJNE R5,#FFh,NOEQU1
    MOV R5,#00H           ;R5=FF
NOEQU1: 
       POP ACC
    RETI
明白了谢谢您 我原来那个把0A之后和FF之后的都考虑进去了,都是没有必要的 再次感谢! 您那个

INTT0:
    PUSH ACC    ;  为了不覆盖A只堆入不弹出  但是程序也不可以 按下按钮后数码管无变化
    INC R5
    CJNE R5,#10H,CLOSE
    MOV R5,#09H
CLOSE:
    POP ACC
    RETI
  
INTT1:
    PUSH ACC       ;为了不覆盖A只堆入不弹出  但是程序也不可以 按下按钮后数码管无变化
    DEC R5
    CJNE R5,#FFh,NOEQU1
    MOV R5,#00H           ;R5=FF
NOEQU1: 
       POP ACC
    RETI
里面的#10H应该是#0AH吧
zhenxing2000 2018-01-22
  • 打赏
  • 举报
回复

/*波特率相关设置*/
UART_DIV = (float)(72000000/(16*Baud));
DIV_Dantissa = UART_DIV;                     //截取整数部分
DIV_Fraction = (UART_DIV - DIV_Dantissa)*16; //截取小数部分
DIV_Dantissa <<= 4;                          //整数部分放到4:15位
DIV_Dantissa += DIV_Fraction;                //得到DIV的数值
USART1->BRR = DIV_Dantissa;                  //将计算值赋值到BRR寄存器
tianxj001 2018-01-21
  • 打赏
  • 举报
回复
顺便说一下,以后提问题,代码部分可别抓图,回复里面有专门贴代码的,贴进去又好看还好用,我们帮分析的,也方便到你帖子里面粘贴,否则一行一行给你重新敲代码,谁都嫌烦。
tianxj001 2018-01-21
  • 打赏
  • 举报
回复
引用 7 楼 suyunzzz 的回复:
[quote=引用 6 楼 schlafenhamster 的回复:] "不是应该有一个等待中断的指令吗" 中断 不是 等待 来的, 查询 才是 等待
我记得好像教材上面有一个例子就是主函数最后有一个ajmp $;等待中断 按您这个我懂了正好跟c里面的while(1)一直执行一个意思 谢谢[/quote] 信书可以,可别尽信书哈,你如果只是在一个语句上面等待,试问还能干些啥呢?所以,主函数的循环部分,必须能够有一个基本动作循环,比如执行、比如刷新显示,然后在这个循环里面等待中断,像你编的这个,实际上需要的一个基本动作是刷新显示,别的真没什么了,那么你如果非要在一个语句里面循环等待中断也是可以的,但是,你需要在按钮动作时候,刷新显示,也就是说你必须在中断程序里面加进去刷新显示过程,这样也可以了。 你中断函数修改成这样: ORG 0200H INTTO:PUSH ACC INC R5 MOV A, R5 MOVC A,@A+DPTR MOV P0,A POP ACC RETI 你看看是不是能够显示更新了,其实你主函数里面什么都没干,因此,这里实际上中断函数根本不需要把ACC压栈和出栈,当然良好的编程习惯,加上这个也是可以的。
schlafenhamster 2018-01-21
  • 打赏
  • 举报
回复
中断发生时,旧的PSW会入栈,所以 IRET 要 pop 旧的PSW。 而· RET 不必·
schlafenhamster 2018-01-21
  • 打赏
  • 举报
回复
把主程序做的事,放中断中做是错误的设计(一个中断发生时 会阻塞其他中断!)
tianxj001 2018-01-21
  • 打赏
  • 举报
回复
判断和加减有冲突,应该修改为

INTT0:
    PUSH ACC    ;  为了不覆盖A只堆入不弹出  但是程序也不可以 按下按钮后数码管无变化
    INC R5
    CJNE R5,#10H,CLOSE
    MOV R5,#09H
CLOSE:
    POP ACC
    RETI
  
INTT1:
    PUSH ACC       ;为了不覆盖A只堆入不弹出  但是程序也不可以 按下按钮后数码管无变化
    DEC R5
    CJNE R5,#FFh,NOEQU1
    MOV R5,#00H           ;R5=FF
NOEQU1: 
       POP ACC
    RETI
tianxj001 2018-01-21
  • 打赏
  • 举报
回复
你把程序大大的复杂化了,而且,对于汇编怎么样缩减跳转地址入口,简洁编写完全没有理解,我给你简化了一下,注意一下,判断R5上下边界时候的入口用法,如果可以的,最好我们就是只让程序跳过一段执行,而不是来回开辟程序段,这样程序又简洁,读起来更顺畅。 修改的程序,所有查表、刷新功能放主函数,中断只修改R5值并作上下限判断。
MOV SP,#70H    ;堆栈指针
MOV DPTR,#TABLE    ;查表
MOV R5,#00H;计数初值
L0:MOV A,R5
MOVC A,@A+DPTR
MOV P0,A
LCALL DELAY;调用延时程序
LJMP L0;等待中断
 
ORG 0200H
INTT0:
	PUSH ACC    ;  为了不覆盖A只堆入不弹出  但是程序也不可以 按下按钮后数码管无变化
	INC R5
	CJNE R5,#09H,CLOSE
	MOV R5,#09H
CLOSE:
	POP ACC
	RETI
 
INTT1:
	PUSH ACC       ;为了不覆盖A只堆入不弹出  但是程序也不可以 按下按钮后数码管无变化
	DEC R5
	CJNE R5,#00h,NOEQU1
	MOV R5,#00H           ;R5=FF
NOEQU1: 
   	POP ACC
	RETI
Tech沉思录 2018-01-21
  • 打赏
  • 举报
回复
引用 9 楼 tianxj001 的回复:
顺便说一下,以后提问题,代码部分可别抓图,回复里面有专门贴代码的,贴进去又好看还好用,我们帮分析的,也方便到你帖子里面粘贴,否则一行一行给你重新敲代码,谁都嫌烦。
您说的对 刚开始用这个论坛 以后会注意的 还有根据您说的我用了在中断里刷新还有在主函数里面送至P0口的 有一个不对不知道为什么就是我在中断里查表送至A,然后在主函数里送至P0,如果我PUSH POP都不用的话是对的,然后如果只使用PUSH 不使用POP的话是不对的,这里想不通,我明明没有使用POP将查表后的数据覆盖,为啥还是不刷新呢
Tech沉思录 2018-01-21
  • 打赏
  • 举报
回复
引用 11 楼 suyunzzz 的回复:
ORG 0000H
LJMP MAIN
ORG 0003H
LJMP INTT0
ORG 0013H
LJMP INTT1
ORG 0100H
MAIN:
SETB P2^3	//选中第8个数码管
SETB P2^4
SETB P2^2
SETB EA	   ;开中断
SETB EX0   ;低电平触发
SETB IT0
SETB EX1
SETB IT1
MOV SP,#70H	;堆栈指针
MOV DPTR,#TABLE	;查表
MOV R5,#00H;计数初值
MOV A,R5
MOVC A,@A+DPTR
MOV R4,A
L0:MOV P0,R4
LCALL DELAY;调用延时程序
LJMP L0;等待中断

ORG 0200H
INTT0:PUSH ACC	;  为了不覆盖A只堆入不弹出  但是程序也不可以 按下按钮后数码管无变化

INC R5
CJNE R5,#09H,NOEQU
LJMP CLOSE
NOEQU:JNC NEXT1;C=0 没有进阶位,R5大于9,跳转至赋值语句
 LJMP CLOSE		 ;R5<9
NEXT1:MOV R5,#09H

  CLOSE:MOV A,R5
   MOVC A,@A+DPTR	 ;只放在A中,不刷新显示 //////可以把A放在另一个R4中 然后依然有堆入弹出,使用R4刷新显示	?
 	MOV R4,A
	
	POP ACC
RETI

INTT1:PUSH ACC	   ;为了不覆盖A只堆入不弹出  但是程序也不可以 按下按钮后数码管无变化
DEC R5
CJNE R5,#00h,NOEQU1
LJMP CLOSE1
NOEQU1:CJNE R5,#0FFH, CLOSE1	  ;R5!=FF
MOV R5,#00H		   ;R5=FF

CLOSE1:MOV A,R5
   MOVC A,@A+DPTR		  ;只放在A中,不刷新显示
   MOV R4,A
   POP ACC
RETI

DELAY:MOV R0,#255
L1:MOV R1,#255
DJNZ R1,$
DJNZ R0,L1
RET


TABLE:DB 03FH
      DB   06H 
	DB	 5BH 
	DB	 4FH 
	DB	 66H 
	DB	 6DH 
	DB	 7DH 
	DB	 07H 
	DB	 7FH 
	DB	6FH
END
这个代码是对的,我做了很多次尝试,就是上面说的那个PUSH不POP的不对,其他的都对
Tech沉思录 2018-01-21
  • 打赏
  • 举报
回复
ORG 0000H
LJMP MAIN
ORG 0003H
LJMP INTT0
ORG 0013H
LJMP INTT1
ORG 0100H
MAIN:
SETB P2^3	//选中第8个数码管
SETB P2^4
SETB P2^2
SETB EA	   ;开中断
SETB EX0   ;低电平触发
SETB IT0
SETB EX1
SETB IT1
MOV SP,#70H	;堆栈指针
MOV DPTR,#TABLE	;查表
MOV R5,#00H;计数初值
MOV A,R5
MOVC A,@A+DPTR
MOV R4,A
L0:MOV P0,R4
LCALL DELAY;调用延时程序
LJMP L0;等待中断

ORG 0200H
INTT0:PUSH ACC	;  为了不覆盖A只堆入不弹出  但是程序也不可以 按下按钮后数码管无变化

INC R5
CJNE R5,#09H,NOEQU
LJMP CLOSE
NOEQU:JNC NEXT1;C=0 没有进阶位,R5大于9,跳转至赋值语句
 LJMP CLOSE		 ;R5<9
NEXT1:MOV R5,#09H

  CLOSE:MOV A,R5
   MOVC A,@A+DPTR	 ;只放在A中,不刷新显示 //////可以把A放在另一个R4中 然后依然有堆入弹出,使用R4刷新显示	?
 	MOV R4,A
	
	POP ACC
RETI

INTT1:PUSH ACC	   ;为了不覆盖A只堆入不弹出  但是程序也不可以 按下按钮后数码管无变化
DEC R5
CJNE R5,#00h,NOEQU1
LJMP CLOSE1
NOEQU1:CJNE R5,#0FFH, CLOSE1	  ;R5!=FF
MOV R5,#00H		   ;R5=FF

CLOSE1:MOV A,R5
   MOVC A,@A+DPTR		  ;只放在A中,不刷新显示
   MOV R4,A
   POP ACC
RETI

DELAY:MOV R0,#255
L1:MOV R1,#255
DJNZ R1,$
DJNZ R0,L1
RET


TABLE:DB 03FH
      DB   06H 
	DB	 5BH 
	DB	 4FH 
	DB	 66H 
	DB	 6DH 
	DB	 7DH 
	DB	 07H 
	DB	 7FH 
	DB	6FH
END
Tech沉思录 2018-01-20
  • 打赏
  • 举报
回复
引用 6 楼 schlafenhamster 的回复:
"不是应该有一个等待中断的指令吗" 中断 不是 等待 来的, 查询 才是 等待
我记得好像教材上面有一个例子就是主函数最后有一个ajmp $;等待中断 按您这个我懂了正好跟c里面的while(1)一直执行一个意思 谢谢
schlafenhamster 2018-01-20
  • 打赏
  • 举报
回复
"不是应该有一个等待中断的指令吗" 中断 不是 等待 来的, 查询 才是 等待
Tech沉思录 2018-01-20
  • 打赏
  • 举报
回复
引用 1 楼 tianxj001 的回复:
中断返回指令就是一个RETI,至于为什么,通过按钮中断,可以改变,数据的关系是INT0中断 每次发生,都会修改R5的值,而你主函数上面用的是R5间址查表显示。 程序基本方法的对的,但是,你最后一句是AJMP $,程序强制返回语句本身,也就是说,后面中断发生后,还是在这个语句循环,因此你数据显示刷新都没继续进行,这导致你只能显示一个0,正确的应该返回到MOVC A,@A+DPTR 这样,才会在R5被改变后,刷新显示。
谢谢 懂了 ,就是有一点不明白,不是应该有一个等待中断的指令吗,现在那条语句实现了这个功能呢
Tech沉思录 2018-01-20
  • 打赏
  • 举报
回复
引用 2 楼 tianxj001 的回复:
应该跳转到 MOV A,R5 这句 上面我看错行了。
引用 2 楼 tianxj001 的回复:
应该跳转到 MOV A,R5 这句 上面我看错行了。
这条指令不应该是等待中断的吗 你的意思是在中断服务子程序里面加一个LJMP 跳出来到MOV A,R5吗
tianxj001 2018-01-19
  • 打赏
  • 举报
回复
应该跳转到 MOV A,R5 这句 上面我看错行了。
tianxj001 2018-01-19
  • 打赏
  • 举报
回复
中断返回指令就是一个RETI,至于为什么,通过按钮中断,可以改变,数据的关系是INT0中断 每次发生,都会修改R5的值,而你主函数上面用的是R5间址查表显示。 程序基本方法的对的,但是,你最后一句是AJMP $,程序强制返回语句本身,也就是说,后面中断发生后,还是在这个语句循环,因此你数据显示刷新都没继续进行,这导致你只能显示一个0,正确的应该返回到MOVC A,@A+DPTR 这样,才会在R5被改变后,刷新显示。
schlafenhamster 2018-01-19
  • 打赏
  • 举报
回复
ajmp $ 这条指令等价于 LL: ajmp LL ;即不断执行该指令 不走了(也可以把它 看做是一条暂停指令)

27,372

社区成员

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

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