;------------------------------------------------------------------------------- ; FILE: Serial LCD character Display ; AUTH: Ed's Projects ; DATE: 16/07/2016 ; DESC: Asynchronous Serial to 4-bit LCD ; Protocol ; 254 will initiate command ; 160 will initiate splash screen write sequence, 80 characters or end with 160 ; All other data will write a character ; Three dip switches will set the baud rate ;RA4;;;RA3;;;RA2;;;baud rate ;;0;;;;;0;;;;;0;;;;1200 ;;0;;;;;0;;;;;1;;;;2400 ;;0;;;;;1;;;;;0;;;;4800 ;;0;;;;;1;;;;;1;;;;9600 ;;1;;;;;0;;;;;0;;;;19200 ;;1;;;;;0;;;;;1;;;;38400 ;;1;;;;;1;;;;;0;;;;57600 ;;1;;;;;1;;;;;1;;;;76800 ; A dip switch on RA5 will turn 1 second splash screen on or off ; splash screen is saved in EEPROM and never lost ; The commands are the same as those in the data sheet ;------------------------------------------------------------------------------- LIST P=16F628A, R=DEC ; All numbers Decimal format unless otherwise stated. include ; Define configurations, registers, etc. __config _CP_OFF & _CPD_OFF & _LVP_OFF & _BOREN_ON & _MCLRE_OFF & _PWRTE_ON & _WDTE_OFF & _HS_OSC ;------------------------------------------------------------------------------- ;----------------------------- Port Definitions ------------------------------ ;------------------------------------------------------------------------------- ; PortA - Output - RA0 - Pin 17 - RS Register select for LCD ; PortA - Output - RA1 - Pin 18 - E Enable for LCD ; PortB - Output - RB4 - Pin 10 - DB4 Dataline for LCD ; PortB - Output - RB5 - Pin 11 - DB5 Dataline for LCD ; PortB - Output - RB6 - Pin 12 - DB6 Dataline for LCD ; PortB - Output - RB7 - Pin 13 - DB7 Dataline for LCD ; PortB - Input - RB1 - Pin 7 - Serial Data In ; PortA - Input - RA2 - Pin 1 - Baud Control ; PortA - Input - RA3 - Pin 2 - Baud Control ; PortA - Input - RA4 - Pin 3 - Baud Control ; PortA - Input - RA5 - Pin 4 - Splash Screen ;------------------------------------------------------------------------------- ;-------------------------------- Variables ---------------------------------- ;------------------------------------------------------------------------------- cblock h'20' micro200f micro50f ms2delayf ms2delayg offset ; PCL shift offset dly0 ; 2ms number of loops Tmp ; LCD character write temp file w_save ; Save working register on interrupt status_save ; Save status register on interrupt sertemp ; Recieved serial temp file baudctrl ; Baud rate control variable cmdcall ; Command call Indicator chrcall ; Character call Indicator msgcall ; Message call Indicator msgtemp ; For writing and reading message ee_data ; EEPROM data ee_adr ; EEPROM address fsrtemp ; fsr temp file endc ;------------------------------------------------------------------------------- ;----------------------------- Define Symbols -------------------------------- ;------------------------------------------------------------------------------- #define LCD4 PORTB, 4 #define LCD5 PORTB, 5 #define LCD6 PORTB, 6 #define LCD7 PORTB, 7 #define LCDRS PORTA, 0 #define LCDE PORTA, 1 ;------------------------------------------------------------------------------- ;------------------------------- Program Code -------------------------------- ;------------------------------------------------------------------------------- ORG 0 goto Init ;------------------------------------------------------------------------------- ;---------------------------- Interrupt Address ------------------------------ ;------------------------------------------------------------------------------- ORG 04 goto Interrupt ;------------------------------------------------------------------------------- ;-------------------------- Initialisation of Ports -------------------------- ;------------------------------------------------------------------------------- Init bsf STATUS,RP0 ; Set RP0 to 1 bcf STATUS,RP1 ; Set RP1 to 0 ; Bank 1 Selected bsf INTCON, PEIE ; Turn on peripheral Interrupts clrf VRCON ; Set Vref to off clrf TRISB ; Set all PortB as Output movlw b'00111100' ; Load 00111100 to working register movwf TRISA ; bcf STATUS,RP0 ; Set RP0 to 0 ; Bank 0 Selected movlw d'7' ; Load working register with "7" movwf CMCON ; Turn off comparators clrf PORTA clrf PORTB clrf micro200f clrf ms2delayf clrf ms2delayg clrf Tmp clrf offset clrf dly0 clrf sertemp clrf baudctrl clrf cmdcall clrf chrcall clrf msgcall ;------------------------------------------------------------------------------- ;------------------------------- Set Baud Rate ------------------------------- ;------------------------------------------------------------------------------- btfsc PORTA, 2 bsf baudctrl, 0 btfsc PORTA, 3 bsf baudctrl, 1 btfsc PORTA, 4 bsf baudctrl, 2 movf baudctrl, w bsf STATUS, RP0 ; Bank 1 selected bsf TXSTA, BRGH ; Set high baud rate call baudlookup goto serialinit baudlookup addwf PCL, f goto lwbd1200 goto lwbd2400 goto lwbd4800 retlw d'129' retlw d'64' retlw d'32' retlw d'21' retlw d'15' lwbd1200 bcf TXSTA, BRGH ; Set low baud rate retlw d'255' lwbd2400 bcf TXSTA, BRGH ; Set low baud rate retlw d'129' lwbd4800 bcf TXSTA, BRGH ; Set low baud rate retlw d'32' ;------------------------------------------------------------------------------- ;----------------- Asynchronous Serial Receive Initialisation ----------------- ;------------------------------------------------------------------------------- serialinit bsf TRISB, 1 ; Both serial input and output must bsf TRISB, 2 ; be set as inputs. movwf SPBRG ; Set baud rate bcf TXSTA, SYNC ; Set to asynchronous mode bcf STATUS, RP0 ; Set RP0 to 0 ; Bank 0 Selected bsf RCSTA, SPEN ; Enable Serial Port bsf STATUS, RP0 ; Set RP0 to 1 ; Bank 1 Selected bsf PIE1, RCIE ; Turn on Serial Receive Interrupt bcf STATUS, RP0 ; Set RP0 to 0 ; Bank 0 Selected bsf RCSTA, CREN ; Turns on receive movf RCREG, w movf RCREG, w movf RCREG, w ;------------------------------------------------------------------------------- ;--------------------------- LCD Initialisation ------------------------------ ;------------------------------------------------------------------------------- movlw d'32' call delay bsf LCD5 bsf LCD4 call Enable call ms2delay call ms2delay call Enable call micro200 call Enable bcf LCD4 call Enable ;Function Set movlw b'00101000' ;4-bit mode, 2 lines, 5x7 matrix call SendLCD ;Display on / off movlw b'00001100' ;Display on, Cursor off, Blink off call SendLCD ;Entry Mode Set movlw b'00000110' ;Increment, Display shifted call SendLCD ;Cursor or display shift movlw b'00010000' ;Display Shift call SendLCD ;Clear Screen movlw b'00000001' ; Clear screen call SendLCD call ms2delay call ms2delay bsf LCDRS ; Set data mode goto Start ;------------------------------------------------------------------------------- ;----------------------------- Send Data to LCD ------------------------------ ;------------------------------------------------------------------------------- SendLCD ; Send data in two 4-bit nibbles movwf Tmp bcf LCD7 bcf LCD6 bcf LCD5 bcf LCD4 btfsc Tmp, 7 bsf LCD7 btfsc Tmp, 6 bsf LCD6 btfsc Tmp, 5 bsf LCD5 btfsc Tmp, 4 bsf LCD4 call Enable bcf LCD7 bcf LCD6 bcf LCD5 bcf LCD4 btfsc Tmp, 3 bsf LCD7 btfsc Tmp, 2 bsf LCD6 btfsc Tmp, 1 bsf LCD5 btfsc Tmp, 0 bsf LCD4 call Enable return ;------------------------------------------------------------------------------- ;--------------------------------- Enable ------------------------------------ ;------------------------------------------------------------------------------- Enable bsf LCDE nop nop nop nop bcf LCDE call micro50 return ;------------------------------------------------------------------------------- ;--------------------------------- LCD Clear --------------------------------- ;------------------------------------------------------------------------------- LCDClr bcf LCDRS movlw b'00000001' call SendLCD bsf LCDRS call ms2delay return ;------------------------------------------------------------------------------- ;---------------------------- Loops 2ms Delay -------------------------------- ;------------------------------------------------------------------------------- delay movwf dly0 delayloop call ms2delay decfsz dly0, f goto delayloop return ;------------------------------------------------------------------------------- ;------------------------------- 2ms Delay ----------------------------------- ;------------------------------------------------------------------------------- ms2delay movlw d'8' movwf ms2delayg ms2delayc movlw d'250' movwf ms2delayf ms2delaya nop ;0.2us nop ;0.2us decfsz ms2delayf,f ;0.2us goto ms2delaya ;0.4us ;total 250us ms2delayb decfsz ms2delayg,f ;0.2us goto ms2delayc ;0.4us return ;return from call ;------------------------------------------------------------------------------- ;------------------------------- 200us Delay --------------------------------- ;------------------------------------------------------------------------------- micro200 movlw d'200' movwf micro200f micro200a nop ;0.2us nop ;0.2us decfsz micro200f,f ;0.2us goto micro200a ;0.4us return ;return from call ;------------------------------------------------------------------------------- ;------------------------------- 50us Delay --------------------------------- ;------------------------------------------------------------------------------- micro50 movlw d'50' movwf micro50f micro50a nop ;0.2us nop ;0.2us decfsz micro50f,f ;0.2us goto micro50a ;0.4us return ;return from call ;------------------------------------------------------------------------------- ;------------------------------ EEPROM Write --------------------------------- ;------------------------------------------------------------------------------- Ewrite movf ee_adr, w ; Load working register with ee_adr bsf STATUS, RP0 ; Bank 1 Selected movwf EEADR ; Set location to write to EEPROM bcf STATUS, RP0 ; Bank 0 Selected movf ee_data, w ; Load working register with ee_data bsf STATUS, RP0 ; Bank 1 Selected movwf EEDATA ; Data to be written to address bsf EECON1, WREN ; Enables EEPROM write ; The next four lines must be there to allow the data to be written movlw d'85' ; Load working register with decimal 85 movwf EECON2 ; Load working register to EECON2 movlw d'170' ; Load working register with decimal 170 movwf EECON2 ; Load working register to EECON2 bsf EECON1, WR ; Send data btfsc EECON1, WR goto $-1 ; If 1, check again, 0 indicates data written bcf EECON1, WREN ; Turn off EEPROM write bcf STATUS, RP0 ; Select bank 0 return ; return from where left off ;------------------------------------------------------------------------------- ;------------------------------ EEPROM Read ---------------------------------- ;------------------------------------------------------------------------------- Eread movf ee_adr, w ; Load working register with ee_adr bsf STATUS, RP0 ; Bank 1 Selected movwf EEADR ; Set location to read EEPROM from bsf EECON1, RD ; Enables EEPROM read btfsc EECON1, RD goto $-1 movf EEDATA, w ; Load working resgister with EEPROM data bcf STATUS, RP0 ; Bank 0 Selected movwf ee_data return ; return from where left off ;------------------------------------------------------------------------------- ;---------------------------- Interrupt Program ------------------------------ ;------------------------------------------------------------------------------- Interrupt movwf w_save movf STATUS, w clrf STATUS movwf status_save movf RCREG, w movwf sertemp xorlw d'254' btfsc STATUS, Z goto Intcmd movf sertemp, w xorlw d'160' btfsc STATUS, Z bsf msgcall, 0 ; States message to be called bsf chrcall, 0 ; States character called Intcmddone movf status_save, w movwf STATUS swapf w_save, f swapf w_save, w retfie Intcmd bsf cmdcall, 0 ; States command called goto Intcmddone ;------------------------------------------------------------------------------- ;------------------------- Main part of program ------------------------------ ;------------------------------------------------------------------------------- Start btfsc PORTA, 5 ; Splash screen turn on / off goto Starta clrf ee_adr movlw h'A0' movwf fsrtemp Startb call Eread movf fsrtemp, w movwf FSR movf ee_data, w movwf INDF incf ee_adr, f incf fsrtemp, f movf fsrtemp, w xorlw d'240' btfss STATUS, Z goto Startb movlw h'A0' movwf fsrtemp Startc movf fsrtemp, w movwf FSR movf INDF, w call SendLCD incf fsrtemp, f movf fsrtemp, w xorlw d'240' btfss STATUS, Z goto Startc movlw d'250' call delay movlw d'250' call delay Starta call LCDClr movf RCREG, w movf RCREG, w movf RCREG, w bsf INTCON, GIE ; Turn on global interrupts Cats btfsc cmdcall, 0 goto cmdmode ; Goto command mode btfsc msgcall, 0 goto msgmode ; Goto write message mode btfss chrcall, 0 ; Go send data goto Cats movf sertemp, w call SendLCD clrf chrcall goto Cats cmdmode btfss chrcall, 0 goto cmdmode bcf LCDRS ; Set LCD command mode movf sertemp, w call SendLCD bsf LCDRS ; Set LCD character mode clrf chrcall clrf cmdcall clrf msgcall goto Cats msgmode clrf msgcall msgwrite movlw h'A0' movwf msgtemp msgwritea btfsc msgcall, 0 goto finmes btfss chrcall, 0 goto msgwritea clrf chrcall movf msgtemp, w movwf FSR movf sertemp, w movwf INDF incf msgtemp, f movf msgtemp, w xorlw d'240' btfss STATUS, Z goto msgwritea finmes bcf INTCON, GIE clrf msgcall clrf chrcall clrf ee_adr movlw h'A0' movwf msgtemp finmesa movf msgtemp, w movwf FSR movf INDF, w movwf ee_data call Ewrite incf ee_adr, f incf msgtemp, f movf msgtemp, w xorlw d'240' btfss STATUS, Z goto finmesa bsf INTCON, GIE goto Cats end