; 5x7 LED Array test ; PORTB used to select row (0 is on, 1 is off) ; PORTC<4:5> used for data,clk of 74164 Shift Reg list p=18F252 #include ;************************************************************ ; constants ; Number of columns in the display ; to change the number of displays, change NCHARS NCHARS equ d'6' NSTRINGS equ d'27' COLUMNS equ 5*NCHARS DWELL_TIME equ d'9' FontTable equ 0x01000 StringTable equ 0x00800 ;************************************************************ ; variables ; Used as counters for displaying the rows cblock 0x000 CurrentRow ; the row being displayed CurrentString ; index of current string being displayed CurrentColumn ; counts down from COLUMNS as chars are displayed CurrentCharIndex ; index of character currently being displayed CurrentCharData ; the character data to display AdvanceWidth ; advance width for char being drawn CurrentStrLen ; length of the current string RowRingCounter ; holds the ring counter for the row display DwellCounter ; how many iterations before scrolling endc ; Used by the shift register write routine cblock ShiftReg ; Temp var to hold shifting byte in ShiftBits ; number of bits to shift into shift reg ShiftCounter ; Temp counter endc ; Used to keep track of what string is being displayed cblock StringCharIndex ; index of current character in string StringSubCharIndex ; index into current character in bits endc ; Used for delay loops cblock DelayCountL DelayCountH endc ; Used in GetCharData subroutine cblock GCDTemp endc ;************************************************************ ;program code starts here org 00200h ; Beginning of program EPROM Start clrf LATB ; Clear PORTB output latch clrf TRISB ; Make PORTB pins all outputs clrf LATC ; init PORTC movlw b'10001000' movwf TRISC ; make most portc pins outputs clrf CurrentString ; start with string 0 ; Set up the string, char, subchar offsets here clrf CurrentCharIndex call GetStrChar ; get length byte (beginning of string) movwf CurrentStrLen movlw -NCHARS movwf StringCharIndex clrf StringSubCharIndex setf LATB ScrollLoop movlw DWELL_TIME movwf DwellCounter ; The same image gets displayed for DWELL_TIME iterations DwellLoop ; reset if programming switch is set... btfsc PORTC, 3 reset Display7Rows movlw b'10111111' movwf RowRingCounter ; set up display of high bit row first clrf CurrentRow DisplayRow movlw COLUMNS movwf CurrentColumn movf StringSubCharIndex,w addwf CurrentColumn,f movff StringCharIndex,CurrentCharIndex DisplayChar ; lookup data for current char movf CurrentCharIndex,w call GetCharData movlw 0x5 addwf AdvanceWidth,w cpfsgt CurrentColumn goto DisplayLastChar movwf ShiftBits movf CurrentCharData,w call ShiftData movlw 0x5 addwf AdvanceWidth,w subwf CurrentColumn,f ; check for more columns to display bz DisplayNextRow ; done if no columns left to display incf CurrentCharIndex ; else go to next char goto DisplayChar ; and repeat routine till done DisplayLastChar movff CurrentColumn,ShiftBits ; note: don't advance last char! movf CurrentCharData,w call ShiftData DisplayNextRow ; Pause for long enough for somebody to see the data movff RowRingCounter, LATB call Delay clrf LATB comf LATB rrncf RowRingCounter,f ; move to next row incf CurrentRow movlw 0x7 cpfseq CurrentRow goto DisplayRow DisplayRowsDone decfsz DwellCounter goto DwellLoop movff StringCharIndex,CurrentCharIndex call GetCharData incf StringSubCharIndex movlw 0x5 addwf AdvanceWidth,w cpfseq StringSubCharIndex goto ScrollLoop clrf StringSubCharIndex incf StringCharIndex movf CurrentStrLen, w cpfseq StringCharIndex goto ScrollLoop incf CurrentString movlw NSTRINGS cpfslt CurrentString clrf CurrentString clrf CurrentCharIndex call GetStrChar ; get length byte (beginning of string) movwf CurrentStrLen movlw -NCHARS movwf StringCharIndex goto ScrollLoop ; Delay Subroutine Delay ; return clrf DelayCountL Delay1 decfsz DelayCountL goto Delay1 return ; ShiftData subroutine ; takes the byte in w and shifts it into the shift register ; shifts ShiftBits bits, starting with the MSB ShiftData movwf ShiftReg movff ShiftBits, ShiftCounter ; test the last bit, put it into output bit ; we are inverting the output here ShiftData_Loop btfsc ShiftReg, 4 bsf LATC, 4 btfss ShiftReg, 4 bcf LATC, 4 ; strobe the SR clock bsf LATC, 5 bcf LATC, 5 ; keep going until all 5 bits are shifted rlncf ShiftReg, f decfsz ShiftCounter,f goto ShiftData_Loop return ; GetStrChar routine ; return the CurrentCharIndex'th character from the string at ; index CurrentString (in w) GetStrChar movf CurrentString,w ; TBLPTRH:TBLPTRL gets string offset mullw 0x40 ; (string starts at PRODH:PRODL) movff PRODH, TBLPTRH movf PRODL, w addwf CurrentCharIndex,0 ; add current character offset back into w movwf TBLPTRL btfsc STATUS, C incf TBLPTRH movlw (StringTable>>8)&0xff ; add base offset of StringTable addwf TBLPTRH ; high order movlw StringTable&0xff addwf TBLPTRL ; then low order byte btfsc STATUS, C incf TBLPTRH tblrd* ; TABLAT gets character code movf TABLAT,w ; return character code in w return ; GetCharData subroutine ; returns character data of char at index w for row CurrentRow ; value returned in CurrentCharData ; **REPLACE THIS WITH SOMETHING SMARTER** GetCharData ; Calculate offset of char in table movwf GCDTemp movf CurrentStrLen, w cpfslt GCDTemp goto GetCharDataNull movlw 0x00 cpfsgt GCDTemp goto GetCharDataNull call GetCharDataFromTable movwf CurrentCharData return GetCharDataNull clrf CurrentCharData clrf AdvanceWidth ; don't advance on null return GetCharDataFromTable call GetStrChar ; get next character mullw 0x08 ; TBLPTRH:TBLPTRL get row data offset movff PRODH, TBLPTRH ; (8 bytes/character) movff PRODL, TBLPTRL movf CurrentRow,w ; add in current row addwf TBLPTRL btfsc STATUS, C incf TBLPTRH movlw (FontTable>>8)&0xff ; then add FontTable base addr addwf TBLPTRH movlw FontTable&0xff addwf TBLPTRL btfsc STATUS, C incf TBLPTRH tblrd* clrf AdvanceWidth ; set AdvanceWidth if this char btfsc TABLAT, 5 ; requires an column extra space incf AdvanceWidth movf TABLAT, w return org StringTable #include "text.asm" org FontTable #include "5x7.asm" END ; directive indicates end of code