            ;****************************************
            ;*     EXAMPLE PROGRAM FOR  CP-2051     *
            ;* Large Serial Display By ETT CO.,LTD. *
            ;* Used IC 74HC595 (SERIAL TO PARALLEL) *
            ;****************************************

            SERIAL      EQU     P1.0        ; Serial Input pin
            SHIFT       EQU     P1.1        ; Shift Clock pin
            LATCH1      EQU     P1.2        ; Latch Clock pin SO0..7
            LATCH2      EQU     P1.3        ; Latch Clock pin SO8..15
            RS_LCD      EQU     P3.4        ; RS LCD (Pin T0)
            CS_LCD      EQU     P3.5        ; E  LCD (PIN T1)
            DSP_BUFF    EQU     80H         ; Display buffer 16 byte
            SER_BUFF    EQU     90H         ; Serial buffer

            ORG     0000H

MAIN_OUT:   SETB    SERIAL
            SETB    SHIFT
            SETB    LATCH1
            SETB    LATCH2
            MOV     A,#0            ; Clear data
            LCALL   SER_OUT
            CLR     LATCH1          ; Latch SO0..SO7
            CLR     LATCH2          ; Latch SO8..SO15
            SETB    LATCH1
            SETB    LATCH2
            ;
MAIN_LCD:   LCALL   INIT_LCD        ; Initial LCD
            LCALL   INIT_SR         ; Initial Serial Port
            MOV     DPTR,#TAB1
            LCALL   TX_BOX
            MOV     DPTR,#TAB2
            LCALL   TX_BOX
            MOV     DPTR,#TAB3
            LCALL   TX_BOX
            MOV     DPTR,#TAB4
            LCALL   TX_BOX
            MOV     DPTR,#TAB5
            LCALL   TX_BOX
            MOV     DPTR,#TAB6
            LCALL   TX_BOX
            MOV     DPTR,#TAB7
            LCALL   TX_BOX
            MOV     DPTR,#TAB8
            LCALL   TX_BOX
            MOV     DPTR,#TAB9
            LCALL   TX_BOX
            MOV     DPTR,#TAB10
            LCALL   TX_BOX
            MOV     DPTR,#TAB11
            LCALL   TX_BOX
            MOV     DPTR,#TAB12
            LCALL   TX_BOX
            MOV     DPTR,#TAB13
            LCALL   TX_BOX
            MOV     DPTR,#TAB14
            LCALL   TX_BOX
            ;
            MOV     R0,#SER_BUFF
            MOV     R1,#110
RECEIVE:    LCALL   RX_2ASCII
            MOV     @R0,A
            INC     R0
            DJNZ    R1,RECEIVE
            ;
NEW_LCD:    MOV     R3,#0           ; Pointer show
LOOP_LCD:   MOV     DPTR,#SER_BUFF
            LCALL   DSP_LEFT        ; left display
            LCALL   WR_DSP          ; display data to LCD
            INC     R3              ; Shift pointer
            MOV     A,R3
            CJNE    A,#110,LOOP_LCD
            SJMP    NEW_LCD


LOOP_OUT:   MOV     R0,#00H         ; Movlight data
            MOV     R3,#10          ; Counter loop1
LOOP1:      MOV     A,R0
            MOV     DPTR,#TAB_DSP
            MOVC    A,@A+DPTR
            LCALL   SER_OUT
            CLR     LATCH1          ; Latch SO0..SO7
            SETB    LATCH1
            LCALL   DELAY
            INC     R0
            DJNZ    R3,LOOP1
            ;
            MOV     R0,#00H         ; Movlight data
            MOV     R3,#10          ; Counter loop2
LOOP2:      MOV     A,R0
            MOV     DPTR,#TAB_DSP
            MOVC    A,@A+DPTR
            LCALL   SER_OUT
            CLR     LATCH2          ; Latch SO8..SO15
            SETB    LATCH2
            LCALL   DELAY
            INC     R0
            DJNZ    R3,LOOP2
            ;
            MOV     R0,#00H         ; Movlight data
            MOV     R3,#10          ; Counter loop3
LOOP3:      MOV     A,R0
            MOV     DPTR,#TAB_DSP
            MOVC    A,@A+DPTR
            LCALL   SER_OUT
            CLR     LATCH1          ; Latch SO0..SO7
            CLR     LATCH2          ; Latch SO8..SO15
            SETB    LATCH1
            SETB    LATCH2
            LCALL   DELAY
            INC     R0
            DJNZ    R3,LOOP3
            SJMP    LOOP_OUT


            ;************************
            ;*  Serial data output  *
            ;*  Input  = ACC        *
            ;*  Output = Serial pin *
            ;*  Reg.   = ACC,R2     *
            ;************************
            ;
SER_OUT:    MOV     R2,#8           ; Counter data out
            CLR     CY
SHF_OUT1:   RLC     A               ; Shift Out data LSB..MSB
            MOV     SERIAL,C
            CLR     SHIFT           ; Shift Clock
            SETB    SHIFT
            DJNZ    R2,SHF_OUT1
            RET

TAB_DSP:    DB      00H,01H,02H,04H,08H
            DB      10H,20H,40H,80H,00H

            ;****************************************
            ;*     Example Program For  CP-2051     *
            ;*          4bit LCD Interface          *
            ;****************************************
            ;
            ;*******************************
            ;* Fill data to Display buffer *
            ;* for show display Left style *
            ;*******************************
            ;
DSP_LEFT:   MOV     R2,#16          ; counter display buffer
            MOV     A,R3
            MOV     R0,A            ; pointer data in buffer
            MOV     R1,#DSP_BUFF
            ;MOV     DPTR,#TAB_LCD
DSP_LFT1:   MOV     A,R0
            MOVC    A,@A+DPTR       ; get data
            MOV     @R1,A           ; Fill data to buffer
            INC     R0
            INC     R1
            DJNZ    R2,DSP_LFT1
            RET

            ;*********************
            ;* Write data to LCD *
            ;* Reg. : R0,R2,ACC  *
            ;*********************
            ;
WR_DSP:     MOV     R0,#DSP_BUFF    ; display buffer
            MOV     A,#00H          ; goto line 1
            LCALL   GOTO_LCD
            MOV     R2,#8
WR_DSP1:    MOV     A,@R0
            LCALL   WR_LCD
            INC     R0
            DJNZ    R2,WR_DSP1
            ;
            MOV     R2,#8
            MOV     A,#40H          ; goto line 2
            LCALL   GOTO_LCD
WR_DSP2:    MOV     A,@R0
            LCALL   WR_LCD
            INC     R0
            DJNZ    R2,WR_DSP2
            LCALL   DELAY
            RET

TAB_LCD:    DB      '                '
            DB      ' Example Program for LCD 4bit Interface with CP-2051'
            DB      ' By ETT CO.,LTD. 1108/32 Sukhumvit Rd. Phrakanong'
            DB      ' Bangkok 10110  Tel. 3917215-6 7121120-1 7121123'
            DB      ' Fax. 3917216  CPU AT89C2051 is Micro Controller'
            DB      ' Compatible with MCS-51 family Thank You !!'

            ;**************************
            ;*   Write ASCII to LCD   *
            ;* Input  : ACC  (ASCII)  *
            ;* Output : Data bus LCD  *
            ;**************************
            ;
WR_LCD:     SETB    RS_LCD          ; Write Data select
            MOV     B,A
            ANL     A,#0F0H
            MOV     P1,A            ; High byte
            LCALL   EN_LCD
            MOV     A,B             ; Low byte
            SWAP    A
            ANL     A,#0F0H
            MOV     P1,A
            LCALL   EN_LCD
            RET

            ;**************************
            ;* Write Instruction LCD  *
            ;* Input  : ACC (Command) *
            ;* Output : Data bus LCD  *
            ;**************************
            ;
WR_INS:     CLR     RS_LCD          ; Instruction select
            MOV     B,A
            ANL     A,#0F0H
            MOV     P1,A            ; High byte
            LCALL   EN_LCD
            MOV     A,B             ; Low byte
            SWAP    A
            ANL     A,#0F0H
            MOV     P1,A
            LCALL   EN_LCD
            RET

            ;************************
            ;* Goto position of LCD *
            ;* Input : ACC (addr.)  *
            ;************************
            ;
GOTO_LCD:   SETB    ACC.7
            LCALL   WR_INS
            RET

            ;**********************
            ;*   Mov LCD cursor   *
            ;* to Left 1 position *
            ;**********************
            ;
SHF_LFT:    MOV     A,#10H
            LCALL   WR_INS
            RET

            ;***********************
            ;*    Mov LCD cursor   *
            ;* to Right 1 position *
            ;***********************
            ;
SHF_RGT:    MOV     A,#14H
            LCALL   WR_INS
            RET

            ;*******************
            ;*   Initial LCD   *
            ;* 4-Bit Interface *
            ;*******************
            ;
INIT_LCD:   CLR     RS_LCD
            MOV     A,#33H          ; Set DL=1 3-time
            LCALL   WR_INS
            MOV     A,#32H          ; Clear DL=0 1-time
            LCALL   WR_INS
            MOV     A,#28H          ; Function set
            LCALL   WR_INS          ; DL=0 4Bit,N=1 2Line,F=0 5X7
            MOV     A,#0CH          ; Display on/off Control
            LCALL   WR_INS          ; Entry display,cursor off,cursor not blink
            MOV     A,#06H          ; Entry mode set
            LCALL   WR_INS          ; I/D=1 Increment,S=0 cursor shift
            MOV     A,#01H          ; Clear display
            LCALL   WR_INS          ; clear display,set DD RAM address=0
            RET

            ;**********************
            ;*  Enable Pin E LCD  *
            ;* Active Chip select *
            ;**********************
            ;
EN_LCD:     CLR     CS_LCD          ; Enable LCD
            LCALL   BUSY            ; Busy delay time
            SETB    CS_LCD          ; Disable LCD
            RET

            ;***********************
            ;* Delay time for Busy *
            ;*    Wait LCD Ready   *
            ;***********************
            ;
BUSY:       MOV     R7,#0FFH
            DJNZ    R7,$
            RET

            ;**************
            ;* Delay Time *
            ;**************
            ;
DELAY:      MOV     R5,#2
DEL1:       MOV     R6,#0FFH
DEL2:       MOV     R7,#0FFH
            DJNZ    R7,$
            DJNZ    R6,DEL2
            DJNZ    R5,DEL1
            RET

            ;****************************************
            ;*     Example Program For  CP-2051     *
            ;*         Serial port Interface        *
            ;****************************************

INIT_SR:    MOV    A,#0FDH                ; Set baud rate 9600
            MOV    TH1,A
            MOV    TL1,A
            MOV    TMOD,#00100000B        ; Timer1 Mode 1
            CLR    ES                     ; Disable serial interupt
            CLR    ET1                    ; Disable timer1 interupt
            SETB   TR1                    ; Set timer1 control
            MOV    SCON,#01010000B        ; Serial mode 1
            RET
            ;


TAB1:       DB     'Soft Ware  :  Demo Serial port Transmitter'
            DB     0DH,0AH
TAB2:       DB     'Example    :  abcdefghijklmnopqrstuvwxyz'
            DB     0DH,0AH
TAB3:       DB     '           :  ABCDEFGHIJKLMNOPQRSTUVWXYZ'
            DB     0DH,0AH
TAB4:       DB     '           :  !@#$%^&*()_+|{}<>?'
            DB     0DH,0AH
TAB5:       DB     '           :  1234567890-=\[],./'
            DB     0DH,0AH
TAB6:       DB     'Hard Ware  :  CP-2051 V1.0'
            DB     0DH,0AH
TAB7:       DB     'Product of :  ETT CO.,LTD.'
            DB     0DH,0AH
TAB8:       DB     'Address    :  1108/32 Sukhumvit Rd.'
            DB     0DH,0AH
TAB9:       DB     '           :  Phrakanong Bangkok 10110'
            DB     0DH,0AH
TAB10:      DB     'Tel.       :  391 7215-6'
            DB     0DH,0AH
TAB11:      DB     '           :  712 1120-1'
            DB     0DH,0AH
TAB12:      DB     '           :  712 1123'
            DB     0DH,0AH
TAB13:      DB     'Fax.       :  3917216'
            DB     0DH,0AH
TAB14:      DB     'Ready to Receive data for Display on LCD Now!!'
            DB     0DH,0AH

            ;****************************
            ;*    Send data 1 Byte      *
            ;* Input    : ACC           *
            ;* Output   : Serial port   *
            ;****************************
            ;
TX_BYTE:    PUSH   IE
            CLR    ES
            CLR    TI
            MOV    SBUF,A
            JNB    TI,$
            CLR    TI
            POP    IE
            RET

            ;*****************************************
            ;*  Transmit ASCII Until Carrier Return  *
            ;*  Input  : DPTR (ASCII Code Table)     *
            ;*  Output : ASCII Code to Serial Port   *
            ;*         : Stop If Line Feed (0AH)     *
            ;*****************************************
            ;
TX_BOX:     MOV     R0,#0       ; Get ASCII
TX_BOX1:    MOV     A,R0
            MOVC    A,@A+DPTR
            CJNE    A,#0AH,TX_BOX2
            SJMP    TX_BOX3
TX_BOX2:    LCALL   TX_BYTE
            INC     R0
            SJMP    TX_BOX1
TX_BOX3:    LCALL   TX_BYTE
            RET

            ;***********************************
            ;* Send 1 byte BCD to ASCII form   *
            ;*  Input    :  ACC (Binary)       *
            ;*  Output   :  Serial port        *
            ;*  Register :  ACC.,B.            *
            ;*  Sub.Call :  TX_BYTE            *
            ;***********************************
            ;
TX_BCD:     MOV    B,A
            SWAP   A
            ACALL  SBCD
            MOV    A,B
SBCD:       ANL    A,#0FH
            ORL    A,#30H
            LCALL  TX_BYTE
            RET

            ;******************************
            ;*    Send 2 byte of ASCII    *
            ;*  Input : ACC (HEX)         *
            ;*  Example : A = A3H         *
            ;*          : send 41H,33H    *
            ;******************************
            ;
TX_2ASC:    LCALL  HEX_2ASC
            LCALL  TX_BYTE
            MOV    A,B
            LCALL  TX_BYTE
            RET

            ;******************************
            ;*   Convert HEX to ASCII     *
            ;* Input    :  A              *
            ;* Output   :  A (high-byte)  *
            ;*          :  B (low-byte)   *
            ;******************************
            ;
HEX_2ASC:   PUSH   ACC
            LCALL  HEX_TO_ASC
            MOV    B,A              ; B = Lo byte
            POP    ACC
            SWAP   A
            LCALL  HEX_TO_ASC
            RET

            ;********************************
            ;*  Convert hex (0-F) to ASCII  *
            ;*  Input   : ACC (HEX code)    *
            ;*  Output  : ACC (ASCII code)  *
            ;********************************
            ;
HEX_TO_ASC: PUSH   PSW
            CLR    CY
            ANL    A,#00001111B
            CJNE   A,#09H,HTOA1
            SETB   CY
HTOA1:      JNB    CY,HTOA2       ;> 0AH
            ORL    A,#30H         ;< 0AH
            SJMP   END_HTOA
HTOA2:      SUBB   A,#09H         ;> 0AH
            ORL    A,#40H
END_HTOA:   POP    PSW
            RET

            ;*********************************
            ;*  Receive ascii one character  *
            ;*  from Serial port             *
            ;*  Output  : ACC                *
            ;*********************************
            ;
RX_BYTE:    PUSH   IE
            CLR    ES               ; Disable Interupt
            JNB    RI,$             ; Wait data
            CLR    RI
            MOV    A,SBUF
            POP    IE
            RET

            ;************************************
            ;* Function = Receive ASCII 2 bytes *
            ;*            from serial port and  *
            ;*            convert to hex in "A" *
            ;* Output   = Registor ACC          *
            ;************************************
            ;
RX_2ASCII:  PUSH   B
            PUSH   IE
            CLR    ES
            JNB    RI,$             ;Wait data
            CLR    RI
            MOV    A,SBUF
            LCALL  ASC_TO_HEX       ;Convert to hex
            SWAP   A
            MOV    B,A              ;Hi-nibble
            ;** second byte **
            JNB    RI,$             ;Wait for second byte
            CLR    RI
            MOV    A,SBUF
            LCALL  ASC_TO_HEX       ;Convert ot hex
            ORL    A,B              ;Merge
            POP    IE
            POP    B
            RET

            ;**********************************
            ;*  ASC_TO_HEX  = ASCII TO HEX    *
            ;*  Function    = Convert one byte*
            ;*                of ASCII to one *
            ;*                byte in hex.    *
            ;*  Input       = "A" carry ASCII *
            ;*  Output      = "A" = HEX       *
            ;**********************************
            ;
ASC_TO_HEX: PUSH   PSW
            CLR    CY
            CJNE   A,#41H,MORE_A        ; "A"
MORE_A:     JC     AH2
AH1:        ADD    A,#09
AH2:        ANL    A,#00001111B
            POP    PSW
            RET

            ;***********************************
            ;*   Serial Port Service Routine   *
            ;*  USED Register Bank 2           *
            ;*  OVER_RX  : Set if buffer full  *
            ;*           : Set if 0AH Detect   *
            ;*  Input    : R0 (Pointer Buffer) *
            ;*           : R1 (Buffer count)   *
            ;***********************************
            ;
SERL_IN:    CLR     ES                  ; disable serial interupt
            PUSH    PSW                 ; push Reg.
            PUSH    ACC
            PUSH    DPL
            PUSH    DPH
            SETB    RS1                 ; Select Bank #2
            ;
            JBC     RI,STRT_RX          ; RX flag
            CLR     TI                  ; clear TX flag
            SJMP    OUT_SER             ; Ignore if TX Interupt
STRT_RX:    ;JB      OVER_RX,OUT_SER     ; Buffer full not receive
            MOV     A,SBUF              ; Get data from serial port
            MOV     @R0,A               ; Save to buffer (with carry)
            CLR     ACC.7               ; Ignore parity bit
            CJNE    A,#0AH,NEXT_RX      ; Check end of files
            SJMP    RX_READY
NEXT_RX:    MOV     A,R1                ; Buffer counter
            CJNE    A,#110,CHK_RBUF     ; 110 byte buffer check
CHK_RBUF:   JNC     RX_READY            ; Buffer full
            INC     R1                  ; Addvance counter
            INC     R0                  ; Addvance pointer
            SJMP    OUT_SER             ; Data already save
RX_READY:   ;SETB    OVER_RX             ; Buffer full or ready received
            ;
OUT_SER:    POP     DPH                 ; restore Reg.
            POP     DPL
            POP     ACC
            POP     PSW
            SETB    ES                  ; enable serial interupt
OUT_SRI:    RETI                        ; end of serial service

            END

