我当前正在编写一个汇编代码,该代码将 BCD计数器(通过7段显示器)。按下某个键时,计数器值将被键盘值所覆盖,然后继续递减计数。例如,如果当前计数器值为“ 8”,然后按按键5覆盖,则计数器设置为“ 5”,然后递减计数。计数器将永久递减计数,只要在键盘上按任何键,该计数器就会被覆盖。
这是我的电路
这是我当前编写的代码:
COUNT EQU 0CH
ORG 000H ; reset vector
GOTO MAIN ; jump to label main during reset or startup
ORG 004H ; interrupt vector
GOTO INT_RTN ; jump to label INT_RTN or the interrupt service routine
;set up
MAIN BSF STATUS, RP0
CLRF TRISA
MOVLW 0F1H
MOVWF TRISB
MOVLW 0DH
MOVWF OPTION_REG
BCF STATUS, RP0
BSF OPTION_REG, 6 ; interrupt event during rising edge
BCF INTCON, INTF ; clear the RB0/INT interrupt flag
BSF INTCON, INTE ; unmask (enable) RB0/INT interrupt source
BSF INTCON, GIE ; enable all unmasked interrupt
GOTO START
;Interrupt-----------------------------------------------------------
INT_RTN BCF INTCON, GIE ; disable all unmasked interrupt to prevent interrupt overriding
BTFSS INTCON, INTF ; check the RB0/INT interrupt flag is ‘1’ (interrupt source from RB0/INT)
GOTO EXIT ; exit ISR if not RB0/INT interrupt
;interrupt code
CLRW
BTFSC PORTB, 4
ADDLW 01H
BTFSC PORTB, 5
ADDLW 02H
BTFSC PORTB, 6
ADDLW 04H
BTFSC PORTB, 7
ADDLW 08H
CALL KEY_VAL ; call the array KEY_VAL
MOVWF COUNT
INCF COUNT
BCF INTCON, INTF
BSF INTCON, GIE
GOTO CDOWN
EXIT BSF INTCON, GIE ; enable all unmasked interrupt
RETFIE ; return from interrupt routine
;Program Start--------------------------------------------------------------------------------------------
START MOVLW 0AH
MOVWF COUNT
MOVLW 09H
CDOWN MOVWF PORTA
SLEEP
DECFSZ COUNT, 1
GOTO DOWN
GOTO START
DOWN DECF PORTA, 0
GOTO CDOWN
;End of Start-----------------------------------------------------------
KEY_VAL ADDWF PCL, F
RETLW 01H ; returns 01H for key 1 (addr 00H)
RETLW 02H ; returns 02H for key 2 (addr 01H)
RETLW 03H ; returns 03H for key 3 (addr 02H)
RETLW 00H ; returns 00H for key A (addr 03H)
RETLW 04H ; returns 04H for key 4 (addr 04H)
RETLW 05H ; returns 05H for key 5 (addr 05H)
RETLW 06H ; returns 06H for key 6 (addr 06H)
RETLW 00H ; returns 00H for key B (addr 07H)
RETLW 07H ; returns 07H for key 7 (addr 08H)
RETLW 08H ; returns 08H for key 8 (addr 09H)
RETLW 09H ; returns 09H for key 9 (addr 0AH)
RETLW 00H ; returns 00H for key C (addr 0BH)
RETLW 00H ; returns 00H for key * (addr 0CH)
RETLW 00H ; returns 00H for key 0 (addr 0DH)
RETLW 00H ; returns 00H for key # (addr 0EH)
RETLW 00H ; returns 00H for key D (addr 0FH)
END
自然地,bcd倒计时,当按下按钮时发生中断,读取RB4中的输入-RB7在KEY_VAL给定的地址中找到数据并将其加载到PORTA
但是,我的问题是,当我按键盘上的一个按钮并开始中断时。当我阅读时,引脚RB4-RB7可获得IC给定的地址。我得到的全部都很高,所以我总是得到15(D的地址)。
如果我不按按钮,则MM74c922的引脚A B C D自然为高电平,而当按键盘上的按钮时,ic的引脚12变为高电平,地址被发送至rb4-7。问题是我认为pic控制器无法读取rb4-7中的移位,因此它总是在中断之前读取数据,而中断总是很高,因此我无法获取所需的地址。
我尝试将中断设置为在下降沿期间切换,但是同样的事情出于想法而出现,我需要帮助
如果有帮助,这是按钮的地址
Address: 00H 01H 02H 03H 04H 05H 06H 07H 08H 09H 0AH 0BH 0CH 0DH 0EH 0FH
Key: 1 2 3 A 4 5 6 B 7 8 9 C * 0 # D
答案 0 :(得分:1)
您的中断程序看起来有些疯狂。尝试类似的东西:
; Save Data Space
Bank_shr udata_shr 0x70
W_safe RES 1
S_safe RES 1
.....
;Interrupt-----------------------------------------------------------
INT_RTN
MOVWF W_safe
SWAPF STATUS, W
BCF STATUS, RP0
MOVWF s_safe
Interrupt_code
.......
Interrupt_End
SWAPF s_safe, w
MOVWF STATUS
SWAPF w_safe, F
SWAPF w_safe, w
RETFIE ;GIE will set automatically
请在数据表中查找更多详细信息,其中有一些示例
答案 1 :(得分:1)
从GOTO中断返回并不明智。当您进入中断时,它将发送要堆叠的位置,当您使用goto PC返回时,它不使用该lvl堆栈,直接跳转到标记为Label的GOTO。
你可以尝试
RETFIE
代替
BCF INTCON, INTF
BSF INTCON, GIE
GOTO CDOWN
让我知道是否有任何变化
答案 2 :(得分:0)
因此,显然我找到了答案,而且非常简单,我在bank 0中编辑了选项reg,使中断在下降沿开始无效。
解决方法是
MAIN BSF STATUS, RP0
CLRF TRISA
MOVLW 0F1H
MOVWF TRISB
MOVLW 0DH
MOVWF OPTION_REG
BSF OPTION_REG, 6 --move this line here-- ; interrupt event during rising edge
BCF STATUS, RP0
BCF INTCON, INTF ; clear the RB0/INT interrupt flag
BSF INTCON, INTE ; unmask (enable) RB0/INT interrupt source
BSF INTCON, GIE ; enable all unmasked interrupt
GOTO START
现在代码可以正常工作了,谢谢大家的帮助