Re: serial LCD 1602 Backpack using PIC16F690 for Hitach HD44780
My code honours the timing as specified by the lcd defines , timing that most lcd displays need esp the cheapest and oldest examples of them.
If you send data at a rate that exceeds the specified time constraints as defined it will of course fall. The solution is to either pace data transmission or set the defines to the actual speed the lcd can tolerate . The intent of my code is to match data rate to the real speed that the lcd can manage
Re: serial LCD 1602 Backpack using PIC16F690 for Hitach HD44780
set pace to 1 , and it's working
sEROUT2 lcd,baudR,pace,[254,128,"ABCDEFGHIJKLMNOP"]
thanks.
Re: serial LCD 1602 Backpack using PIC16F690 for Hitach HD44780
I only tested at 19200 and the Backlight works OK.
But text, could not send up to this moment.
WIll try different Baud Rate. Though I test on a PIC16F1827 at 32MHz.
Ioannis
2 Attachment(s)
Re: serial LCD 1602 Backpack using PIC16F690 for Hitach HD44780
when testing baud rate, usualy I start at 300 and up
when it stopped working then I set pace = 1
and re-start from the last baud rate tested.
16F690 Xtal 20Mhz
set pace to 1
sEROUT2 lcd,baudR,pace,[254,128,"ABCDEFGHIJKLMNOP"]
from my code here's the tested baud rate .
and when booting the PIC's at different baud rate the sender 12F683 and receiver 16F690 the LCD screen light up right away and start displaying text, and back light on/off
there's no lag for the first receiving if I remember correctly the pace for the sender is set = 0.
Attachment 9994
Also I add baud rate selection jumpers on the Backpack''
Attachment 9995
' Jumpers
'
J3 300 600 1200 2400 4800 9600 14400 19200 28800 38400
' 1--2 RB7 On On On On On On
' 3--4 RA2 On On On On
' 5--6 RA1 On On On On
' 7--8 RA3 On On On
' Baud Rate SW Selection (PCB J3)
If PORTA = 001110 And PORTB.7 = 1 Then BaudR = 3313 ' 300
If PORTA = 001110 And PORTB.7 = 0 Then BaudR = 1646 ' 600
If PORTA = 001010 And PORTB.7 = 1 Then BaudR = 813 ' 1200
If PORTA = 001100 And PORTB.7 = 1 Then BaudR = 396 ' 2400
If PORTA = 000110 And PORTB.7 = 1 Then BaudR = 188 ' 4800
If PORTA = 001010 And PORTB.7 = 0 Then BaudR = 84 ' 9600
If PORTA = 001100 And PORTB.7 = 0 Then BaudR = 49 ' 14400
If PORTA = 000110 And PORTB.7 = 0 Then BaudR = 32 ' 19200
If PORTA = 001000 And PORTB.7 = 0 Then BaudR = 15 ' 28800
If PORTA = 000000 And PORTB.7 = 0 Then BaudR = 6 ' 38400
1 Attachment(s)
Re: serial LCD 1602 Backpack using PIC16F690 for Hitach HD44780
from my last edit,
' Jumpers
' J3 300 600 1200 2400 4800 9600 14400 19200 28800 38400
' 1--2 RB7 On On On On On On
' 3--4 RA2 On On On On
' 5--6 RA1 On On On On
' 7--8 RA3 On On On
I think courier new does not take spaces !
better use screen cap
Attachment 9996
1 Attachment(s)
Re: serial LCD 1602 Backpack using PIC16F690 for Hitach HD44780
edited BaudR var word : baudr = 3313 and TRISA = 111110
1st receiving random characters
2nd normal
what could be done to avoid the first
thanks.
Attachment 9997
Re: serial LCD 1602 Backpack using PIC16F690 for Hitach HD44780
its always better to use the hardware than bit-banged routines and there is nothing better than a ring-buffer to overcome traffic snarls
Code:
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Name : 16F690 LCD BACKPACK
' Date : oct 2025 richard
' Note : RING BUFFERED
' Notes : 19200 Intrc_OSC 8Mhz
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
#CONFIG
cfg = _INTRC_OSC_NOCLKOUT
cfg&= _WDT_OFF
cfg&= _PWRTE_OFF
cfg&= _MCLRE_OFF
cfg&= _CP_OFF
cfg&= _CPD_OFF
cfg&= _BOD_OFF
cfg&= _IESO_OFF
cfg&= _FCMEN_OFF
__CONFIG cfg
#ENDCONFIG
DEFINE OSC 8
DEFINE INTHAND myint
ANSEL = 0 ' Set all pins digital
ANSELH = 0 ' Set all pins digital
OPTION_REG.7 = 0 ' PORTA/PORTB pull-ups are enabled by individual port latch values
CLEAR
DEFINE LCD_BITS 8 'defines the number of data interface lines (4 or 8)
DEFINE LCD_DREG PORTC 'defines the port where data lines are connected to
DEFINE LCD_RSREG PORTB 'defines the port where RS line is connected to
DEFINE LCD_RSBIT 6 'defines the pin where RS line is connected to
DEFINE LCD_EREG PORTB 'defines the port where E line is connected to
DEFINE LCD_EBIT 4 'defines the pin where E line is connected
DEFINE LCD_COMMANDUS 1500 'defines the delay after LCDOUT statement
DEFINE LCD_DATAUS 50 'delay in micro seconds
RCSTA = $90 ' Enable serial port & continuous receive
TXSTA = $20 ' Enable transmit, BRGH = 0
SPBRG = 25 ' 19200 Baud @ 8MHz, 0.16%
SPBRGH = 0
BAUDCTL.3 = 1 ' Enable 16 bit baudrate generator
wsave VAR BYTE $70 SYSTEM ;wsave in access RAM
ssave VAR BYTE BANK0 SYSTEM
psave VAR BYTE BANK0 SYSTEM
index_in VAR BYTE bank0 ' Pointer - next empty location in buffer
index_out VAR BYTE bank0 ' Pointer - location of oldest character in buffer
errflag VAR BYTE bank0 ' Error flag
UartFlag VAR errflag.0
BufferFlag VAR errflag.1
buffer_size CON 32 ' Sets the size of the ring buffer
buffer VAR BYTE[buffer_size] ' Array variable for holding received characters
bufchar VAR BYTE ' Stores the character retrieved from the buffer
Bl var byte
GOTO overint ' Jump over the interrupt handler
ASM
myint
if CODE_SIZE <= 2 ; If less than 2K code space
; Save the state of critical registers (PIC12/PIC16)
movwf wsave ; Save W
swapf STATUS,W ; Swap STATUS to W (swap avoids changing STATUS)
clrf STATUS ; Clear STATUS
movwf ssave ; Save swapped STATUS
movf PCLATH,W ; Move PCLATH to W
movwf psave ; Save PCLATH
endif
; Check for hardware overrun error
btfsc RCSTA,OERR ; Check for usart overrun
goto usart_err ; jump to assembly error routine
; Test for buffer overrun
incf _index_in,W ; Increment index_in to W
subwf _index_out,W ; Subtract indexes to test for buffer overrun
btfsc STATUS,Z ; check for zero (index_in = index_out)
goto buffer_err ; jump to error routine if zero
; Increment the index_in pointer and reset it if it's outside the ring buffer
incf _index_in,F ; Increment index_in to index_in
movf _index_in,W ; Move new index_in to W
sublw _buffer_size-1; Subtract index_in from buffer_size-1
btfss STATUS, C ; If index_in => buffer_size
clrf _index_in ; Clear index_in
; Set FSR with the location of the next empty location in buffer
movlw _buffer ;Store the High byte of buffer to FSR
movwf FSR
addwf _index_in,W ; Add index_in to point to next empty slot
movwf FSR ; Store Low byte of pointer in FSR
; Read and store the character from the USART
movf RCREG,W ; Read the received character
movwf INDF ; Put the received character in FSR location
BTFSC PIR1,RCIF ;ANY MORE ?
goto myint
finished
; Restore the state of critical registers (PIC12/PIC16)
movf psave,W ; restore PCLATH
movwf PCLATH
swapf ssave,W ; restore STATUS
movwf STATUS
swapf wsave,F ; restore W (swap avoids changing STATUS)
swapf wsave,W
retfie ; Return from interrupt
; Error routines
buffer_err ; Jump here on buffer error
bsf _errflag,1 ; Set the buffer flag
usart_err ; Jump here on USART error
bsf _errflag,0 ; Set the USART flag
movf RCREG, W ; Trash the received character
goto finished ; Restore state and return to program
ENDASM
overint:
TRISC = 0
TRISB = % 10101111
TRISA = % 11111110
OSCCON = $70
PAUSE 500
hserout ["ready @19200"]
LCDOUT $FE,1
LCDOUT "ready @19200"
PAUSE 500
@ bsf LCD_RSREG ,LCD_RSBIT
INTCON = $C0
PIE1.5 = 1
GOSUB ERROR
main:
IF errflag Then GOSUB error ' Goto error routine if needed
IF index_in = index_out Then main ' loop if nothing in buffer
GoSub getbuf ' Get a character from buffer
' hserout [bufchar] ' Send the character to terminal
if bl then
if bufchar = 0 then
porta.0 = 0 ' Back Light OFF
endif
if bufchar = 8 then
porta.0 = 1 ' Back Light ON
endif
bl = 0
goto main
endif
if bufchar = 255 then
bl = 1
goto main
endif
if bufchar = 254 then
@ bcf LCD_RSREG ,LCD_RSBIT
goto main
endif
@ MOVE?BB _bufchar,R3
@ L?CALL lcdsend
@ bsf LCD_RSREG ,LCD_RSBIT
goto main ' loop back to top
error: ' Display error message
INTCON = 0 ' Disable interrupts while in the error routine
IF errflag.1 Then ' Determine the error
hserout ["B!",13]' Display buffer error on line-2
Else
hserout ["U!",13] ' Display usart error on line_2
EndIF
PIR1.5=0
errflag = 0 ' Reset the error flag ;clear any rcsta error
RCSTA.4=0 'CREN = 0 Disable continuous receive to clear hardware error
RCSTA.4=1 'CREN = 1 Enable continuous receive
INTCON = %11000000 ' Enable interrupts
RETURN ' repeat
getbuf: ' Move the next character in buffer to bufchar
index_out = index_out + 1 ' Increment index_out pointer (0 to 31)
IF index_out => buffer_size Then index_out = 0 ' Reset pointer if outside buffer
bufchar = buffer[index_out] ' Read buffer location(index_out)
Return
Re: serial LCD 1602 Backpack using PIC16F690 for Hitach HD44780
ASM , very impressif code,
thanks.
1 Attachment(s)
Re: serial LCD 1602 Backpack using PIC16F690 for Hitach HD44780
here's the revised baud rate test chart
Attachment 9998
Re: serial LCD 1602 Backpack using PIC16F690 for Hitach HD44780
Tried different baud rate but still only Backlight work. The rest is just irrelevant characters on screen.
Then tried the new code of Richards, but have 1827 chip, so asm code is not compatible.
Gave up...
Ioannis
Re: serial LCD 1602 Backpack using PIC16F690 for Hitach HD44780
maybe the chip?
for my part I used
12F683, 16F690 old regular Pic.
I tried richard code, and it's impressive asm code, that I can't do for sure.
so I stick to basic.
when you're back on this LCD, try this 'self text' backpack for 16F690 maybe it will give a hint.
Code:
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Name : 16F690 LCD BACKPACK Self Text
' File : "D:\PIC\PBP3\16F690\LCD BACKPACK\16F690 LCD BACKPACK Self Text.pbp"
' Date : Oct 4-2025
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Serin2
'#CONFIG
' __config _INTRC_OSC_CLKOUT & _WDT_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _BOD_OFF & _IESO_OFF & _FCMEN_OFF
'#ENDCONFIG
' HSERIN
#CONFIG
__config _HS_OSC & _WDT_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _BOD_OFF & _IESO_OFF & _FCMEN_OFF
#ENDCONFIG
DEFINE OSC 20 ' Core is running at EXT-CRYSTAL 20MHz PBP 33,217
'DEFINE OSC 8
ANSEL = 0 ' Set all pins digital
ANSELH = 0 ' Set all pins digital
OPTION_REG.7 = 0 ' PORTA/PORTB pull-ups are enabled by individual port latch values
CM1CON0 = 0 ' Analog comparators off
En var Portb.4 : low en
RS var Portb.6 : low rs
B1 var byte : b1 = 0
C VAR BYTE : C = 100
I VAR BYTE
' 1602
ArrayA var Byte [16] : ARRAYWRITE ArrayA,["ABCDEF1234567890"] ' Line 1
ArrayB var Byte [16] : ARRAYWRITE ArrayB,["1234567890!@#$%^"] ' Line 2
' 2004
'ArrayC var Byte [20] : ARRAYWRITE ArrayC,["ABCDEF1234567890!@#$"] ' Line 1
'ArrayD var Byte [20] : ARRAYWRITE ArrayD,["1234567890!@#$%^!@#$"] ' Line 2
'ArrayE var Byte [20] : ARRAYWRITE ArrayE,["ABCDEF1234567890!@#$"] ' Line 3
'ArrayF var Byte [20] : ARRAYWRITE ArrayF,["1234567890!@#$%^!@#$"] ' Line 4
TRISA = 0 : TRISB = %00100000 : TRISC = 0
PORTA = 0 : PORTB = 0 : PORTC = 0
OSCCON = $70
pause 100
high Porta.0 ' Backlight ON
gosub LCDinit ' initialise LCD
pause 100
main:
' 1602
Low RS : PORTC = 128 : High En : PauseUS 1 : Low En : High RS : Pause 3 ' Line 1
For I = 0 To 15
PORTC = ArrayA[I]
High En : PauseUS 1 : Low En
Pause C
Next I
Low RS : PORTC = 192 : High En : PauseUS 1 : Low En : High RS : Pause 3 ' Line 2
For I = 0 To 15
PORTC = ArrayB[I]
High En : PauseUS 1 : Low En
Pause C
Next I
' 2004
'Low RS : PORTC = 128 : High En : PauseUS 1 : Low En : High RS : Pause 3 ' Line 1
'For I = 0 To 19
' PORTC = ArrayC[I]
' High En : PauseUS 1 : Low En
' Pause C
'Next I
'Low RS : PORTC = 192 : High En : PauseUS 1 : Low En : High RS : Pause 3 ' Line 2
'For I = 0 To 19
' PORTC = ArrayD[I]
' High En : PauseUS 1 : Low En
' Pause C
'Next I
'Low RS : PORTC = 148 : High En : PauseUS 1 : Low En : High RS : Pause 3 ' Line 3
'For I = 0 To 19
' PORTC = ArrayE[I]
' High En : PauseUS 1 : Low En
' Pause C
'Next I
'Low RS : PORTC = 212 : High En : PauseUS 1 : Low En : High RS : Pause 3 ' Line 4
'For I = 0 To 19
' PORTC = ArrayF[I]
' High En : PauseUS 1 : Low En
' Pause C
'Next I
Pause 1000
Low RS : PORTC = 1 : High En : PauseUS 1 : Low En : High RS : PauseUS 4 ' Clear display
Pause 500
'Low PORTA.0 ' Bacck Light off
Pause 200
High PORTA.0 ' Bacck Light on
Pause 200
C = C - 20
If C < 20 Then
C = 100
EndIf
GoTo main
LCDINIT: ' Standard LCD Module Initialisation
PORTC = %00000001 : HIGH EN : PAUSEus 1 : LOW EN : pause 4 ' Clear Display
PORTC = %00000010 : HIGH EN : PAUSEus 1 : LOW EN : pause 2 ' Return Home
PORTC = %00111000 : HIGH EN : PAUSEus 1 : LOW EN : Pause 2 ' 8 bit, 2 line, 5x8 Characters
PORTC = %00000110 : HIGH EN : PAUSEus 1 : LOW EN : Pause 2 ' Entry mode
PORTC = %00001100 : HIGH EN : PAUSEus 1 : LOW EN : Pause 2 ' %00001DCB Display on/off, Cursor on/off, Blink y/n
RETURN
Re: serial LCD 1602 Backpack using PIC16F690 for Hitach HD44780
For a 1827 it would look like this [untested]
Code:
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Name : 16F1827 LCD BACKPACK *
' Date : oct 2025 richard *
' Note : RING BUFFERED *
' Notes : DEFA BAUD RATE 9600 Intrc_OSC 8Mhz *
' eeprom full case is unhandled,factory reset would be advisable *
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
#CONFIG
__config _CONFIG1, _FOSC_INTOSC & _WDTE_ON & _PWRTE_OFF & _MCLRE_ON & _CP_OFF & _CPD_OFF & _BOREN_ON & _CLKOUTEN_OFF & _IESO_ON & _FCMEN_ON
__config _CONFIG2, _WRT_OFF & _PLLEN_OFF & _STVREN_ON & _BORV_19 & _LVP_OFF
#ENDCONFIG
;commands eg SEROUT2 lcd,84,[255,11] set baudrate from 9600 to 19200
'255 0/8 backlight
'255 10/11/12 baud rate 9600/19200/38400
'255 "F" factory reset
DEFINE OSC 8
DEFINE INTHAND myint
DEFINE WRITE_INT 1
ANSELA = 0 ' Set all pins digital
ANSELB = 0 ' Set all pins digital
OPTION_REG.7 = 0 ' PORTA/PORTB pull-ups are enabled by individual port latch values
CLEAR
DEFINE LCD_BITS 4 'defines the number of data interface lines (4 or 8)
DEFINE LCD_DREG PORTA 'defines the port where data lines are connected to
DEFINE LCD_DBIT 4
DEFINE LCD_RSREG PORTB 'defines the port where RS line is connected to
DEFINE LCD_RSBIT 6 'defines the pin where RS line is connected to
DEFINE LCD_EREG PORTB 'defines the port where E line is connected to
DEFINE LCD_EBIT 4 'defines the pin where E line is connected
DEFINE LCD_COMMANDUS 1500 'defines the delay after LCDOUT statement
DEFINE LCD_DATAUS 50 'delay in micro seconds
RCSTA = $90 ' Enable serial port & continuous receive
TXSTA = $20 ' Enable transmit, BRGH = 0
SP1BRG = 51 ' 19200 Baud @ 8MHz, 0.16%, 51 ' 9600 Baud @ 8MHz, 0.16%, 12 ' 38400 Baud @ 8MHz, 0.16%
SP1BRGH = 0
BAUDCON.3 = 1 ' Enable 16 bit baudrate generator
buffer_size CON 32 ' Sets the size of the ring buffer
index_in VAR BYTE bank0 ' Pointer - next empty location in buffer
index_out VAR BYTE bank0 ' Pointer - location of oldest character in buffer
errflag VAR BYTE bank0 ' Error flag
UartFlag VAR errflag.0
BufferFlag VAR errflag.1
buffer VAR BYTE[buffer_size] ' Array variable for holding received characters
bufchar VAR BYTE ' Stores the character retrieved from the buffer
Bl var byte
inx var byte
Br var byte
GOTO overint ' Jump over the interrupt handler
ASM
myint
; Check for hardware overrun error
btfsc RCSTA,OERR ; Check for usart overrun
goto usart_err ; jump to assembly error routine
; Test for buffer overrun
incf _index_in,W ; Increment index_in to W
subwf _index_out,W ; Subtract indexes to test for buffer overrun
btfsc STATUS,Z ; check for zero (index_in = index_out)
goto buffer_err ; jump to error routine if zero
; Increment the index_in pointer and reset it if it's outside the ring buffer
incf _index_in,F ; Increment index_in to index_in
movf _index_in,W ; Move new index_in to W
sublw _buffer_size-1; Subtract index_in from buffer_size-1
btfss STATUS, C ; If index_in => buffer_size
clrf _index_in ; Clear index_in
; Set FSR with the location of the next empty location in buffer
movlw _buffer ;Store the High byte of buffer to FSR
movwf FSR0
addwf _index_in,W ; Add index_in to point to next empty slot
movwf FSR0 ; Store Low byte of pointer in FSR
; Read and store the character from the USART
movf RCREG,W ; Read the received character
movwf INDF0 ; Put the received character in FSR location
BTFSC PIR1,RCIF ;ANY MORE ?
goto myint
finished
retfie ; Return from interrupt
; Error routines
buffer_err ; Jump here on buffer error
bsf _errflag,1 ; Set the buffer flag
usart_err ; Jump here on USART error
bsf _errflag,0 ; Set the USART flag
movf RCREG, W ; Trash the received character
goto finished ; Restore state and return to program
ENDASM
overint:
TRISB = % 00101111
TRISA = % 11110000
OSCCON = $70
PAUSE 500
gosub getbaud
PAUSE 5
LCDOUT $FE,1
hserout [13,"ready"]
LCDOUT "ready "
if br==51 then
hserout ["@9600"]
LCDOUT "@9600"
elseif br==25 then
hserout ["@19200"]
LCDOUT "@19200"
else
hserout ["@38400"]
LCDOUT "@38400"
endif
PAUSE 500
@ bsf LCD_RSREG ,LCD_RSBIT
GOSUB error
INTCON = $C0
PIE1.5 = 1
main:
IF errflag Then GOSUB error ' Goto error routine if needed
IF index_in = index_out Then main ' loop if nothing in buffer
GoSub getbuf ' Get a character from buffer
if bl then
if bufchar = 0 then
porta.0 = 0 ' Back Light OFF
endif
if bufchar = 8 then
porta.0 = 1 ' Back Light ON
endif
if bufchar = 10 then
write inx+1,51
gosub getbaud
endif
if bufchar = 11 then
write inx+1,25
gosub getbaud
endif
if bufchar = 12 then
write inx+1,12
gosub getbaud
endif
if bufchar = "F" then
gosub factory
endif
bl = 0
goto main
endif
if bufchar = 255 then
bl = 1
goto main
endif
if bufchar = 254 then
@ bcf LCD_RSREG ,LCD_RSBIT
goto main
endif
@ MOVE?BB _bufchar,R3
@ L?CALL lcdsend
@ bsf LCD_RSREG ,LCD_RSBIT
goto main ' loop back to top
error: ' Display error message
INTCON = 0 ' Disable interrupts while in the error routine
IF errflag.1 Then ' Determine the error
hserout ["B!",13]' Display buffer error on line-2
Else
hserout ["U!",13] ' Display usart error on line_2
EndIF
errflag = 0 ' Reset the error flag ;clear any rcsta error
RCSTA.4 = 0 'CREN = 0 Disable continuous receive to clear hardware error
RCSTA.4 = 1 'CREN = 1 Enable continuous receive
INTCON = %11000000 ' Enable interrupts
RETURN ' repeat
getbuf: ' Move the next character in buffer to bufchar
index_out = index_out + 1 ' Increment index_out pointer (0 to 31)
IF index_out => buffer_size Then index_out = 0 ' Reset pointer if outside buffer
bufchar = buffer[index_out] ' Read buffer location(index_out)
Return
getbaud:
bufchar = 0
inx = 255
read inx,Br
while Br==255
read inx,Br
if Br==255 then
if inx == 0 then
br=51
write inx,51
hserout [13,"init@9600 " ,dec inx,",",dec Br]
else
inx = inx-1
endif
endif
wend ;note if inx=255 then eeprom full
hserout [" index " ,dec inx,",",dec Br]
SP1BRG = Br
Return
factory:
write 0,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
write 16,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
write 32,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
write 48,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
write 64,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
write 80,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
write 96,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
write 112,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
write 128,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
write 144,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
write 160,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
write 176,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
write 192,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
write 208,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
write 224,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
write 240,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
gosub getbaud
Return
Re: serial LCD 1602 Backpack using PIC16F690 for Hitach HD44780
a bit out of practice , forgot porta.4 is input only plus 1827 has bits and pieces in other banks
so tested and working version
Code:
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Name : 16F1827 LCD BACKPACK *
' Date : oct 2025 richard *
' Note : RING BUFFERED *
' Notes : DEFA BAUD RATE 9600 Intrc_OSC 8Mhz *
' eeprom full case is unhandled,factory reset would be advisable *
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
#CONFIG
__config _CONFIG1, _FOSC_INTOSC & _WDTE_ON & _PWRTE_OFF & _MCLRE_ON & _CP_OFF & _CPD_OFF & _BOREN_ON & _CLKOUTEN_OFF & _IESO_ON & _FCMEN_ON
__config _CONFIG2, _WRT_OFF & _PLLEN_OFF & _STVREN_ON & _BORV_19 & _LVP_OFF
#ENDCONFIG
;commands eg SEROUT2 lcd,84,[255,11] set baudrate from 9600 to 19200
'255 0/8 backlight
'255 10/11/12 baud rate 9600/19200/38400
'255 "F" factory reset
;TX PORTB.2 RX PORTB.1 BACKLIGHT PORTB.0
DEFINE OSC 8
DEFINE INTHAND myint
DEFINE WRITE_INT 1
ANSELA = 0 ' Set all pins digital
ANSELB = 0 ' Set all pins digital
' OPTION_REG.7 = 0 ' PORTA/PORTB pull-ups are enabled by individual port latch values
CLEAR
DEFINE LCD_BITS 4 'defines the number of data interface lines (4 or 8)
DEFINE LCD_DREG PORTA 'defines the port where data lines are connected to
DEFINE LCD_DBIT 0
DEFINE LCD_RSREG PORTB 'defines the port where RS line is connected to
DEFINE LCD_RSBIT 6 'defines the pin where RS line is connected to
DEFINE LCD_EREG PORTB 'defines the port where E line is connected to
DEFINE LCD_EBIT 4 'defines the pin where E line is connected
DEFINE LCD_COMMANDUS 1500 'defines the delay after LCDOUT statement
DEFINE LCD_DATAUS 50 'delay in micro seconds
RCSTA = $90 ' Enable serial port & continuous receive
TXSTA = $20 ' Enable transmit, BRGH = 0
SP1BRG = 51 ' 19200 Baud @ 8MHz, 0.16%, 51 ' 9600 Baud @ 8MHz, 0.16%, 12 ' 38400 Baud @ 8MHz, 0.16%
SP1BRGH = 0
BAUDCON.3 = 1 ' Enable 16 bit baudrate generator
buffer_size CON 32 ' Sets the size of the ring buffer
index_in VAR BYTE bank0 ' Pointer - next empty location in buffer
index_out VAR BYTE bank0 ' Pointer - location of oldest character in buffer
errflag VAR BYTE bank0 ' Error flag
UartFlag VAR errflag.0
BufferFlag VAR errflag.1
buffer VAR BYTE[buffer_size] ' Array variable for holding received characters
bufchar VAR BYTE ' Stores the character retrieved from the buffer
Bl var byte
inx var byte
Br var byte
GOTO overint ' Jump over the interrupt handler
ASM
myint
; Check for hardware overrun error
banksel RCSTA
btfsc RCSTA,OERR ; Check for usart overrun
goto usart_err ; jump to assembly error routine
; Test for buffer overrun
banksel 0
incf _index_in,W ; Increment index_in to W
subwf _index_out,W ; Subtract indexes to test for buffer overrun
btfsc STATUS,Z ; check for zero (index_in = index_out)
goto buffer_err ; jump to error routine if zero
; Increment the index_in pointer and reset it if it's outside the ring buffer
incf _index_in,F ; Increment index_in to index_in
movf _index_in,W ; Move new index_in to W
sublw _buffer_size-1; Subtract index_in from buffer_size-1
btfss STATUS, C ; If index_in => buffer_size
clrf _index_in ; Clear index_in
; Set FSR with the location of the next empty location in buffer
movlw High _buffer ;Store the High byte of buffer to FSR0H
movwf FSR0H
movlw Low _buffer ; Get the Low byte of buffer[0]
addwf _index_in,W ; Add index_in to point to next empty slot
movwf FSR0L ; Store Low byte of pointer in FSR0
; Read and store the character from the USART
banksel RCREG
movf RCREG,W ; Read the received character
movwf INDF0 ; Put the received character in FSR location
banksel PIR1
BTFSC PIR1,RCIF ;ANY MORE ?
goto myint
finished
RST?RP
retfie ; Return from interrupt
; Error routines
buffer_err ; Jump here on buffer error
bsf _errflag,1 ; Set the buffer flag
usart_err ; Jump here on USART error
banksel _errflag
bsf _errflag,0 ; Set the USART flag
banksel RCREG
movf RCREG, W ; Trash the received character
goto finished ; Restore state and return to program
ENDASM
overint:
TRISB = %10101010
TRISA = %11110000
OSCCON = $70
PAUSE 500
gosub getbaud
PAUSE 5
LCDOUT $FE,1
hserout [13,"ready"]
LCDOUT "ready "
if br==51 then
hserout ["@9600"]
LCDOUT "@9600"
elseif br==25 then
hserout ["@19200"]
LCDOUT "@19200"
else
hserout ["@38400"]
LCDOUT "@38400"
endif
PAUSE 500
@ bsf LCD_RSREG ,LCD_RSBIT
GOSUB error
INTCON = $C0
PIE1.5 = 1
main:
IF errflag Then GOSUB error ' Goto error routine if needed
IF index_in = index_out Then main ' loop if nothing in buffer
GoSub getbuf ' Get a character from buffer
if bl then
if bufchar = 0 then
portB.0 = 0 ' Back Light OFF
endif
if bufchar = 8 then
portB.0 = 1 ' Back Light ON
endif
if bufchar = 10 then
write inx+1,51
gosub getbaud
endif
if bufchar = 11 then
write inx+1,25
gosub getbaud
endif
if bufchar = 12 then
write inx+1,12
gosub getbaud
endif
if bufchar = "F" then
gosub factory
endif
bl = 0
goto main
endif
if bufchar = 255 then
bl = 1
goto main
endif
if bufchar = 254 then
@ bcf LCD_RSREG ,LCD_RSBIT
goto main
endif
@ MOVE?BB _bufchar,R3
@ MOVE?CT 1,FLAGS ,0
@ L?CALL lcdsend
@ bsf LCD_RSREG ,LCD_RSBIT
goto main ' loop back to top
error: ' Display error message
INTCON = 0 ' Disable interrupts while in the error routine
IF errflag.1 Then ' Determine the error
hserout ["B!",13]' Display buffer error on line-2
Else
hserout ["U!",13] ' Display usart error on line_2
EndIF
errflag = 0 ' Reset the error flag ;clear any rcsta error
RCSTA.4 = 0 'CREN = 0 Disable continuous receive to clear hardware error
RCSTA.4 = 1 'CREN = 1 Enable continuous receive
INTCON = %11000000 ' Enable interrupts
RETURN ' repeat
getbuf: ' Move the next character in buffer to bufchar
index_out = index_out + 1 ' Increment index_out pointer (0 to 31)
IF index_out => buffer_size Then index_out = 0 ' Reset pointer if outside buffer
bufchar = buffer[index_out] ' Read buffer location(index_out)
Return
getbaud:
bufchar = 0
inx = 255
read inx,Br
while Br==255
read inx,Br
if Br==255 then
if inx == 0 then
br=51
write inx,51
hserout [13,"init@9600 " ,dec inx,",",dec Br]
else
inx = inx-1
endif
endif
wend ;note if inx=255 then eeprom full
hserout [" index " ,dec inx,",",dec Br]
SP1BRG = Br
Return
factory:
write 0,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
write 16,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
write 32,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
write 48,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
write 64,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
write 80,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
write 96,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
write 112,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
write 128,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
write 144,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
write 160,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
write 176,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
write 192,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
write 208,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
write 224,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
write 240,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
gosub getbaud
Return
Re: serial LCD 1602 Backpack using PIC16F690 for Hitach HD44780
Thanks Richard.
The new code:
- works OK with LCD Backlight On/Off
- works OK sending text over the serial port
- works OK sending commands to LCD over serial port
- On power up LCD shows ready@38400 and this does not change. But the communication baud rate is 9600. With 255,10 or 11 or12 can change baud rate but it is not displayed on LCD. Though higher baud rates need pace.
- On power up the terminal shows ready@38400U!
Have done two changes on port b to drive the RS and E signal on PortB.3 and PortB.4.
PortB.1 is the RS-232 driver TX output from PIC
PortB.2 is the RS-232 driver RX input to PIC
Ioannis
Re: serial LCD 1602 Backpack using PIC16F690 for Hitach HD44780
Re: serial LCD 1602 Backpack using PIC16F690 for Hitach HD44780
removed debug messages that are sent before spbrg set to correct value
since 1827 has more resources have increased buffer size, u may not need pacing any longer to compensate for
the 4 bit lcd interface being a bit slower
baud rate is only shown on lcd at boot , setting is stored in eeprom
Code:
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Name : 16F1827 LCD BACKPACK *
' Date : oct 2025 richard *
' Note : RING BUFFERED *
' Notes : DEFA BAUD RATE 9600 Intrc_OSC 8Mhz *
' eeprom full case is unhandled,factory reset would be advisable *
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
#CONFIG
__config _CONFIG1, _FOSC_INTOSC & _WDTE_ON & _PWRTE_OFF & _MCLRE_ON & _CP_OFF & _CPD_OFF & _BOREN_ON & _CLKOUTEN_OFF & _IESO_ON & _FCMEN_ON
__config _CONFIG2, _WRT_OFF & _PLLEN_OFF & _STVREN_ON & _BORV_19 & _LVP_OFF
#ENDCONFIG
;commands eg SEROUT2 lcd,84,[255,11] set baudrate from 9600 to 19200
'255 0/8 backlight
'255 10/11/12 baud rate 9600/19200/38400
'255 "F" factory reset
;TX PORTB.2 RX PORTB.1 BACKLIGHT PORTB.0
DEFINE OSC 8
DEFINE INTHAND myint
DEFINE WRITE_INT 1
ANSELA = 0 ' Set all pins digital
ANSELB = 0 ' Set all pins digital
' OPTION_REG.7 = 0 ' PORTA/PORTB pull-ups are enabled by individual port latch values
CLEAR
DEFINE LCD_BITS 4 'defines the number of data interface lines (4 or 8)
DEFINE LCD_DREG PORTA 'defines the port where data lines are connected to
DEFINE LCD_DBIT 0
DEFINE LCD_RSREG PORTB 'defines the port where RS line is connected to
DEFINE LCD_RSBIT 6 'defines the pin where RS line is connected to
DEFINE LCD_EREG PORTB 'defines the port where E line is connected to
DEFINE LCD_EBIT 4 'defines the pin where E line is connected
DEFINE LCD_COMMANDUS 1500 'defines the delay after LCDOUT statement
DEFINE LCD_DATAUS 50 'delay in micro seconds
RCSTA = $90 ' Enable serial port & continuous receive
TXSTA = $20 ' Enable transmit, BRGH = 0
SP1BRG = 51 ' 19200 Baud @ 8MHz, 0.16%, 51 ' 9600 Baud @ 8MHz, 0.16%, 12 ' 38400 Baud @ 8MHz, 0.16%
SP1BRGH = 0
BAUDCON.3 = 1 ' Enable 16 bit baudrate generator
buffer_size CON 64 ' Sets the size of the ring buffer
index_in VAR BYTE bank0 ' Pointer - next empty location in buffer
index_out VAR BYTE bank0 ' Pointer - location of oldest character in buffer
errflag VAR BYTE bank0 ' Error flag
UartFlag VAR errflag.0
BufferFlag VAR errflag.1
buffer VAR BYTE[buffer_size] ' Array variable for holding received characters
bufchar VAR BYTE ' Stores the character retrieved from the buffer
Bl var byte
inx var byte
Br var byte
GOTO overint ' Jump over the interrupt handler
ASM
myint
; Check for hardware overrun error
banksel RCSTA
btfsc RCSTA,OERR ; Check for usart overrun
goto usart_err ; jump to assembly error routine
; Test for buffer overrun
banksel 0
incf _index_in,W ; Increment index_in to W
subwf _index_out,W ; Subtract indexes to test for buffer overrun
btfsc STATUS,Z ; check for zero (index_in = index_out)
goto buffer_err ; jump to error routine if zero
; Increment the index_in pointer and reset it if it's outside the ring buffer
incf _index_in,F ; Increment index_in to index_in
movf _index_in,W ; Move new index_in to W
sublw _buffer_size-1; Subtract index_in from buffer_size-1
btfss STATUS, C ; If index_in => buffer_size
clrf _index_in ; Clear index_in
; Set FSR with the location of the next empty location in buffer
movlw High _buffer ;Store the High byte of buffer to FSR0H
movwf FSR0H
movlw Low _buffer ; Get the Low byte of buffer[0]
addwf _index_in,W ; Add index_in to point to next empty slot
movwf FSR0L ; Store Low byte of pointer in FSR0
; Read and store the character from the USART
banksel RCREG
movf RCREG,W ; Read the received character
movwf INDF0 ; Put the received character in FSR location
banksel PIR1
BTFSC PIR1,RCIF ;ANY MORE ?
goto myint
finished
;RST?RP
retfie ; Return from interrupt
; Error routines
buffer_err ; Jump here on buffer error
bsf _errflag,1 ; Set the buffer flag
usart_err ; Jump here on USART error
banksel _errflag
bsf _errflag,0 ; Set the USART flag
banksel RCREG
movf RCREG, W ; Trash the received character
goto finished ; Restore state and return to program
ENDASM
overint:
TRISB = % 00101010
TRISA = % 11110000
OSCCON = $70
PAUSE 500
gosub getbaud
PAUSE 5
LCDOUT $FE,1
hserout [13,"ready"]
LCDOUT "ready "
if br==51 then
hserout ["@9600"]
LCDOUT "@9600"
elseif br==25 then
hserout ["@19200"]
LCDOUT "@19200"
else
hserout ["@38400"]
LCDOUT "@38400"
endif
PAUSE 500
@ bsf LCD_RSREG ,LCD_RSBIT
GOSUB error
INTCON = $C0
PIE1.5 = 1
main:
IF errflag Then GOSUB error ' Goto error routine if needed
IF index_in = index_out Then main ' loop if nothing in buffer
GoSub getbuf ' Get a character from buffer
if bl then
if bufchar = 0 then
portB.0 = 0 ' Back Light OFF
portB.7 = 1 ' Back Light OFF
endif
if bufchar = 8 then
portB.0 = 1 ' Back Light ON
portB.7 = 0 ' Back Light OFF
endif
if bufchar = 10 then
write inx+1,51
gosub getbaud
endif
if bufchar = 11 then
write inx+1,25
gosub getbaud
endif
if bufchar = 12 then
write inx+1,12
gosub getbaud
endif
if bufchar = "F" then
gosub factory
endif
bl = 0
goto main
endif
if bufchar = 255 then
bl = 1
goto main
endif
if bufchar = 254 then
@ bcf LCD_RSREG ,LCD_RSBIT
goto main
endif
@ MOVE?BB _bufchar,R3
@ MOVE?CT 1,FLAGS ,0
@ L?CALL lcdsend
@ bsf LCD_RSREG ,LCD_RSBIT
goto main ' loop back to top
error: ' Display error message
INTCON = 0 ' Disable interrupts while in the error routine
IF errflag.1 Then ' Determine the error
hserout [" Buffer overflow",13]' Display buffer error on line-2
Else
hserout [" Uart reset",13] ' Display usart error on line_2
EndIF
errflag = 0 ' Reset the error flag ;clear any rcsta error
RCSTA.4 = 0 'CREN = 0 Disable continuous receive to clear hardware error
RCSTA.4 = 1 'CREN = 1 Enable continuous receive
INTCON = % 11000000 ' Enable interrupts
RETURN ' repeat
getbuf: ' Move the next character in buffer to bufchar
index_out = index_out + 1 ' Increment index_out pointer (0 to 31)
IF index_out => buffer_size Then index_out = 0 ' Reset pointer if outside buffer
bufchar = buffer[index_out] ' Read buffer location(index_out)
Return
getbaud:
bufchar = 0
inx = 255
read inx,Br
while Br==255
read inx,Br
if Br==255 then
if inx == 0 then
br=51
write inx,51
' hserout [13,"init@9600 " ,dec inx,",",dec Br]
else
inx = inx-1
endif
endif
wend ;note if inx=255 then eeprom full
' hserout [" index " ,dec inx,",",dec Br]
SP1BRG = Br
Return
factory:
write 0,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
write 16,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
write 32,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
write 48,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
write 64,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
write 80,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
write 96,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
write 112,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
write 128,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
write 144,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
write 160,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
write 176,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
write 192,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
write 208,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
write 224,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
write 240,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
gosub getbaud
Return
Re: serial LCD 1602 Backpack using PIC16F690 for Hitach HD44780
Great work Richard!
Works very well. Thank you.
I had to change LCD_COMMANDUS to 2000 from 1500 for best performance.
I just did not understood what all these ff's at the end of the code do.
Ioannis
Re: serial LCD 1602 Backpack using PIC16F690 for Hitach HD44780
Quote:
I had to change LCD_COMMANDUS to 2000 from 1500 for best performance
not to be unexpected, the LCD timing defines need to match the display in use. some are very slow
Code:
I just did not understood what all these ff's at the end of the code do.
not pretty I agree but its one simple way to erase the eeprom at run time, hence "factory" as in factory reset
Re: serial LCD 1602 Backpack using PIC16F690 for Hitach HD44780
one last update:
added an PGM Sw on RA3
to edit the baud rate:
turn off the LCD display, press & hold the PGM sw, turn on the LCD
line 1 will show "Press to Select" , line 2 : "Baud Rate:"
release the sw and press it again to select next value (at this point the new value is save to EEPROM memory)
when the desire value is reach, turn off the LCD and turn it on again at this point the LCD will display the baud rate on line 2
and the display is ready to receive a clear LCD command, and data from the sender.
As for different LCD module eg: 1601,1602,2004 1 line, 2 lines 4 lines etc.. the LCD commands is use to control position of the data on the screen.
as of today the 1601, 1602, 2004 have been tested successfuly.
Code:
#CONFIG
__config _HS_OSC & _WDT_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _BOD_OFF & _IESO_OFF & _FCMEN_OFF
#ENDCONFIG
DEFINE OSC 20 ' Running @ 20MHz PBP 33,217
ANSEL = 0 : ANSELH = 0 ' Set all pins digital
TRISA = 001000 : TRISB = 100000 : TRISC = 0 ' 0 = OUT, 1 = IN
PORTA = 000001 : PORTB = 0 : PORTC = 0 ' 0 = Low 1 = High
OSCCON = $78 ' $78=External Xtal $70 = Internal
BaudR var word ' Baud Rate word var
En var Portb.4 ' LCD Enable
RS var Portb.6 ' LCD Register Set
B1 var byte ' Serial IN Byte
Flag var bit ' Display Baud Rate on Power-up
I VAR BYTE : II VAR BYTE : III VAR BYTE ' use in Set1
read 0, word baudr,ii : pause 2 ' Read Baud Rate from EEPROM
if ii < 0 or ii > 7 then
baudr = 84 : ii = 3
WRITE 0, Word baudr,ii : pause 2 ' Write to EEPROM
endif
ArrayA var Byte [65]
' Array index (III) 0 5 10 15 20 25 30 35 40~55 56~65
ARRAYWRITE ArrayA,[" 1200 2400 4800 960014400192002880038400Press to Select:Baud Rate:"]
gosub LCDinit ' Initialise LCD
IF PORTA.3 = 1 THEN ' PGM Switch
GOTO Set1
else
flag = 1
gosub set2
pause 500
ENDIF
main:
serin2 Portb.5,baudr,3,main,[b1] ' Serial IN
if b1 < 253 then ' if Characters
PORTC = b1
HIGH EN : PAUSEus 1 : LOW EN
goto main
elseif b1 = 254 then ' if LCD Command
low RS
serin2 Portb.5,baudr,3,main,[b1]
PORTC = b1 ' output the data
HIGH EN : PAUSEus 1 : LOW EN
high RS ' character mode
goto main
elseif b1 = 255 then ' if Port Command
serin2 Portb.5,baudr,3,main,[b1]
if b1 = 0 then TOGGLE PORTA.0 ' Toggle Back Light OFF / ON
if b1 = 1 then TOGGLE PORTB.7 ' Toggle PORTB.7 ON / OFF
if b1 = 2 then TOGGLE PORTA.2 ' Toggle PORTA.2 ON / OFF
goto main ' loop back to top
ENDIF
LCDINIT: ' Standard LCD Module Initialisation
PORTC = 000001 : HIGH EN : PAUSEus 1 : LOW EN : pause 4 ' Clear Display
PORTC = 000010 : HIGH EN : PAUSEus 1 : LOW EN : pause 2 ' Return Home
PORTC = 111000 : HIGH EN : PAUSEus 1 : LOW EN : Pause 2 ' 8 bit, 2 line, 5x8 Characters
PORTC = 000110 : HIGH EN : PAUSEus 1 : LOW EN : Pause 2 ' Entry mode
PORTC = 001110 : HIGH EN : PAUSEus 1 : LOW EN : Pause 2 ' 001DCB Display on/off, Cursor on/off, Blink y/n
RETURN
Set1: ' Baud Rate Selection and EEPROM Save at Power ON with Switch press
PAUSE 10 ' "Press to Select:"
Low RS : PORTC = 128 : High En : PauseUS 1 : Low En : High RS : Pause 3 ' Line 1
For I = 40 To 55
PORTC = ArrayA[I]
High En : PauseUS 1 : Low En
PAUSE 2
Next I
Set2:
PAUSE 10 ' "Baud Rate:"
Low RS : PORTC = 192 : High En : PauseUS 1 : Low En : High RS : Pause 3 ' Line 2
For I = 56 To 65
PORTC = ArrayA[I]
High En : PauseUS 1 : Low En
PAUSE 2
Next I
Set3:
Low RS : PORTC = 203 : High En : PauseUS 1 : Low En : High RS : Pause 3 ' Line 2
PAUSE 2 ' Index
IF II = 0 THEN III = 0 : baudr = 813 ' 1200
IF II = 1 THEN III = 5 : baudr = 396 ' 2400
IF II = 2 THEN III = 10 : baudr = 188 ' 4800
IF II = 3 THEN III = 15 : baudr = 84 ' 9600
IF II = 4 THEN III = 20 : baudr = 49 ' 14400
IF II = 5 THEN III = 25 : baudr = 32 ' 19200
IF II = 6 THEN III = 30 : baudr = 15 ' 28800
IF II = 7 THEN III = 35 : baudr = 6 ' 38400
For I = III To (IIi + 4)
PORTC = ArrayA[I]
High En : PauseUS 1 : Low En
PAUSE 2
Next I
if flag = 1 then
flag = 0 : return
endif
WRITE 0, Word baudr,ii : pause 2 ' Write to EEPROM
II = II + 1
IF II > 7 THEN II = 0
while PORTA.3 = 1 ' Switch Press
wend
PAUSE 250
while PORTA.3 = 0 ' Switch Release
wend
pause 250
GOTO set3
Re: serial LCD 1602 Backpack using PIC16F690 for Hitach HD44780
Newhaven Display (newhavendisplay.com) offers a collection of 10 different character LCDs in 2x16, 2x20 and 4x20 formats that are exclusively serial inputs -- I2C, SPI and Async TTL -- and reasonably priced at $15 to $20 U.S. I have a couple of the 2x20's, and they work nicely in all 3 interface modes. Nevertheless, this is a very interesting project as I (like everyone else) have a drawer full of parallel interface HD44780 type LCDs that will be put to better use with this serial interface. Many thanks, and I'll provide you feedback if I have anything useful to contribute.