;test.A51 test program ;check the LCD display 2x20 characters, additional serial and buzzer ; $DEBUG ; debug in obj $PAGELENGTH (65535) ; listing lines $PAGEWIDTH (110) ; listing columns $XREF ; symbols table CODESEG SEGMENT CODE ; programm (code) zone STIVA SEGMENT DATA ; stack VARSEG SEGMENT DATA ; byte data zone RSEG STIVA DS 32 ; stack 32 bytes RSEG VARSEG ATEXL: DS 1 ; low addr of display text ATEXH: DS 1 ; high addr of dysplay text CONTOR: DS 1 ; counter NUMAR: DS 1 ; nr of char per line PORTEX: DS 1 ; extension port status ;-------main programm-------------------------------------------------- RSEG CODESEG USING 0 ; use bank 0 ORG 8000H ; starting prog addr LJMP INCEPUT ORG 8003H ; External interrupt 0 RETI ORG 800BH ; Timer 0 interrupt RETI ORG 8013H ; External interrupt 1 RETI ORG 801BH ; Timer 1 interrupt RETI ORG 8023H ; Serial interrupt RETI INCEPUT: MOV SP,#STIVA-1 ; init stack CALL INIHARD ; init hardware CALL INILCD ; init LCD START: MOV R1,#3 CCC1: MOV R2,#80H ; DD RAM Address Set - first line CALL WRITECOM ; send command to LCD MOV DPTR,#TEXT1 CALL AFITEX ; send txt to LCD MOV R2,#0C0H ; DD RAM Address Set - second line CALL WRITECOM MOV DPTR,#TEXT2 CALL AFITEX ; send txt to LCD CALL DELAY_500ms MOV R2,#01H ; 00000001 = display clear CALL WRITECOM ; send command to LCD CALL BEEP CALL DELAY_500ms DJNZ R1,CCC1 CALL DELAY_500ms ;--------------------------------------------------------------------- MOV R2,#80H ; DD RAM Address Set - first line CALL WRITECOM ; send command to LCD MOV DPTR,#TEXT3 CALL AFITEX ; send txt to LCD MOV R2,#0C0H ; DD RAM Address Set - second line CALL WRITECOM MOV DPTR,#TEXT4 CALL AFITEX ; send txt to LCD CALL DELAY_500ms CALL DELAY_500ms MOV R2,#01H ; 00000001 = display clear CALL WRITECOM ; send command to LCD CALL DELAY_500ms JMP START ;------------------------------------------------------------------------ TEXT1: DB 'Module LCD 2x20 char',00H TEXT2: DB 'Type LCD alphanum. ',00H TEXT3: DB 'ABCDEFGHIJKLMNOPQRST',00H TEXT4: DB 'UVWXYZ1234567890abcd',00H ;----------------------subs----------------------------------------- SwPC: ; switch serial to main serial SETB P1.0 ; MEM&P in 1 - switch to port MOV A,PORTEX ; send port status CLR ACC.0 ; to PC SETB ACC.1 SETB ACC.2 MOVX @R1,A MOV PORTEX,A ; memorize new status CLR P1.0 ; switch back from port to RAM RET ;------------------------------------------------------------------------- SwPrint: ; switch serial to additional serial SETB P1.0 ; MEM&P (for port ) goes to 1 MOV A,PORTEX ; send port status SETB ACC.0 CLR ACC.1 ; to sdditional serial SETB ACC.2 MOVX @R1,A MOV PORTEX,A ; memorize new status CLR P1.0 ; switch back from port to RAM RET ;------------------------------------------------------------------------- TXCHAR: ; send a character from A to serial JNB TI,TXCHAR CLR TI MOV SBUF,A RET ;------------------------------------------------------------------------ INIHARD: ; init hardware MOV A,#01111110B ; 0 - 1 - 1 - 1 -1- 1 - 1 - 0 ; ENAF-RSAF-CASH1-BEEPER-*-CDAAX-CDATP-CDAIO SETB P1.0 ; MEM&P(for port ) goes to 1 MOVX @R1,A ; send A to port (does not matter R1) MOV PORTEX,A ; memorize port status clr p1.4 ; get port out of high impedance state setb p1.4 ; clr p1.4 setb p1.4 MOV P1,#11111100B ; MEM&P (for RAM) goes to 0 ; signals for I2C goes to 1 RET ;------------------------------------------------------------------------- BEEP: ; a buzzer beep 10 ms SETB P1.0 ; MEM&P(for port ) to 1 MOV A,PORTEX CLR ACC.4 ; set power supply to buzzer MOVX @R1,A CALL DELAY_2ms CALL DELAY_2ms CALL DELAY_2ms CALL DELAY_2ms CALL DELAY_2ms SETB ACC.4 ; cut power supply to buzzer MOVX @R1,A CLR P1.0 RET ;------------------------------------------------------------------------- DHLCD: ; data high (4 bit) to LCD ; data is in R2 and we use high digit MOV A,R2 ; load in A DHLCD1: ANL A,#11110000B ; mask (delete) 4 bit low ORL A,#00001100B ; add bit low, 11 for I2C, 00 for rest MOV P1,A RET ;------------------------------------------------------------------------- DLLCD: ; data low (4 bit) to LCD ; data is in R2 and we use low digit MOV A,R2 SWAP A ; reverse digits in A AJMP DHLCD1 ;-------------------------------------------------------------------------- ENDATA: ; send EN to LCD for data SETB P1.0 ; MEM&P goes to port ext. MOV A,PORTEX ; load status of port SETB ACC.7 ; EN goes to 1 MOVX @R1,A ; R1 does not matter CLR ACC.7 ; EN goes to 0 MOVX @R1,A CLR P1.0 ; switch back to RAM RET ;-------------------------------------------------------------------------- ENCDA: ; send EN to LCD for commands SETB P1.0 ; MEM&P goes to port MOV A,PORTEX ; load port status CLR ACC.6 ; RS=0 MOVX @R1,A ; R1 does not matter SETB ACC.7 ; EN up MOVX @R1,A ; CLR ACC.7 ; EN down MOVX @R1,A CLR ACC.6 ; RS=1 MOVX @R1,A ; CLR P1.0 ; switch back to RAM RET ;------------------------------------------------------------------------ WRITEDATA: ; send data to LCD (one char) from R2 CALL DHLCD CALL ENDATA CALL DLLCD CALL ENDATA CALL DELAY_100us RET ;--------------------------------------------------------------------------- WRITECOM: ; send command from R2 to LCD CALL DHLCD CALL ENCDA CALL DLLCD CALL ENCDA CALL DELAY_100us RET ;---------------------------------------------------------------------------- INILCD: ; init LCD for 4 bit work MOV R2,#30H CALL DHLCD CALL ENCDA ; 3h CALL DELAY_2ms CALL DELAY_2ms CALL ENCDA ; 3h CALL DELAY_100us CALL ENCDA ; 3h CALL DELAY_100us MOV R2,#20H CALL DHLCD CALL ENCDA ; 2h CALL DELAY_100us MOV R2,#28H ; 001 - function set, 0 - 4 bit data CALL WRITECOM ; 1 - 2 lines, 0 - 5x7 dot format MOV R2,#06H ; 000001 - entry mode set, 1 - increment CALL WRITECOM ; 0 - no shift MOV R2,#0CH ; 00001 - display control, 1 - display on CALL WRITECOM ; 0 - cursor off, 0 - blink off MOV R2,#01H ; display clear CALL WRITECOM CALL DELAY_2ms MOV R2,#80H ; 80h - first line, first digit CALL WRITECOM RET ;---------------------------------------------------------------------------- AFITEX: ; send a line of text ; with addr in DPTR ; txt ends with 00H MOV ATEXL,DPL ; memorize adrlow of text in ATEXL MOV ATEXH,DPH ; memorize adrhigh of text in ATEXL MOV CONTOR,#00H ; init counter BEGIN1: MOV A,CONTOR ; load counter in A MOV DPL,ATEXL ; load in DPTR adr of text MOV DPH,ATEXH ; MOVC A,@A+DPTR ; load in A value find on DPTR + counter JZ LABEL1 ; if zero, jump MOV R2,A ; load value in R2 CALL WRITEDATA ; send data to LCD mov a,r2 call txchar call swprint mov a,r2 call txchar call swpc INC CONTOR ; next JMP BEGIN1 ; LABEL1: RET ;--------------------------------------------------------------------------- DELAY_100us: ; wait 100us MOV R7,#23 ; for FQ=11,059MHz , Tosc=90,424ns XXX1: NOP ; 1 hard cicle=12*Tosc=1,085us NOP ; 2 nop + 1 djnz = 4 hard cicles DJNZ R7,XXX1 ; delay=4*23*1hardcicle=99.8us RET ;----------------------------------------------------------------------- DELAY_2ms: ; wait 2ms MOV R6,#19 ; load R6 with 19 XXX2: ACALL DELAY_100us ; call absolute (short) DJNZ R6,XXX2 ; decrement register and jump if not zero RET ;--------------------------------------------------------------------------- DELAY_500ms: ; wait 0,5 seconds MOV R5,#250 ; load R5 with 250 XXX3: ACALL DELAY_2ms ; call absolute (short) DJNZ R5,XXX3 ; decrement register and jump if not zero RET ;--------------------------------------------------------------------------- END