;Tutorial 13.4 - Nigel Goodwin 2006
;Matrix LED display - display a scrolling text message
LIST p=16F876 ;tell assembler what chip we are using
include "P16F876.inc" ;include the defaults for the chip
ERRORLEVEL 0, -302 ;suppress bank selection messages
__config 0x393A ;sets the configuration settings (oscillator type etc.)
cblock 0x20 ;start of general purpose registers
count ;used in looping routines
count1 ;used in delay routine
counta ;used in delay routine
countb ;used in delay routine
tmp1 ;temporary storage
tmp2
milli ;3,2 mil1i 51 = 1 second
hour ;hours
min10 ;tens min
min ;ones min
p_temp ;save register
s_temp ;save register
w_temp ;save register
offsetL ;table registers
offsetH
offsetL1
offsetH1
;registers for display
row_pos ;position on row
zero ;zero storage
one ;one storage
two ;two storage
three ;three storage
four ;four storage
five ;five storage
six ;six storage
seven ;seven storage
zero1 ;zero storage
one1 ;one storage
two1 ;two storage
three1 ;three storage
four1 ;four storage
five1 ;five storage
six1 ;six storage
seven1 ;seven storage
endc
ROW_PORT Equ PORTB ;row port
ROW_TRIS Equ TRISB
COL_PORT Equ PORTC ;column port
COL_TRIS Equ TRISC
org 0x0000
goto START
;**************************************************************************
; Interrupt routine
;**************************************************************************
; Interrupt routine handles TMR2 which generates a 1ms tick
; Interrupt vector
ORG 0x0004
INT
movwf w_temp ; Save W register
swapf STATUS,W ; Swap status to be saved into W
movwf s_temp ; Save STATUS register
movfw PCLATH
movwf p_temp ; Save PCLATH
btfss PIR1,TMR2IF ; Flag set if TMR2 interrupt
goto INTX ; Jump if not timed out
; Timer (TMR2) timeout
bcf PIR1,TMR2IF ; Clear the calling flag
btfss row_pos, 0 ;check which ROW was last
goto Do_One
btfss row_pos, 1 ;check which ROW was last
goto Do_Two
btfss row_pos, 2 ;check which ROW was last
goto Do_Three
btfss row_pos, 3 ;check which ROW was last
goto Do_Four
btfss row_pos, 4 ;check which ROW was last
goto Do_Five
btfss row_pos, 5 ;check which ROW was last
goto Do_Six
btfss row_pos, 6 ;check which ROW was last
goto Do_Seven
btfss row_pos, 7 ;check which ROW was last
goto Do_Zero
Do_Zero movlw 0xFF
movwf ROW_PORT ;turn off all rows
movwf row_pos
movf zero, w
movwf COL_PORT ;load columns
bcf row_pos, 0
bcf ROW_PORT, 0 ;turn ON row zero
goto INTX
Do_One movlw 0xFF
movwf ROW_PORT ;turn off all rows
movwf row_pos
movf one, w
movwf COL_PORT ;load columns
bcf row_pos, 1
bcf ROW_PORT, 1 ;turn ON row one
goto INTX
Do_Two movlw 0xFF
movwf ROW_PORT ;turn off all rows
movwf row_pos
movf two, w
movwf COL_PORT ;load columns
bcf row_pos, 2
bcf ROW_PORT, 2 ;turn ON row two
goto INTX
Do_Three movlw 0xFF
movwf ROW_PORT ;turn off all rows
movwf row_pos
movf three, w
movwf COL_PORT ;load columns
bcf row_pos, 3
bcf ROW_PORT, 3 ;turn ON row three
goto INTX
Do_Four movlw 0xFF
movwf ROW_PORT ;turn off all rows
movwf row_pos
movf four, w
movwf COL_PORT ;load columns
bcf row_pos, 4
bcf ROW_PORT, 4 ;turn ON row four
goto INTX
Do_Five movlw 0xFF
movwf ROW_PORT ;turn off all rows
movwf row_pos
movf five, w
movwf COL_PORT ;load columns
bcf row_pos, 5
bcf ROW_PORT, 5 ;turn ON row five
goto INTX
Do_Six movlw 0xFF
movwf ROW_PORT ;turn off all rows
movwf row_pos
movf six, w
movwf COL_PORT ;load columns
bcf row_pos, 6
bcf ROW_PORT, 6 ;turn ON row six
goto INTX
Do_Seven movlw 0xFF
movwf ROW_PORT ;turn off all rows
movwf row_pos
movf seven, w
movwf COL_PORT ;load columns
bcf row_pos, 7
bcf ROW_PORT, 7 ;turn ON row seven
goto INTX
INTX
incf milli,f
movlw .151
subwf milli,w
btfss STATUS,C
goto NTX2
bcf STATUS,C
clrf milli
incf min,f
movlw .10
subwf min,w
btfss STATUS,C
goto NTX2
bcf STATUS,C
clrf min
bsf STATUS,C
rlf min10,f
btfss min10,6
goto NTX2
clrf min10
bsf STATUS,C
rlf hour,f
btfss hour,7
goto NTX2
clrf hour
NTX2 movfw p_temp
movwf PCLATH ; Restore PCLATH
swapf s_temp,W
movwf STATUS ; Restore STATUS register - restores bank
swapf w_temp,F
swapf w_temp,W ; Restore W register
retfie
;program initialisation
START
BANKSEL ADCON1 ;disable analogue inputs
movlw 0x06
movwf ADCON1
BANKSEL PORTA
bsf STATUS, RP0 ;select bank 1
movlw b'00000000' ;Set port data directions, data output
movwf ROW_TRIS
movwf COL_TRIS
bcf STATUS, RP0 ;select bank 0
clrf COL_PORT ;turn OFF all LED's
movlw 0xFF
movwf ROW_PORT
movlw 0x01
movwf row_pos
; Set up Timer 2.
;movlw b'01111111' ; Post scale /16, pre scale /16, TMR2 ON
;uncomment previous line, and comment next line, to slow multiplexing speed
;so you can see the multiplexing happening
movlw b'00011111' ; Post scale /4, pre scale /16, TMR2 ON
movwf T2CON
bsf STATUS, RP0 ;select bank 1
movlw .249 ; Set up comparator
movwf PR2
bsf PIE1,TMR2IE ; Enable TMR2 interrupt
bcf STATUS, RP0 ;select bank 0
; Global interrupt enable
bsf INTCON,PEIE ; Enable all peripheral interrupts
bsf INTCON,GIE ; Global interrupt enable
bcf STATUS, RP0 ;select bank 0
;main program loop
Main
clrf offsetL1 ;set offset to zero
clrf offsetH1
Message
movf min,w
call Load_Char
btfsc min10,1
bsf one,0
btfsc min10,0
bsf zero,0
goto Message
xorlw 0x00 ;is it a zero? - if so end of string
btfsc STATUS, Z
goto Main
movwf tmp2
movlw 0x20 ;subtract to get character index value
subwf tmp2, w
incf offsetL1, f ;increment 16 bit pointer to string
btfsc STATUS , Z
incf offsetH1, f
;display characters start at 0x00 for 'space' (rather than 0x20), and
;carry on from there the same as LCD text modules, ending with the right and
;left arrows.
;because each character takes 8 bytes of storage, we multiply the index value by 8
Load_Char movwf offsetL
clrf offsetH
bcf STATUS, C ;clear carry
rlf offsetL, f ;multiply index value by 8
rlf offsetH, f
bcf STATUS, C ;clear carry
rlf offsetL, f
rlf offsetH, f
bcf STATUS, C ;clear carry
rlf offsetL, f
rlf offsetH, f
call ASCII_Table
movf hour,w
movwf zero
incf offsetL, f ;increment 16 bit pointer
btfsc STATUS , Z
incf offsetH, f
call ASCII_Table
movwf one
incf offsetL, f ;increment 16 bit pointer
btfsc STATUS , Z
incf offsetH, f
call ASCII_Table
movwf two
incf offsetL, f ;increment 16 bit pointer
btfsc STATUS , Z
incf offsetH, f
call ASCII_Table
movwf three
incf offsetL, f ;increment 16 bit pointer
btfsc STATUS , Z
incf offsetH, f
call ASCII_Table
movwf four
incf offsetL, f ;increment 16 bit pointer
btfsc STATUS , Z
incf offsetH, f
call ASCII_Table
movwf five
incf offsetL, f ;increment 16 bit pointer
btfsc STATUS , Z
incf offsetH, f
call ASCII_Table
movwf six
incf offsetL, f ;increment 16 bit pointer
btfsc STATUS , Z
incf offsetH, f
call ASCII_Table
movf min10,w
movwf seven
return
ASCII_Table ;perform read from long table
movlw High(Table)
addwf offsetH, W
movwf PCLATH
movlw Low(Table)
addwf offsetL, w
btfsc STATUS , C
incf PCLATH, f
MOVWF PCL
Delay1Sec call Delay250
call Delay250
call Delay250
call Delay250
Return
Delay255 movlw 0xff ;delay 255mS
goto d0
Delay250 movlw d'250' ;delay 250mS
goto d0
Delay100 movlw d'100' ;delay 100mS
goto d0
Delay50 movlw d'50' ;delay 50mS
goto d0
Delay20 movlw d'20' ;delay 20mS
goto d0
Delay10 movlw d'10' ;delay 10mS
goto d0
Delay1 movlw d'1' ;delay 1mS
goto d0
Delay5 movlw 0x05 ;delay 5ms
d0 movwf count1
d1 movlw 0xE7
movwf counta
movlw 0x04
movwf countb
Delay_0 decfsz counta, f
goto $+2
decfsz countb, f
goto Delay_0
decfsz count1 ,f
goto d1
retlw 0x00
Table
RETLW 0x00
RETLW 0x00
RETLW 0x3C
RETLW 0x42
RETLW 0x42
RETLW 0x3C
RETLW 0x00
RETLW 0x00 ;0
RETLW 0x00
RETLW 0x00
RETLW 0x00
RETLW 0x22
RETLW 0x7E
RETLW 0x02
RETLW 0x00
RETLW 0x00 ;1
RETLW 0x00
RETLW 0x00
RETLW 0x26
RETLW 0x4A
RETLW 0x4A
RETLW 0x32
RETLW 0x00
RETLW 0x00 ;2
RETLW 0x00
RETLW 0x00
RETLW 0x24
RETLW 0x42
RETLW 0x5A
RETLW 0x24
RETLW 0x00
RETLW 0x00 ;3
RETLW 0x00
RETLW 0x00
RETLW 0x00
RETLW 0x78
RETLW 0x08
RETLW 0x3E
RETLW 0x00
RETLW 0x00 ;4
RETLW 0x00
RETLW 0x00
RETLW 0x72
RETLW 0x52
RETLW 0x52
RETLW 0x4C
RETLW 0x00
RETLW 0x00 ;5
RETLW 0x00
RETLW 0x00
RETLW 0x3C
RETLW 0x52
RETLW 0x52
RETLW 0x0C
RETLW 0x00
RETLW 0x00 ;6
RETLW 0x00
RETLW 0x00
RETLW 0x40
RETLW 0x40
RETLW 0x5E
RETLW 0x60
RETLW 0x00
RETLW 0x00 ;7
RETLW 0x00
RETLW 0x00
RETLW 0x2C
RETLW 0x52
RETLW 0x52
RETLW 0x2C
RETLW 0x00
RETLW 0x00 ;8
RETLW 0x00
RETLW 0x00
RETLW 0x30
RETLW 0x4A
RETLW 0x4A
RETLW 0x3C
RETLW 0x00
RETLW 0x00 ;9
END