Usually issues with junk appearing in the display have to do with not allowing the LCD time to process commands.
If you want to hammer the display as fast as possible then you might try reading the BUSY status flag between operations.
Try this and see if it gets any better (untested, so beware)...
Code:
'-------------------------------------------------------------------------------
define OSC 4
OSCCON=%01101010 'OSC is @ 4 MHZ
'------------- LCD DEFINES ------------------------
DEFINE LCD_DREG PORTB 'LCD data port
DEFINE LCD_DBIT 4 'LCD data starting bit 0 or 4
DEFINE LCD_RSREG PORTA 'LCD register select port
DEFINE LCD_RSBIT 7 'LCD register select bit
DEFINE LCD_RWREG PORTA 'LCD read/write port
DEFINE LCD_RWBIT 0 'LCD read/write pin bit
DEFINE LCD_EREG PORTA 'LCD enable port
DEFINE LCD_EBIT 6 'LCD enable bit
DEFINE LCD_BITS 4 'LCD bus size 4 or 8
DEFINE LCD_LINES 2 'Number lines on LCD
DEFINE LCD_COMMANDUS 6200 'command delay time (in us) - clear display requires 6.2ms
DEFINE LCD_DATAUS 50 'data delay time (in us)
'-------------------------------------------------------------------------------
PORTA = %00000000
PORTB = %00000000
TRISA = %00000000
TRISB = %00000000
ANSELA = %00000
ANSELB = %00000000
'ADCON0=%00000001
'ADCON1=%10110000
'OPTION_REG.7=0
'-------------------------------------------------------------------------------
pause 500 'wait for display powerup
lcdout $FE,$28 'function set 4-bit mode
call lcd_busy_wait
lcdout $FE,$08 'display off
call lcd_busy_wait
lcdout $FE,$06 'entry mode set
call lcd_busy_wait
lcdout $FE,$17 'char mode + internal power
call lcd_busy_wait
lcdout $FE,$01 'clear display (requires long delay)
call lcd_busy_wait
lcdout $FE,$02 'home
call lcd_busy_wait
lcdout $FE,$0C 'display on
MAIN:
call lcd_busy_wait
lcdout $FE,$80,"BU BiR DENEMEDiR"
call lcd_busy_wait
lcdout $FE,$C0," iKiNCi SATIR "
goto main
'sub lcd_busy_wait
'read lcd busy flag until busy=0
WAITST CON 1 ' delay 1us
busy var bit
lcd_busy_wait:
busy = 1
TRISB = TRISB or $F0 'set PORTB D4-D7 to inputs
@ bcf LCD_RSREG, LCD_RSBIT 'RS=0
@ bsf LCD_RWREG, LCD_RWBIT 'RW=1
pauseus WAITST
'wait for lcd busy flag (D7) to be low
do while (busy = 1)
@ bsf LCD_EREG, LCD_EBIT 'EN=1
pauseus WAITST
busy = PORTB.7 'read busy bit (bit 7 in upper nibble)
@ bcf LCD_EREG, LCD_EBIT 'EN=0
pauseus WAITST
' dummy read of lower nibble
@ bsf LCD_EREG, LCD_EBIT 'EN=1
pauseus WAITST
@ bcf LCD_EREG, LCD_EBIT 'EN=0
pauseus WAITST
loop
TRISB = TRISB and not $F0 'set PORTB D4-D7 back to outputs
@ bcf LCD_RWREG, LCD_RWBIT 'RW=0
return
You might find that you need to split the cursor position commands and data...
Code:
call lcd_busy_wait
lcdout $FE,$80 'move cursor
call lcd_busy_wait
lcdout "BU BiR DENEMEDiR" 'send data
Even with doing things like this some displays just don't like being continuously written to and you need to use delays.
Reading the BUSY flag really needs to be done for each byte transferred, so it may not help much at all.
Bookmarks