Receive string '?f' and clear the LCD in PIC16F628

project168's Avatar, Join Date: Mar 2011
Newbie Member
How do I write the instruction where if I receive a string of '?f', it will clear my LCD screen? I am using a PIC16F628.

This is the coding I am using and I want to implement it inside:

Code:
;Serial routines - display received bytes on LCD

        cblock    0x20            ;start of general purpose registers
            count            ;used in looping routines
            count1            ;used in delay routine
            counta            ;used in delay routine
            countb            ;used in delay routine
            templcd            ;temp store for 4 bit mode
            templcd2
            lcdtmp
            Xmit_Byte            ;holds byte to xmit
                    Rcv_Byte            ;holds received byte 
                    Bit_Cntr            ;bit counter for RS232
                    Delay_Count            ;delay loop counter
        endc

LCD_PORT    Equ    PORTA
LCD_TRIS    Equ    TRISA
LCD_RS        Equ    0x04            ;LCD handshake lines
LCD_RW        Equ    0x06
LCD_E        Equ    0x07
SER_PORT    Equ    PORTB
SER_TRIS    Equ    TRISB
SER_IN        Equ    0x07
SER_OUT        Equ    0x06



        org    0x0000

Start        movlw    0x07
        movwf    CMCON            ;turn comparators off (make it like a 16F84)

Initialise    clrf    count
        clrf    PORTA
        clrf    PORTB    
        call    SER_INIT        ;initialise serial port
        call    LCD_Init
Loop        call    Rcv_RS232
        call    LCD_Char
        goto    Loop


;Serial routines

SER_INIT
            BSF     STATUS, RP0           ;select bank 1
            BCF     SER_TRIS, SER_OUT     ;set B6 as an output
            BSF     SER_TRIS, SER_IN      ;set B7 as an input
            BCF     STATUS, RP0           ;select bank 0
            BSF     SER_PORT, SER_OUT     ;set SER_OUT high
            RETURN

XMIT_RS232  MOVWF   Xmit_Byte             ;move W to Xmit_Byte
            MOVLW   0x08                  ;set 8 bits out
            MOVWF   Bit_Cntr
            BCF     SER_PORT, SER_OUT
            CALL    Bit_Delay
Ser_Loop    RRF     Xmit_Byte , f         ;send one bit
            BTFSS   STATUS    , C
            BCF     SER_PORT, SER_OUT
            BTFSC   STATUS    , C
            BSF     SER_PORT, SER_OUT
            CALL    Bit_Delay
            DECFSZ  Bit_Cntr  , f         ;test if all done
            GOTO    Ser_Loop
            BSF     SER_PORT, SER_OUT
            CALL    Bit_Delay
            RETURN

Rcv_RS232   BTFSC   SER_PORT, SER_IN      ;wait for start bit
            GOTO    Rcv_RS232
            CALL    Start_Delay              ;do half bit time delay
            BTFSC   SER_PORT, SER_IN      ;check still in start bit
            GOTO    Rcv_RS232
            MOVLW   0x08                  ;set up to read 8 bits
            MOVWF   Bit_Cntr
            CLRF    Rcv_Byte
Next_RcvBit CALL    Bit_Delay
            BTFSS   SER_PORT, SER_IN
            BCF     STATUS    , C
            BTFSC   SER_PORT, SER_IN
            BSF     STATUS    , C
            RRF     Rcv_Byte  , f
            DECFSZ  Bit_Cntr  , f         ;test if all done
            GOTO    Next_RcvBit
            CALL    Bit_Delay
            MOVF    Rcv_Byte, W
            RETURN

Start_Delay MOVLW   0x0C
            MOVWF   Delay_Count
Start_Wait  NOP
            DECFSZ  Delay_Count , f
            GOTO    Start_Wait
            RETURN

Bit_Delay   MOVLW   0x18
            MOVWF   Delay_Count
Bit_Wait    NOP
            DECFSZ  Delay_Count , f
            GOTO    Bit_Wait
            RETURN




;LCD routines

;Initialise LCD
LCD_Init    call     LCD_Busy        ;wait for LCD to settle

        movlw    0x20            ;Set 4 bit mode
        call    LCD_Cmd

        movlw    0x28            ;Set display shift
        call    LCD_Cmd

        movlw    0x06            ;Set display character mode
        call    LCD_Cmd

        movlw    0x0c            ;Set display on/off and cursor command
        call    LCD_Cmd            ;Set cursor off

        call    LCD_Clr            ;clear display

        retlw    0x00

; command set routine
LCD_Cmd        movwf    templcd
        swapf    templcd,    w    ;send upper nibble
        andlw    0x0f            ;clear upper 4 bits of W
        movwf    LCD_PORT
        bcf    LCD_PORT, LCD_RS    ;RS line to 1
        call    Pulse_e            ;Pulse the E line high

        movf    templcd,    w    ;send lower nibble
        andlw    0x0f            ;clear upper 4 bits of W
        movwf    LCD_PORT
        bcf    LCD_PORT, LCD_RS    ;RS line to 1
        call    Pulse_e            ;Pulse the E line high
        call     LCD_Busy
        retlw    0x00

LCD_CharD    addlw    0x30            ;add 0x30 to convert to ASCII
LCD_Char    movwf    templcd
        swapf    templcd,    w    ;send upper nibble
        andlw    0x0f            ;clear upper 4 bits of W
        movwf    LCD_PORT
        bsf    LCD_PORT, LCD_RS    ;RS line to 1
        call    Pulse_e            ;Pulse the E line high

        movf    templcd,    w    ;send lower nibble
        andlw    0x0f            ;clear upper 4 bits of W
        movwf    LCD_PORT
        bsf    LCD_PORT, LCD_RS    ;RS line to 1
        call    Pulse_e            ;Pulse the E line high
        call     LCD_Busy
        retlw    0x00

LCD_Line1    movlw    0x80            ;move to 1st row, first column
        call    LCD_Cmd
        retlw    0x00

LCD_Line2    movlw    0xc0            ;move to 2nd row, first column
        call    LCD_Cmd
        retlw    0x00

LCD_Line1W    addlw    0x80            ;move to 1st row, column W
        call    LCD_Cmd
        retlw    0x00

LCD_Line2W    addlw    0xc0            ;move to 2nd row, column W
        call    LCD_Cmd
        retlw    0x00

LCD_CurOn    movlw    0x0d            ;Set display on/off and cursor command
        call    LCD_Cmd
        retlw    0x00

LCD_CurOff    movlw    0x0c            ;Set display on/off and cursor command
        call    LCD_Cmd
        retlw    0x00

LCD_Clr        movlw    0x01            ;Clear display
        call    LCD_Cmd
        retlw    0x00

Pulse_e        bsf    LCD_PORT, LCD_E
        nop
        bcf    LCD_PORT, LCD_E
        retlw    0x00

LCD_Busy
        bsf    STATUS,    RP0        ;set bank 1
        movlw    0x0f            ;set Port for input
        movwf    LCD_TRIS
        bcf    STATUS,    RP0        ;set bank 0
        bcf    LCD_PORT, LCD_RS    ;set LCD for command mode
        bsf    LCD_PORT, LCD_RW    ;setup to read busy flag
        bsf    LCD_PORT, LCD_E
        swapf    LCD_PORT, w        ;read upper nibble (busy flag)
        bcf    LCD_PORT, LCD_E        
        movwf    templcd2 
        bsf    LCD_PORT, LCD_E        ;dummy read of lower nibble
        bcf    LCD_PORT, LCD_E
        btfsc    templcd2, 7        ;check busy flag, high = busy
        goto    LCD_Busy        ;if busy check again
        bcf    LCD_PORT, LCD_RW
        bsf    STATUS,    RP0        ;set bank 1
        movlw    0x00            ;set Port for output
        movwf    LCD_TRIS
        bcf    STATUS,    RP0        ;set bank 0
        return

;end of LCD routines


;Delay routines

Long_Delay
        call    Delay255
        call    Delay255
        call    Delay255
        call    Delay255
        return

Delay255    movlw    0xff        ;delay 255 mS
        goto    d0
Delay100    movlw    d'100'        ;delay 100mS
        goto    d0
Delay50        movlw    d'50'        ;delay 50mS
        goto    d0
Delay20        movlw    d'20'        ;delay 20mS
        goto    d0
Delay10        movlw    d'10'        ;delay 10mS
        goto    d0
Delay1        movlw    d'1'        ;delay 1mS
        goto    d0
Delay5        movlw    0x05        ;delay 5.000 ms (4 MHz clock)
d0        movwf    count1
d1        movlw    0xC7
        movwf    counta
        movlw    0x01
        movwf    countb
Delay_0        decfsz    counta, f
        goto    $+2
        decfsz    countb, f
        goto    Delay_0

        decfsz    count1    ,f
        goto    d1
        retlw    0x00

;end of Delay routines


        end
xpi0t0s's Avatar, Join Date: Aug 2004
Mentor
You'll find more PIC experts at http://www.electro-tech-online.com/microcontrollers/
project168's Avatar, Join Date: Mar 2011
Newbie Member
I posted there too but I am not getting much of a help
xpi0t0s's Avatar, Join Date: Aug 2004
Mentor
It's not clear why you can't figure this out for yourself. If you've written the rest of the code then this should be trivial for a programmer capable of writing that lot.

Currently you just display everything received:
Code:
Loop		call	Rcv_RS232
		call	LCD_Char
		goto	Loop
Between those two calls you need to check the bytes received and act accordingly. Does ? indicate a command sequence to follow? What if you want to display a question mark? Would the sender send ??, akin to C's \\ for a backslash?

If ? indicates a command sequence, you could set a flag that indicates that a command sequence is now expected, and not display that on the screen. The next character accepted would then be a command. Pseudocode:

Code:
CmdExpected=0
forever loop
{
  call Rcv_RS232
  if CmdExpected
  {
    // Rcv_Byte contains the command byte
    if (Rcv_Byte=='f') call LCD_Clr // ?f clears the screen
    else if (Rcv_Byte=='?') call LCD_Char // ?? displays a ?
    // else if (Rcv_Byte==... etc for other commands.

    // Assuming all commands are single byte
    CmdExpected=0
  }
  else if (Rcv_Byte=='?')
  {
    CmdExpected=1
  }
  else
  {
    call LCD_Char
  }
}
shabbir like this