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
Bookmarks