I am tasked with creating a program that will scroll a predetermined message across a 4 display seven segment screen, the scrolling is done with an digital rotary encoder that has two Phases A,B. The screens are multiplexed so all the letters show at the same time. The problem is the message only scrolls one way and I can not find the problem. My program is below, i use the portc,5 to detect direction, and portb,1 to cause a interrupt on change. Code has to be in Assembly
Mod edit: code tags
Code:
; Name: PicLab9.asm
; By James Harris
__config _CONFIG1, 0x03F4 ; internal oscillator, WDT off
__config _CONFIG2, 0x3FFF
[INDENT] #include p16f887.inc ; included with MPLab
#include lowercase_887sfr.inc ; in the Files folder (see note)[/INDENT]
;define variables
cblock 0x20
dig3,
dig2,
dig1,
dig0,
userflag,
direction,
w_save,
status_save,
pclath_save,
m_index, endc
;define constants
#define DIGSEL0 portc,3
#define DIGSEL1 portc,2
#define DIGSEL2 portc,1
#define DIGSEL3 portc,0
#define DRE_0 userflag,0
#define DRE_1 userflag,1
org 0x00
call Init
goto Main
org 0x04 ; interrupt vector
movwf w_save ; save registers
swapf status,W
movwf status_save
movf pclath,W
movwf pclath_save
clrf pclath
[INDENT]call Isr[/INDENT]
movf pclath_save,W ; restore registers
movwf pclath
swapf status_save,W
movwf status
swapf w_save,F
swapf w_save,W
retfie
Message
movf m_index,W
andlw b'00000111' ; mask off upper bits to force m_index to 0 thru 7 only.
addwf pcl,F ; index into the table
retlw b'11110000' ;J
retlw b'01111111' ;.
retlw b'10001001' ;H
retlw b'10001000' ;A
retlw b'10101111' ;r
retlw b'10101111' ;r
retlw b'11101111' ;i
retlw b'10010010' ;s
Init
[INDENT] bsf status,RP0 ;switch to Bank1
movlw b'11110000'
movwf trisc
movlw b'00000000'
movwf trisd
movlw b'01100001' ;4MHz internal oscillator
movwf osccon ;osccon is in bank1
banksel anselh
bcf anselh,ANS10 ;enable digital input on RB1
banksel option_reg
bcf option_reg,NOT_RBPU ;enable pull-ups
banksel wpub
bsf wpub,WPUB1 ;enable RB1 pull-up
banksel iocb
bsf iocb,IOCB1 ;enable RB1 on-change interrupt
bcf status,RP0 ;switch to Bank0
clrf m_index
clrf direction
clrf dig3
clrf dig2
clrf dig1
clrf dig0
bsf intcon,RBIE ;enable interrupts
bsf intcon,PEIE
bsf intcon, GIE
return[/INDENT]
Main
call Dr_encoder
call Display
goto Main
Display
movf dig3,W
movwf portd
bcf DIGSEL3
call Wait
bsf DIGSEL3
movf dig2,W
movwf portd
bcf DIGSEL2
call Wait
bsf DIGSEL2
movf dig1,W
movwf portd
bcf DIGSEL1
call Wait
bsf DIGSEL1
movf dig0,W
movwf portd
bcf DIGSEL0
call Wait
bsf DIGSEL0
return
Isr
btfss intcon,0
return
btfss portb,1 ; previous state of portb 0
call RC_1 ; call if previous state was 1
btfsc portb,1 ; previous state of portb 1
call RC_0 ; call if previous state was 0
call Wait_1sec
call Dre_isr
return
RC_1
btfsc portc,5 ;current state 1
bsf DRE_1
bsf DRE_0
return
RC_0
btfss portc,5 ;current state 1
bsf DRE_1
bsf DRE_0
return
Dre_isr
movf portb,W ;ends the mismatch on change
bcf intcon,RBIF
btfss DRE_0 ;detect direction
return ;negative edge only
movlw -1 ;CCW
btfss DRE_1
movlw 1 ;CW
movwf direction
clrf userflag
return
Dr_encoder
movf direction,W ; CW = +1, CCW = -1,
btfsc status,Z ; if direction is clear, then nothing to do
return
addwf m_index,F ; add direction to the message index
clrf direction ; no change = 0
call Message ; get character from the message table
movwf dig3 ; store it for displaying
incf m_index ; point to next character
call Message ; get character from the message table
movwf dig2 ; store it for displaying
incf m_index ; point to next character
call Message ; get character from the message table
movwf dig1 ; store it for displaying
incf m_index ; point to next character
call Message ; get character from the message table
movwf dig0 ; store it for displaying
movlw .3 ; restore m_index
subwf m_index ; point back to first character
return
Wait
decfsz waitcounter
goto Wait
return
Wait_10msec
Init_z movlw .4
movwf cntr_z
Init_y movlw .239
movwf cntr_y
Init_x
movlw .5
movwf cntr_x
Loop1 decfsz cntr_x, F
goto Loop1
decfsz cntr_y, F
goto Init_x
decfsz cntr_z, F
goto Init_y
return
end
Last edited by a moderator: