Writing message on LCD display
This example uses the most frequently used type of LCD which displays text in two lines with 16 characters each. In order to save I/O ports, only 4 pins are used for communication here. In this way each byte is transmitted in two steps: first higher then lower nible.LCD needs to be initialized at the beginning of the program. Besides, parts of the program which repeat in the program create special subroutines. All this may seem extremely complicated, but the whole program basically performs several simple operations and displays ”Mikroelektronika Razvojni sistemi”.
************************************************************************* ;* PROGRAM NAME : Lcd.ASM ;* DESCRIPRTION : Program for testing LCD display. 4-bit communication ;* is used. Program does not check BUSY flag but uses program delay ;* between 2 commands. PORT1 is used for connection ;* to the microcontroller. ;************************************************************************ ;BASIC DIRECTIVES $MOD53 $TITLE(LCD.ASM) $PAGEWIDTH(132) $DEBUG $OBJECT $NOPAGING ;Stack DSEG AT 0E0h Stack_Start: DS 020h Start_address EQU 0000h ;Reset vectors CSEG AT 0 ORG Start_address JMP Inic ORG Start_address+100h MOV IE,#00 ; All interrupts are disabled MOV SP,#Stack_Start Inic: CALL LCD_inic ; Initialize LCD ;************************************************* ;* MAIN PROGRAM ;************************************************* START: MOV A,#80h ; Next character will appear on the first CALL LCD_status ; location in the first line of LCD display. MOV A,#'M' ; Display character ‘M’. CALL LCD_putc ; Call subroutine for character transmission. MOV A,#'i' ; Display character ‘i’. CALL LCD_putc MOV A,#'k' ; Display character ‘k’. CALL LCD_putc MOV A,#'r' ; Display character ‘r’. CALL LCD_putc MOV A,#'o' ; Display character ‘o’. CALL LCD_putc MOV A,#'e' ; Display character ‘e’. CALL LCD_putc MOV A,#'l' ; Display character ‘l’. CALL LCD_putc MOV A,#'e' ; Display character ‘e’. CALL LCD_putc MOV A,#'k' ; Display character ‘k’. CALL LCD_putc MOV A,#'t' ; Display character ‘t’. CALL LCD_putc MOV A,#'r' ; Display character ‘r’. CALL LCD_putc MOV A,#'o' ; Display character ‘o’. CALL LCD_putc MOV A,#'n' ; Display character ‘n’. CALL LCD_putc MOV A,#'i' ; Display character ‘i’. CALL LCD_putc MOV A,#'k' ; Display character ‘k’. CALL LCD_putc MOV A,#'a' ; Display character ‘a’. CALL LCD_putc MOV A,#0c0h ; Next character will appear on the first CALL LCD_status ; location in the second line of LCD display. MOV A,#'R' ; Display character ‘R’. CALL LCD_putc ; Call subroutine for character transmission. MOV A,#'a' ; Display character ‘a’. CALL LCD_putc MOV A,#'z' ; Display character ‘z’. CALL LCD_putc MOV A,#'v' ; Display character ‘v’. CALL LCD_putc MOV A,#'o' ; Display character ‘o’. CALL LCD_putc MOV A,#'j' ; Display character ‘j’. CALL LCD_putc MOV A,#'n' ; Display character ‘n’. CALL LCD_putc MOV A,#'i' ; Display character ‘i’. CALL LCD_putc MOV A,#' ' ; Display character ‘ ’. CALL LCD_putc MOV A,#'s' ; Display character ‘s’. CALL LCD_putc MOV A,#'i' ; Display character ‘i’. CALL LCD_putc MOV A,#'s' ; Display character ‘s’. CALL LCD_putc MOV A,#'t' ; Display character ‘t’. CALL LCD_putc MOV A,#'e' ; Display character ‘e’. CALL LCD_putc MOV A,#'m' ; Display character ‘m’. CALL LCD_putc MOV A,#'i' ; Display character ‘i’. CALL LCD_putc MOV R0,#20d ; Wait time (20x10ms) CALL Delay_10ms ; MOV DPTR,#LCD_DB ; Clear display MOV A,#6d ; CALL LCD_inic_status ; MOV R0,#10d ; Wait time(10x10ms) CALL Delay_10ms JMP START ;********************************************* ;* Subroutine for wait time (T= r0 x 10ms) ;********************************************* Delay_10ms: MOV R5,00h ; 1+(1+(1+2*r7+2)*r6+2)*r5 approximately MOV R6,#100d ; (if r7>10) MOV R7,#100d ; 2*r5*r6*r7 DJNZ R7,$ ; $ indicates current instruction. DJNZ R6,$-4 DJNZ R5,$-6 RET ;************************************************************************************** ;* SUBROUTINE: LCD_inic ;* DESCRIPTION: Subroutine for LCD initialization. ;* ;* (is used with 4-bit interface, under condition that pins DB4-7 on LCD ;* are connected to pins PX.4-7 on microcontroller’s ports, i.e. four higher ;* bits on the port are used). ;* ;* NOTE: It is necessary to define port pins for controlling LCD operation: ;* LCD_enable, LCD_read_write, LCD_reg_select,similar to port for connection to LCD. ;* It is also necessary to define addresses for the first character in each ;* line. ;************************************************************************************** LCD_enable BIT P1.3 ; Bit for activating pin E on LCD. LCD_read_write BIT P1.1 ; Bit for activating pin RW on LCD. LCD_reg_select BIT P1.2 ; Bit for activating pin RS on LCD. LCD_port SET P1 ; Port for connection to LCD. Busy BIT P1.7 ; Port pin on which Busy flag appears. LCD_Start_I_red EQU 00h ; Address of the first message character ; in the first line of LCD display. LCD_Start_II_red EQU 40h ; Address of the first message character ; in the second line of LCD display. LCD_DB: DB 00111100b ; 0 -8b, 2/1 lines, 5x10/5x7 format DB 00101100b ; 1 -4b, 2/1 lines, 5x10/5x7 format DB 00011000b ; 2 -Display/cursor shift, right/left DB 00001100b ; 3 -Display ON, cursor OFF, cursor blink off DB 00000110b ; 4 -Increment mode, display shift off DB 00000010b ; 5 -Display/cursor home DB 00000001b ; 6 -Clear display DB 00001000b ; 7 -Display OFF, cursor OFF, cursor blink off LCD_inic: ;***************************************** MOV DPTR,#LCD_DB MOV A,#00d ; Triple initialization in 8-bit CALL LCD_inic_status_8 ; mode is performed at the beginning MOV A,#00d ; (in case of slow increment of CALL LCD_inic_status_8 ; power supply when the power supply is on MOV A,#00d lcall LCD_inic_status_8 MOV A,#1d ; Change from 8-bit into CALL LCD_inic_status_8 ; 4-bit mode MOV A,#1d CALL LCD_inic_status MOV A,#3d ; As from this point the program executes in ;4-bit mode CALL LCD_inic_status MOV A,#6d CALL LCD_inic_status MOV A,#4d CALL LCD_inic_status RET LCD_inic_status_8: ;****************************************** PUSH B MOVC A,@A+DPTR CLR LCD_reg_select ; RS=0 - Write command CLR LCD_read_write ; R/W=0 - Write data on LCD MOV B,LCD_port ; Lower 4 bits from LCD port are memorized ORL B,#11110000b ORL A,#00001111b ANL A,B MOV LCD_port,A ; Data is moved from A to LCD port SETB LCD_enable ; high-to-low transition signal ; is generated on the LCD's EN pin CLR LCD_enable MOV B,#255d ; Time delay in case of improper reset DJNZ B,$ ; during initialization DJNZ B,$ DJNZ B,$ POP B RET LCD_inic_status: ;**************************************************************************** MOVC A,@A+DPTR CALL LCD_status RET ;**************************************************************************** ;* SUBROUTINE: LCD_status ;* DESCRIPTION: Subroutine for defining LCD status. ;**************************************************************************** LCD_status: PUSH B MOV B,#255d DJNZ B,$ DJNZ B,$ DJNZ B,$ CLR LCD_reg_select ; RS=O: Command is sent to LCD CALL LCD_port_out SWAP A ; Nibles are swapped in accumulator DJNZ B,$ DJNZ B,$ DJNZ B,$ CLR LCD_reg_select ; RS=0: Command is sent to LCD CALL LCD_port_out POP B RET ;**************************************************************************** ;* SUBROUTINE: LCD_putc ;* DESCRIPTION: Sending character to be displayed on LCD. ;**************************************************************************** LCD_putc: PUSH B MOV B,#255d DJNZ B,$ SETB LCD_reg_select ; RS=1: Character is sent to LCD CALL LCD_port_out SWAP A ; Nibles are swapped in accumulator DJNZ B,$ SETB LCD_reg_select ; RS=1: Character is sent to LCD CALL LCD_port_out POP B RET ;**************************************************************************** ;* SUBROUTINE: LCD_port_out ;* DESCRIPTION: Sending commands or characters on LCD display ;**************************************************************************** LCD_port_out: PUSH ACC PUSH B MOV B,LCD_port ; Lower 4 bits of LCD port are memorized ORL B,#11110000b ORL A,#00001111b ANL A,B MOV LCD_port,A ; Data is copied from A to LCD port SETB LCD_enable ; high-to-low transition signal ; is generated on the LCD's EN pin CLR LCD_enable POP B POP ACC RET END ; End of program
Binary to decimal number conversion
When using LED and LCD displays, it is often necessary to convert numbers from binary to decimal. For example, if some register contains a number in binary format that should be displayed on a three digit LED display it is first necessary to convert it to decimal format. In other words, it is necessary to define what should be displayed on the most right display (units), middle display (tens) and most left display (hundreds).The subroutine below performs conversion of one byte. Binary number is stored in the accumulator, while digits of that number in decimal format are stored in registers R3, R2 and accumulator (units, tens and hundreds, respectively).
;************************************************************************ ;* SUBROUTINE NAME : BinDec.ASM ;* DESCRIPTION : Content of accumulator is converted into three decimal digits ;************************************************************************ BINDEC: MOV B,#10d ; Store decimal number 10 in B DIV AB ; A:B. Remainder remains in B MOV R3,B ; Move units to register R3 MOV B,#10d ; Store decimal number 10 in B DIV AB ; A:B. Remainder remains in B MOV R2,B ; Move tens to register R2 MOV B,#10d ; Store decimal number 10 in B DIV AB ; A:B. Remainder remains in B MOV A,B ; Move hundreds to accumulator RET ; Return to the main program