Hi,
Ive been working on my LCD code, which I had working at one point, on its own. I then tried to port this LCD code into the other code ive been working on and now all I get is solid boxes on the top row of the LCD.
Ive pasted my code below, can anyone see a reason why the LCD might be doing this? Any help or advise would be hugely appreciated.
Ive been working on my LCD code, which I had working at one point, on its own. I then tried to port this LCD code into the other code ive been working on and now all I get is solid boxes on the top row of the LCD.
Ive pasted my code below, can anyone see a reason why the LCD might be doing this? Any help or advise would be hugely appreciated.
Code:
;****************************************************************************
;
; TACHOMETER WITH LCD AND STEPPER MOTOR
;
;****************************************************************************
PROCESSOR PIC16F628
INCLUDE P16F628.INC
RADIX DEC
ERRORLEVEL -302,-305
#DEFINE DATUM PORTA ; PORT FOR LCD DATA.
#DEFINE STEPP PORTB ; PORT FOR STEPPER DATA.
#DEFINE CONTROL PORTB ; PORT FOR LCD CONTROL.
#DEFINE CLKFRQ 4000 ; CPU CLOCK FREQUENCY IN KHZ
#DEFINE LCD_PORT PORTB
#DEFINE LCD_TRIS TRISB
;LCD_PORT bits
DATA7 EQU .7 ; )
DATA6 EQU .6 ; )4 bit wide
DATA5 EQU .5 ; )data bus
DATA4 EQU .4 ; )
RS EQU .3 ; Register select - data or commands
E EQU .2 ; Chip enable
;RAM locations
SCREEN_DELAY_LOOP EQU 0x20
SCREEN_DELAY_LOOP1 EQU 0x21
MESS_POINTER EQU 0x22 ; Message pointer
WORD_STORE EQU 0x23 ; Store for commands / data information
TEMP_PCLATH EQU 0x24 ; Temp store for PCLATH during screen string routine
; cywizard begin
UNITS EQU 0X25
TENS EQU 0X26
HUNS EQU 0X27
; cywizard end
__CONFIG _BODEN_ON&_WDT_OFF&_LVP_OFF&_PWRTE_ON&_HS_OSC
;============================================================================
; MACRO TO CREATE OFFSETS FOR FILE REGISTERS IN RAM
;============================================================================
BYTEADDR SET 32 ; USER FILE REGISTERS START HERE
BYTE MACRO BYTENAME
BYTENAME EQU BYTEADDR
BYTEADDR SET BYTEADDR+1
ENDM
BYTE DATAL
BYTE REC_DATA
;============================================================================
; MACRO STRING
;============================================================================
; Macro to call SEND_SCREEN_STRING, enables message strings to start beyond first 256 memory block
; and to cross block boundaries. Costs a few extra instructions per call, but greatly simplifies
; string handling when dealing with > 256 bytes.
LCD_STRING macro lookup_address
movf PCLATH,W ; Store current value of PCLATH
movwf TEMP_PCLATH ; PCLATH may change below or in SEND_SCREEN_STRING
if high(lookup_address) != 0 ; if start address of string is > 255
movlw high(lookup_address)
movwf PCLATH ; update PCLATH for string start address
endif
movlw low(lookup_address)
call SEND_SCREEN_STRING
movf TEMP_PCLATH,W
movwf PCLATH ; Return PCLATH to original value
endm
;============================================================================
; RESET VECTOR
;============================================================================
ORG 0
GOTO MAIN
;============================================================================
; SETUP
;============================================================================
INITIALISE
movlw .20 ; ~15ms delay after screen power up before send to it
movwf SCREEN_DELAY_LOOP1 ; this delay is approx 15ms ( 20 x 256 x 3 us) @ 4MHz
clrf SCREEN_DELAY_LOOP
decfsz SCREEN_DELAY_LOOP,F
goto $-1
decfsz SCREEN_DELAY_LOOP1,F
goto $-3
movlw 0x20 ; set 4 bit data bus, at power up will be in 8 bit at this stage
call SEND_SCREEN_CMD ; will actually send 0x2? and 0x0? do D0-D3 float high/low
movlw 0x28 ; 4 bit, 2 line display
call SEND_SCREEN_CMD
movlw 0x06 ; Entry mode DD increment
call SEND_SCREEN_CMD
movlw 0x0E ; Display & cursor on, not flashing
call SEND_SCREEN_CMD ; Cursor is usefull while debuging, 0x0C for no cursor
call CLEAR_SCREEN
return
;============================================================================
; Clear Screen Macro
;============================================================================
CLEAR_SCREEN
movlw 0x01 ; Clear display, home cursor
call SEND_SCREEN_CMD
movlw .3 ; needs >= 1.64ms delay before next screen send
movwf SCREEN_DELAY_LOOP1 ; this delay is approx 2.3ms ( 3 x 256 x 3 us) @ 4MHz
clrf SCREEN_DELAY_LOOP
REP
decfsz SCREEN_DELAY_LOOP,F
goto REP
decfsz SCREEN_DELAY_LOOP1,F
goto REP
return
;============================================================================
; Screen Macro
;============================================================================
SEND_SCREEN_CMD
bcf LCD_PORT,RS
goto SEND
SEND_SCREEN_DATA
bsf LCD_PORT,RS
SEND
movwf WORD_STORE ; Store all 8 bits of data
movlw B'00001111'
andwf LCD_PORT,F ; Clear data
movf WORD_STORE,W ; Collect data
andlw B'11110000' ; Strip bottom four bits
iorwf LCD_PORT,F ; Move data MSB Reg. B
nop ; all nops to allow port settle prior to next change
bsf LCD_PORT,E ; Enable screen
nop
bcf LCD_PORT,E
movlw B'00001111'
andwf LCD_PORT,F ; Clear data
swapf WORD_STORE,W ; Reverse nibbles of data
andlw B'11110000' ; Strip bottom four bits
iorwf LCD_PORT,F ; Move data LSB Reg. B
nop
bsf LCD_PORT,E ; Enable screen
nop
bcf LCD_PORT,E
movlw .12 ; Delay between screen sends needs to be >= 40us
movwf SCREEN_DELAY_LOOP ; ~12 x 3 us + call & return etc > 40 us between screen sends
GO_ROUND_AGAIN
decfsz SCREEN_DELAY_LOOP,F
goto GO_ROUND_AGAIN
return
;============================================================================
; Send String Macro
;============================================================================
SEND_SCREEN_STRING
movwf MESS_POINTER
call MESSAGE_DATA ; Fetch address command
call SEND_SCREEN_CMD ; Send address set command
NEXT_DATA
incfsz MESS_POINTER,F ; Increment message pointer and check for overflow
goto NO_OVERFLOW
incf PCLATH,F ; inc PCLATH to move to next 256 memory block
NO_OVERFLOW
call MESSAGE_DATA ; fetch data
addlw .0 ; add zero, if data was 0 then Z of status will be set
btfsc STATUS,Z ; Test for stop byte
return ; This message finished, return
call SEND_SCREEN_DATA ; Display character
goto NEXT_DATA
;============================================================================
; Message Data Macro
;============================================================================
MESSAGE_DATA
; Screen lookup table.
; Each string starts with an address command byte and is terminated by a zero.
; DT means Define Table and is an assembler instruction, the assembler converts this to a
; series of retlw's, DT's are generally more readable except when defining chars.
movf MESS_POINTER,W
movwf PCL
; org 0x0f6 ; Debug only DELETE these 2 lines !!!!!!!!!!!!!!
; ; me testing macro !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
user_defs
; User defined char 5 x 7 plus 1 cursor line
; three most significant bits are ignored by screen
; MSB set to 1 to avoid 0 end of string marker in mid string.
retlw 0x48 ; Start address of second character (1) in character generator ram.
;char 1 ; The first character (0) is difficult to use as it can't be embedded
; in a string as 0 is used as end of string marker.
retlw b'10001010'
retlw b'10000000'
retlw b'10000100'
retlw b'10000100'
retlw b'10000000'
retlw b'10010001'
retlw b'10001110'
retlw b'10000000' ; cursor line, sometimes separated from other 7 rows
;char 2
retlw b'10001010' ; 0x50 start address of char 2
retlw b'10000000'
retlw b'10000100'
retlw b'10000100'
retlw b'10000000'
retlw b'10001110'
retlw b'10010001'
retlw b'10000000' ; cursor line, sometimes separated from other 7 rows
retlw 0 ; 0 marks end of string
hello_world
DT 0x80,"Hello World",0 ; 0x80 is effective address of first char on first line
smiley ; 0xC0 is effective address of first char on second line
DT 0xC0,"Userdef char ",.1,.2,0 ; string followed by userdefined chars 1 & 2 as defined above
;============================================================================
; MAIN PROGRAM
;============================================================================
MAIN
IFDEF __16F628
MOVLW B'00000111'
MOVWF CMCON ; DISABLE COMPARATOR
ENDIF
clrf LCD_PORT
bsf STATUS,RP0 ; Change to bank 1
movlw b'00000000' ; unused bits 0 & 1
movwf LCD_TRIS ; Set data / control lines to Output
bcf STATUS,RP0 ; Go back to bank 0
call INITIALISE ; Set up port and screen ; NEW
CLRF PORTA
CLRF PORTB
MOVLW B'11110000' ; SET PORTA DIRECTIONS
TRIS PORTA
MOVLW B'00000010' ; SET PORTB DIRECTIONS
TRIS PORTB
; NO WEAK PULLUPS, RB0 INT RISING EDGE, TMR0 ON RA4, PRESCALE 1:256
MOVLW B'11110111'
OPTION
; ------------------------------------
; Display Message
; ------------------------------------
LCD_STRING hello_world ; Use Macro to send string from lookup table to LCD
LCD_STRING user_defs ; Define "graphics" characters
LCD_STRING smiley ; Display user defined graphic characters
; ------------------------------------
; SET BAUD RATE TO COMMUNICATE WITH PC
; ------------------------------------
; BOOT BAUD RATE = 9600, NO PARITY, 1 STOP BIT
;
MOVLW 0X19 ; 0X19=9600 BPS (0X0C=19200 BPS)
BANKSEL SPBRG
MOVWF SPBRG
MOVLW B'00100100' ; BRGH = HIGH (2)
BANKSEL TXSTA
MOVWF TXSTA ; ENABLE ASYNC TRANSMISSION, SET BRGH
BCF STATUS,RP0 ; RAM PAGE 0
MOVLW B'10010000' ; ENABLE ASYNC RECEPTION
BANKSEL RCSTA
MOVWF RCSTA
;
; ------------------------------------
; PROVIDE A SETTLING TIME FOR START UP
; ------------------------------------
;
CLRF DATAL
SETTLE DECFSZ DATAL,F
GOTO SETTLE
BANKSEL RCREG
MOVF RCREG,W
MOVF RCREG,W
MOVF RCREG,W ; FLUSH RECEIVE BUFFER
; CALL SERIAL_MESSAGE ;TO DELETE
START:
;cywizard begin
CALL INITIALISE
;cywizard end
MAINLOOP:
CALL RECEIVE
MOVWF REC_DATA
;cywizard begin
CALL CONVERT
MOVF HUNS, W
CALL SEND_SCREEN_STRING
MOVF TENS, W
CALL SEND_SCREEN_STRING
MOVF UNITS, W
CALL SEND_SCREEN_STRING
;cywizard end
GOTO MAINLOOP
;
; -------------------------------------------
; RECEIVE CHARACTER FROM RS232 AND STORE IN W
; -------------------------------------------
; THIS ROUTINE DOES NOT RETURN UNTIL A CHARACTER IS RECEIVED.
;
RECEIVE
BANKSEL PIR1
BTFSS PIR1,RCIF ; (5) CHECK FOR RECEIVED DATA
GOTO RECEIVE
BANKSEL RCREG
MOVF RCREG,W ; SAVE RECEIVED DATA IN W
RETURN
;cywizard begin
; -------------------------------------------
; Convert to ASCII
; -------------------------------------------
CONVERT
movf REC_DATA, w
movwf UNITS
movlw '0'
movwf HUNS
movwf TENS
DO100S
movlw .100
subwf UNITS,W
btfss STATUS,C
goto DO10S
movwf UNITS
incf HUNS,F
goto DO100S
DO10S
movlw .10
subwf UNITS,W
btfss STATUS,C
goto ADJUST
movwf UNITS
incf TENS,F
goto DO10S
ADJUST
movlw '0'
addwf UNITS,F
return
;cywizard end
END
Last edited: