The schematic below is used in the several following examples:
Apart from components necessary for the operation of the microcontroller such as oscillator with capacitors and the simplest reset circuit, there are also several LEDs and one push button. These are used to indicate the operation of the program. All LEDs are polarized in such a way that they are activated by driving a microcontroller pin low (logic 0).;************************************************************************ ;* PROGRAM NAME : Delay.ASM ;* DESCRIPTION: Program turns on/off LED on the pin P1.0 ;* Software delay is used (Delay). ;************************************************************************ ;BASIC DIRECTIVES $MOD53 $TITLE(DELAY.ASM) $PAGEWIDTH(132) $DEBUG $OBJECT $NOPAGING ;STACK DSEG AT 03FH STACK_START: DS 040H ;RESET VECTORS CSEG AT 0 JMP XRESET ;Reset vector ORG 100H XRESET: MOV SP,#STACK_START ;Define Stack pointer MOV P1,#0FFh ;All pins are configured as inputs LOOP: CPL P1.0 ;Pin P1.0 state is inverted LCALL Delay ;Time delay SJMP LOOP Delay: MOV R2,#20 ;500 ms time delay F02: MOV R1,#50 ;25 ms F01: MOV R0,#230 DJNZ R0,$ DJNZ R1,F01 DJNZ R2,F02 END ;End of program
;************************************************************************ ;* PROGRAM NAME : WatchDog.ASM ;* DESCRIPTION : After watch-dog reset, program increments number in ;* register R3 and shows it on port P1 in binary format. ;************************************************************************ ;BASIC DIRECTIVES $MOD53 $TITLE(WATCHDOG.ASM) $PAGEWIDTH(132) $DEBUG $OBJECT $NOPAGING WMCON DATA 96H WDTEN EQU 00000001B ; Watch-dog timer is enabled PERIOD EQU 11000000B ; Nominal Watch-dog period is set to be 1024ms ;RESET VECTOR CSEG AT 0 JMP XRESET ; Reset vector CSEG ORG 100H XRESET: ORL WMCON,#PERIOD ; Define Watch-dog period ORL WMCON,#WDTEN ; Watch-dog timer is enabled MOV A,R3 ; R3 is moved to port 1 MOV P1,A INC R3 ; Register R3 is incremented by 1 LAB: SJMP LAB ; Wait for watch-dog reset END ; End of program
;************************************************************************ ;* PROGRAM NAME : Tim0Mod1.ASM ;* DESCRIPTION: Program rotates "0" on port 1. Timer T0 in mode 1 is ;* used ;************************************************************************ ;BASIC DIRECTIVES $MOD53 $TITLE(TIM0MOD1.ASM) $PAGEWIDTH(132) $DEBUG $OBJECT $NOPAGING ;DECLARATION OF VARIABLES ;STACK DSEG AT 03FH STACK_START: DS 040H ;RESET VECTORS CSEG AT 0 JMP XRESET ; Reset vector ORG 00BH JMP TIM0_ISR ; Timer T0 reset vector ORG 100H XRESET: MOV SP,#STACK_START ; Define Stack pointer MOV TMOD,#01H ; MOD1 is selected MOV A,#0FFH MOV P1,#0FFH SETB TR0 ; Timer T0 is enabled MOV IE,#082H ; Interrupt enabled CLR C LOOP1: SJMP LOOP1 ; Remain here TIM0_ISR: RRC A ; Rotate accumulator A through Carry flag MOV P1,A ; Contents of accumulator A is moved to PORT1 RETI ; Return from interrupt END ; End of program
;************************************************************************ ;* PROGRAM NAME : Split.ASM ;* DESCRIPTION: Timer TL0 rotates bit on port P1, while TL1 determines ;* the rotation direction. Both timers operate in mode ;* 3. Logic zero (0) on output P3.2 disables rotation on port P1. ;************************************************************************ ;BASIC DIRECTIVES $MOD53 $TITLE(SPLIT.ASM) $PAGEWIDTH(132) $DEBUG $OBJECT $NOPAGING ;DECLARATION OF VARIABLES BSEG AT 0 ;DECLARATION OF BIT-VARIABLES SEMAPHORE: DBIT 8 DIRECTION BIT SEMAPHORE ;STACK DSEG AT 03FH STACK_START: DS 040H ;RESET VECTORS CSEG AT 0 JMP XRESET ; Reset vector ORG 00BH JMP TIM0_ISR ; Timer T0 reset vector ORG 01BH JMP TIM1_ISR ; Timer T1 reset vector ORG 100H XRESET: MOV SP,#STACK_START ; Define Stack pointer MOV TMOD,#00001011B ; Define MOD3 MOV A,#0FFH MOV P1,#0FFH MOV R0,#30D SETB TR0 ; TL0 is turned on SETB TR1 ; TL1 is turned on MOV IE,#08AH ; Interrupt enabled CLR C CLR DIRECTION ; Rotate to the right LOOP1: SJMP LOOP1 ; Remain here TIM0_ISR: DJNZ R0,LAB3 ; Slow down rotation by 256 times JB DIRECTION,LAB1 RRC A ; Rotate contents of Accumulator to the right through ; Carry flag SJMP LAB2 LAB1: RLC A ; Rotate contents of Accumulator to the left through ; Carry flag LAB2: MOV P1,A ; Contents of Accumulator is moved to port P1 LAB3: RETI ; Return from interrupt TIM1_ISR: DJNZ R1,LAB4 ; Slow down direction of rotation by 256 times DJNZ R2,LAB4 ; When time expires, change rotation direction CPL SMER MOV R2,#30D LAB4: RETI END ; End of program
;************************************************************************ ;* PROGRAM NAME : Tim0Tim1.ASM ;* DESCRIPTION: Timer TO rotates bit on port P1 while Timer1 ;* changes rotation direction. Both timers are configured to operate in mode 1. ;************************************************************************ ;BASIC DIRECTIVES $MOD53 $TITLE(TIM0TIM1.ASM) $PAGEWIDTH(132) $DEBUG $OBJECT $NOPAGING ;DECLARATION OF VARIABLES BSEG AT 0 ;DECLARATION OF BIT-VARIABLES SEMAPHORE: DBIT 8 DIRECTION BIT SEMAPHORE ;STACK DSEG AT 03FH STACK_START: DS 040H ;RESET VECTORS CSEG AT 0 JMP XRESET ; Reset vector ORG 00BH ; Timer 0 Reset vector JMP TIM0_ISR ORG 01BH ; Timer 1 Reset vector JMP TIM1_ISR ORG 100H XRESET: MOV SP,#STACK_START ; Define Stack pointer MOV TMOD,#11H ; Select MOD1 for both timers MOV A,#0FFH MOV P1,#0FFH MOV R0,#30D ; R0 is initialized SETB TR0 ; TIMER0 is turned on SETB TR1 ; TIMER1 is turned on MOV IE,#08AH ; Timer0 and Timer1 Interrupt enabled CLR C CLR DIRECTION ; Rotate to the right LOOP1: SJMP LOOP1 ; Remain here TIM0_ISR: JB DIRECTION,LAB1 RRC A ; Rotate contents of accumulator to the right through ; Carry flag SJMP LAB2 LAB1: RLC A ; Rotate contents of Accumulator to the left through ; Carry flag LAB2: MOV P1,A ; Contents of Accumulator is moved to port P1 RETI ; Return from interrupt TIM1_ISR: DJNZ R0,LAB3 ; When time expires, change rotation direction CPL DIRECTION MOV R0,#30D ; Initialize R0 LAB3: RETI END ; End of program
;************************************************************************ ;* PROGRAM NAME : Timer2.ASM ;* DESCRIPTION: Program rotates log. "0" on port P3. Timer2 determines ;* the speed of rotation and operates in auto-reload mode ;************************************************************************ ;BASIC DIRECTIVES $MOD53 $TITLE(TIMER2.ASM) $PAGEWIDTH(132) $DEBUG $OBJECT $NOPAGING ;DEFINITION OF VARIABLES T2MOD DATA 0C9H ;STACK DSEG AT 03FH STACK_START: DS 040H ;RESET VECTORS CSEG AT 0 JMP XRESET ; Reset vector ORG 02BH ; Timer T2 Reset vector JMP TIM2_ISR ORG 100H XRESET: MOV SP,#STACK_START ; Define Stack pointer MOV A,#0FFH MOV P3,#0FFH MOV RCAP2L,#0FH ; Prepare 16-bit auto-reload mode MOV RCAP2L,#01H CLR CAP2 ; Enable 16-bit auto-reload mod SETB EXEN2 ; Pin P1.1 reset is enabled SETB TR2 ; Enable Timer T2 MOV IE,#0A0H ; Interrupt is enabled CLR C LOOP1: SJMP LOOP1 ; Remain here TIM2_ISR: RRC A ; Rotate contents of Accumulator to the right through ; Carry flag MOV P3,A ; Move the contents of Accumulator A to PORT3 CLR TF2 ; Clear timer T2 flag TF2 CLR EXF2 ; Clear timer T2 flag EXF2 RETI ; Return from interrupt END ; End of program
;************************************************************************ ;* PROGRAM NAME : Int.ASM ;* DESCRIPTION : Program counts interrupts INT0 generated by appearance of high-to-low ;* transition signal on pin P3.2 Result appears on port P0. Interrupts INT1 are also ;* counted up at the same time. They are generated byappearing high-to-low transition ;* signal on pin P3. The result appears on port P1. ;************************************************************************ ;BASIC DIRECTIVES $MOD53 $TITLE(INT.ASM) $PAGEWIDTH(132) $DEBUG $OBJECT $NOPAGING ;RESET VECTORS CSEG AT 0 JMP XRESET ; Reset vector ORG 003H ; Interrupt routine address for INT0 JMP Isr_Int0 ORG 013H ; Interrupt routine address for INT1 JMP Isr_Int1 ORG 100H XRESET: MOV TCON,#00000101B ; Interrupt INT0 is generated by appearing ; high-to-low transition signal on pin P3.2 ; Interrupt INT0 is generated by appearing ; high-to-low transition signal on pin P3.3 MOV IE,#10000101B ; Interrupt enabled MOV R0,#00H ; Counter starting value MOV R1,#00H MOV P0,#00H ; Reset port P0 MOV P1,#00H ; Reset port P1 LOOP: SJMP LOOP ; Remain here Isr_Int0: INC R0 ; Increment value of interrupt INT0 counter MOV P0,R0 RETI Isr_Int1: INC R1 ; Increment value of interrupt INT1 counter MOV P1,R1 RETI END ; End of program
;************************************************************************ ;* PROGRAM NAME : 7Seg1.ASM ;* DESCRIPTION: Program displays number "3" on 7-segment LED display ;************************************************************************ ;BASIC DIRECTIVES $MOD53 $TITLE(7SEG1.ASM) $PAGEWIDTH(132) $DEBUG $OBJECT $NOPAGING ;STACK DSEG AT 03FH STACK_START: DS 040H ;RESET VECTORS CSEG AT 0 JMP XRESET ; Reset vector ORG 100H XRESET: MOV SP,#STACK_START ; Define Stack pointer MOV P1,#0 ; Turn off all segments on displays MOV P3,#20h ; Activate display D4 LOOP: MOV A,#03 ; Send number “3” to display LCALL Disp ; Perform appropriate masking for the number MOV P1,A SJMP LOOP Disp: ; Subroutine for displaying digits INC A MOVC A,@A+PC RET DB 3FH ; Digit 0 mask DB 06H ; Digit 1 mask DB 5BH ; Digit 2 mask DB 4FH ; Digit 3 mask DB 66H ; Digit 4 mask DB 6DH ; Digit 5 mask DB 7DH ; Digit 6 mask DB 07H ; Digit 7 mask DB 7FH ; Digit 8 mask DB 6FH ; Digit 9 mask END ; End of program
;************************************************************************ ;* PROGRAM NAME: 7Seg2.ASM ;* DESCRIPTION: Program writes numbers 0-9 on 7-segment LED display ;************************************************************************ ;BASIC DIRECTIVES $MOD53 $TITLE(7SEG2.ASM) $PAGEWIDTH(132) $DEBUG $OBJECT $NOPAGING ;STACK DSEG AT 03FH STACK_START: DS 040H ;RESET VECTORS CSEG AT 0 JMP XRESET ; Reset vector ORG 100H XRESET: MOV SP,#STACK_START ; Define Stack pointer MOV R3,#0 ; Counter initial value MOV P1,#0 ; Turn off all display segments MOV P3,#20h ; Activate display D4 LOOP: MOV A,R3 LCALL Disp ; Perform appropriate masking for number in ; Accumulator MOV P1,A INC R3 ; Increment number in register by 1 CJNE R3,#10,L2 ; Check whether the number 10 is in R3 MOV R3,#0 ; If it is, reset counter L2: MOV R2,#20 ; 500 mS time delay F02: MOV R1,#50 ; 25 mS F01: MOV R0,#230 DJNZ R0,$ DJNZ R1,F01 DJNZ R2,F02 SJMP LOOP Disp: ; Subroutine for writing digits INC A MOVC A,@A+PC RET DB 3FH ; Digit 0 mask DB 06H ; Digit 1 mask DB 5BH ; Digit 2 mask DB 4FH ; Digit 3 mask DB 66H ; Digit 4 mask DB 6DH ; Digit 5 mask DB 7DH ; Digit 6 mask DB 07H ; Digit 7 mask DB 7FH ; Digit 8 mask DB 6FH ; Digit 9 mask END ; End of program
;************************************************************************ ;* PROGRAM NAME: 7Seg3.ASM ;* DESCRIPTION: Program displays number "23" on 7-segment LED display ;************************************************************************ ;BASIC DIRECTIVES $MOD53 $TITLE(7SEG3.ASM) $PAGEWIDTH(132) $DEBUG $OBJECT $NOPAGING ;STACK DSEG AT 03FH STACK_START: DS 040H ;RESET VECTORS CSEG AT 0 JMP XRESET ; Reset vector ORG 100H XRESET: MOV SP,#STACK_START ; Define Stack pointer LOOP: MOV P1,#0 ; Turn off all display segments MOV P3,#20h ; Activate display D4 MOV A,#03 ; Write digit 3 on display D4 LCALL Disp ; Find appropriate mask for that digit MOV P1,A ; Put the mask on the port MOV P1,#0 ; Turn off all dislay segments MOV P3,#10h ; Activate display D3 MOV A,#02 ; Write digit 2 on display D3 LCALL Disp ; Find mask for that digit MOV P1,A ; Put the mask on the port SJMP LOOP ; Return to the label LOOP Disp: ; Subroutine for writing digits INC A MOVC A,@A+PC RET DB 3FH ; Digit 0 mask DB 06H ; Digit 1 mask DB 5BH ; Digit 2 mask DB 4FH ; Digit 3 mask DB 66H ; Digit 4 mask DB 6DH ; Digit 5 mask DB 7DH ; Digit 6 mask DB 07H ; Digit 7 mask DB 7FH ; Digit 8 mask DB 6FH ; Digit 9 mask END ; End of program
;************************************************************************ ;* PROGRAM NAME : 7Seg5.ASM ;* DESCRIPTION : Program displays number"1234" on 7-segment LED display ;************************************************************************ ;BASIC DIRECTIVES $MOD53 $TITLE(7SEG5.ASM) $PAGEWIDTH(132) $DEBUG $OBJECT $NOPAGING ;STACK DSEG AT 03FH STACK_START: DS 040H ;RESET VECTORS CSEG AT 0 JMP XRESET ; Reset vector ORG 100H XRESET: MOV SP,#STACK_START ; Define Stack pointer LOOP: MOV P1,#0 ; Turn off all display segments MOV P3,#20h ; Activate display D4 MOV A,#04 ; Write digit 4 on display D4 LCALL Disp ; Find mask for that digit MOV P1,A ; Put the mask on the port MOV P1,#0 ; Turn off all display segments MOV P3,#10h ; Activate display D3 MOV A,#03 ; Write digit 3 on display D3 LCALL Disp ; Find mask for that digit MOV P1,A ; Put the mask on the port MOV P1,#0 ; Turn off all display segments MOV P3,#08h ; Activate display D2 MOV A,#02 ; Write digit 2 on display D2 LCALL Disp ; Find mask for that digit MOV P1,A ; Put the mask on the port MOV P1,#0 ; Turn off all display segments MOV P3,#04h ; Activate display D1 MOV A,#01 ; Write digit 1 on display D1 LCALL Disp ; Find mask for that digit MOV P1,A ; Put the mask on the port SJMP LOOP ; Return to the lable LOOP Disp: ; Subroutine for writing digits INC A MOVC A,@A+PC RET DB 3FH ; Digit 0 mask DB 06H ; Digit 1 mask DB 5BH ; Digit 2 mask DB 4FH ; Digit 3 mask DB 66H ; Digit 4 mask DB 6DH ; Digit 5 mask DB 7DH ; Digit 6 mask DB 07H ; Digit 7 mask DB 7FH ; Digit 8 mask DB 6FH ; Digit 9 mask END ; End of program
;************************************************************************ ;* PROGRAM NAME : 7Seg4.ASM ;* DESCRIPTION: Program displays numbers 0-99 on 7-segment LED displays ;************************************************************************ ;BASIC DIRECTIVES $MOD53 $TITLE(7SEG4.ASM) $PAGEWIDTH(132) $DEBUG $OBJECT $NOPAGING ;STACK DSEG AT 03FH STACK_START: DS 040H ;RESET VECTORS CSEG AT 0 JMP XRESET ; Reset vector ORG 100H XRESET: MOV SP,#STACK_START ; Define Stack pointer MOV R2,#0 ; Counter starting value MOV R3,#0 MOV R4,#0 LOOP: INC R4 ;Wait for display to be "refreshed" for 100 times CJNE R4,#20d,LAB1 ;before incrementing the counter MOV R4,#0 MOV P1,#0 ; Turn off all display segments INC R2 ; Increment Register containing units by 1 CJNE R2,#10d,LAB1 MOV R2,#0 ; Reset units INC R3 ; Increment Register with tens by 1 CJNE R3,#10d,LAB1 ; MOV R3,#0 ; Reset tens LAB1: MOV P3,#20h ; Activate display D4 MOV A,R2 ; Copy Register containing units to A LCALL Disp ; Call mask for that digit MOV P1,A ; Write units on display D4 LCALL Delay ; 25ms delay MOV P1,#0 ; Turn off all display segments MOV P3,#10h ; Activate display D3 MOV A,R3 ; Copy Register contaning tens to A LCALL Disp ; Call mask for that digit MOV P1,A ; Write tens on display D3 LCALL Delay ; 25ms delay SJMP LOOP Delay: MOV R1,#50 ; 5 ms delay F01: MOV R0,#250 DJNZ R0,$ DJNZ R1,F01 RET Disp: ; Subroutine for displaying digits INC A MOVC A,@A+PC RET DB 3FH ; Digit 0 mask DB 06H ; Digit 1 mask DB 5BH ; Digit 2 mask DB 4FH ; Digit 3 mask DB 66H ; Digit 4 mask DB 6DH ; Digit 5 mask DB 7DH ; Digit 6 mask DB 07H ; Digit 7 mask DB 7FH ; Digit 8 mask DB 6FH ; Digit 9 mask END ; End of program
;************************************************************************ ;* PROGRAM NAME: EEProm1.ASM ;* DESCRIPTION: Programming EEPROM at address 0000hex and displaying message ;* on LED display. ;************************************************************************ ;BASIC DIRECTIVES $MOD53 $TITLE(EEPROM1.ASM) $PAGEWIDTH(132) $DEBUG $OBJECT $NOPAGING WMCON DATA 96H EEMEN EQU 00001000B ; Access to internal EEPROM is enabled EEMWE EQU 00010000B ; Write to EEPROM is enabled TEMP DATA 030H ; Define Auxiliary register THE END EQU 071H ; Display "F" ERROR EQU 033H ; Display "E" ;STACK DSEG AT 03FH STACK_START: DS 040H ;RESET VECTORS CSEG AT 0 JMP XRESET ; Reset vector ORG 100H XRESET: MOV IE,#00 ; All interrupts are disabled MOV SP,#STACK_START MOV DPTR,#0000H ; Choose location address in EEPROM ORL WMCON,#EEMEN ; Access to EEPROM is enabled ORL WMCON,#EEMWE ; Write to EEPROM is enabled MOV TEMP,#23H ; Number written to EEPROM is moved to MOV A,TEMP ; register TEMP and Accumulator MOVX @DPTR,A ; Write byte to EEPROM CALL DELAY ; 10ms delay MOVX A,@DPTR ; Read the same location and compare to TEMP, CJNE A,TEMP,ERROR ; If they don't match, jump to label ERROR MOV A,#KRAJ ; Display F (correct) MOV P1,A XRL WMCON,#EEMWE ; Write to EEPROM is disabled XRL WMCON,#EEMEN ; Access to EEPROM is disabled LOOP1: SJMP LOOP1 ; Remain here ERROR: MOV A,#ERROR ; Display E (error) MOV P1,A LOOP2: SJMP LOOP2 DELAY: MOV A,#0AH ; Delay MOV R3,A LOOP3: NOP LOOP4: DJNZ B,LOOP4 LOOP5: DJNZ B,LOOP5 DJNZ R3,LOOP3 RET END ; End of program
;************************************************************************ ;* PROGRAM NAME : UartR.ASM ;* DESCRIPTION: Each data received from PC via UART appears on the port ;* P1. ;* ;************************************************************************ ;BASIC DIRECTIVES $MOD53 $TITLE(UARTR.ASM) $PAGEWIDTH(132) $DEBUG $OBJECT $NOPAGING ;STACK DSEG AT 03FH STACK_START: DS 040H ;RESET VECTORS CSEG AT 0 JMP XRESET ; Reset vector ORG 023H ; Starting address of UART interrupt routine JMP IR_SER ORG 100H XRESET: MOV IE,#00 ; All interrupts are disabled MOV SP,#STACK_START ; Initialization of Stack pointer MOV TMOD,#20H ; Timer1 in mode2 MOV TH1,#0FDH ; 9600 baud rate at the frequency of ; 11.0592MHz MOV SCON,#50H ; Receiving enabled, 8-bit UART MOV IE,#10010000B ; UART interrupt enabled CLR TI ; Clear transmit flag CLR RI ; Clear receive flag SETB TR1 ; Start Timer1 LOOP: SJMP LOOP ; Remain here IR_SER: JNB RI,OUTPUT ; If any data is received, ; move it to the port MOV A,SBUF ; P1 MOV P1,A CLR RI ; Clear receive flag OUTPUT RETI END ; End of program
;************************************************************************ ;* PROGRAM NAME : UartS.ASM ;* DESCRIPTION: Sends values 0-255 to PC. ;************************************************************************ ;BASIC DIRECTIVES $MOD53 $TITLE(UARTS.ASM) $PAGEWIDTH(132) $DEBUG $OBJECT $NOPAGING ;STACK DSEG AT 03FH STACK_START: DS 040H ;RESET VECTORS CSEG AT 0 JMP XRESET ; Reset vector ORG 100H XRESET: MOV IE,#00 ; All interrupts are disabled MOV SP,#STACK_START ; Initialization of Stack pointer MOV TMOD,#20H ; Timer1 in mode 2 MOV TH1,#0FDH ; 9600 baud rate at the frequency of ; 11.0592MHz MOV SCON,#40H ; 8-bit UART CLR TI ; Clear transmit bit CLR RI ; Clear receive flag MOV R3,#00H ; Reset caunter SETB TR1 ; Start Timer 1 START: MOV SBUF,R3 ; Move number from counter to a PC LOOP1: JNB TI,LOOP1 ; Wait here until byte transmission is ; complete CLR TI ; Clear transmit bit INC R3 ; Increment the counter value by 1 CJNE R3,#00H,START ; If 255 bytes are not sent return to the ; label START LOOP: SJMP LOOP ; Remain here END ; End of program
************************************************************************* ;* 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
;************************************************************************ ;* 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