;---; Copyright (C) 2001 Samuel Barnes.
; All rights reserved. ;
; Name : Samuel Barnes
; Login : barnsa
; Homework # : 6
; Date : 11-26-01
; FILE NAME : barnsa.ASM ; TARGET MCU : C8051F000
; DESCRIPTION : Timer program, will count three things: count seconds after you hit MOM0
; a simple stop watch, will count how long you hold down MOM0 in seconds, and ; will count how many times you press MOM2, MOM1 is a reset. No LATs on is stop ; watch mode, LAT0 on is hold down mode, and LAT1 on is count button press mode, ; if LAT0 and LAT1 are both on nothing will run.
; ;
; NOTES:
; (1) Memory usage:
; Bytes:
; R7, R1, R2 = Clock Registers R3->R4 = Alarm Registers R5->R6 = Total Timer Value R0 = (indirect addressing)
;
; 08h = Clock 1/20 of a sec byte
; 09h = Blink Delay byte
; 0Ah->0Bh = Set mode display bytes
; 0Ch = Timer delay byte
; 0Dh = Alarm delay byte
; 0Eh = Alarm time limit byte
; 0Fh = Old time value
; 10h->11h = Old display bytes value (used so it is only updated when they change)
; 12h = Set Display mode
; 13h -> 15h = Current Chrono Values ; 16h -> 1Fh = indirect addressing bytes ; 20h->22h = Instant timer value
; 23h->25h = Old Instant timer value
; 26h = Old Chrono Value
; 27h = Chrono delay byte
; 28h = Bit values
; @29h = Saved for future bit values
; 2Ah = Tenths of second chrono bit
; 2Bh = Alarm on off byte
; 2Ch -> 2Fh = Un-Used
;
; Bits:
; 41h = Display on off bit
; 42h = Timer alarm bit
; 43h = Chrono StartStop bit
; 44h = Set Alarm Alarm bit
; 45h = Alarm on off bit
; 46h = Alarm oscilate bit
; @@47h = Un-Used
; 48h->4Fh = Saved For Now
;
; (2) To Do:
; Write alarm sound
;
;---; EQUATES
;---$include (c8051f000.inc) ; Include regsiter definition file.
D0 EQU P0.0 D1 EQU P0.1 D2 EQU P0.2 D3 EQU P0.3 D4 EQU P0.4 D5 EQU P0.5 D6 EQU P0.6 D7 EQU P0.7 MOM3 EQU P1.7 MOM2 EQU P1.6 MOM1 EQU P1.5 MOM0 EQU P1.4 LAT3 EQU P1.3 LAT2 EQU P1.2 LAT1 EQU P1.1 LAT0 EQU P1.0 RS EQU P3.0 RW EQU P3.1 EN EQU P3.2
;---; VARIABLES
;---; RESET and INTERRUPT VECTORS
; Reset Vector cseg AT 0
ljmp Main ; Locate a jump to the start of code at ; the reset vector.
org 000Bh ljmp Timer0_Int org 001Bh ljmp Timer1_Int org 002Bh ljmp Timer2_Int org 0073h ljmp Timer3_Int ;---; CODE SEGMENT ;---Code_Seg segment CODE
rseg Code_Seg ; Switch to this code segment. using 0 ; Specify register bank for the following ; program code.
Main: ; Disable the WDT. (IRQs not enabled at this point.)
; If interrupts were enabled, we would need to explicitly disable
; them so that the 2nd move to WDTCN occurs no more than four clock ; cycles after the first move to WDTCN.
mov WDTCN, #0DEh mov WDTCN, #0ADh
;---;Cyrstal initialization ;---;XOSCMD 110 ;XFCN 101 mov OSCXCN, #65h ;11100101 mov OSCICN, #18h ;00011000 ;---;Port I/O Crossbar Initialization
;---mov XBR2, #40h
;disable weak pullups mov xbr2, #0C0h
;---;DL6 Board Initialization ;---mov PRT1CF, #0 mov PRT2CF, #0 mov P1, #0FFh mov P2, #0FFh
mov P0, #000h ;turns off all LED's mov P3, #00h ;clears port 3 mov PRT0CF,#00h ;set's P0 as push-pull
;---;Memory Initialization
;---mov SP, #30h ;moves stack pointer up out of the way
mov 08h, #14h ;sets clock bit to 20 base 10 (have to have this) mov 09h, #04h ;sets blink delay byte
mov 13h, #00h
mov 14h, #00h ;sets Chrono bytes to zero mov 15h, #00h
mov 20h, #00h
mov 21h, #00h ;clears actual timer bytes mov 22h, #00h
mov 23h, #0FFh ;sets old actual timer byte so display will be refeshed ;as soon as you switch modes
mov 26h, #0FFh ;sets old chrono value so display will initially refresh mov 28h, #00h ;clears bits
mov 0Ch, #01h ;timer delay byte mov 0Dh, #01h ;alarm delay byte mov R0, #00h mov R1, #00h mov R2, #00h mov R3, #00h mov R4, #00h mov R5, #00h mov R6, #00h mov R7, #00h mov 10h, #0FFh
;Indirect adressing for my clock display
mov 16h, #030h ;0 mov 17h, #031h mov 18h, #032h mov 19h, #033h mov 1Ah, #034h mov 1Bh, #035h mov 1Ch, #036h mov 1Dh, #037h mov 1Eh, #038h mov 1Fh, #039h ;9 ;---; Interupt Initialization ;---setb EA setb ET0 setb ET1
setb ET2 ;must clear interupt on timer 2 and 3 manually mov EIE2,#01h ;enables timer 3 interupt
;mov IE, #20h ;makes timer 2 (clock timer) high priority
;---; Timer Initialization
;---mov TMOD, #010h ; Timer Mode Register timer 1 and 0 16bit mode mov T2CON, #004h ; Timer 2 Control Register 16-bit auto re-load, turns it on ;mov TMR3CN, #004h ; Timer 3 Control Register 16-bit auto re-load, turns it on
mov RCAP2H, #76 ; Timer 2 Reset Register High Byte 19,457 (76 * 256 = 19,456) initial value so timer takes 1/20sec
mov TMR3RLH, #076 ; Timer 3 Reload Register High Byte mov TMR3RLL, #001 ; Timer 3 Reload Register Low Byte
MOV TH1,#076 ;High byte of timer 76 (makes 1/20 of a sec)
MOV TL1,#01 ;Low byte of time1
;MOV TH0,#0FFh ;High byte of
;MOV TL0,#0F1h ;Low byte of
;SETB TR0 ;starts timer0 ;SETB TR1 ;starts timer1
;---; Headphone Initialization
;---mov REF0CN, #03h
mov DAC0CN, #084h ; DAC0 Control Register or 80, 84 left or right alligned ; hertz 260 to 512
mov DAC0H, #016h ; DAC0 High Byte Register
mov DAC1CN, #084h ; DAC1
mov DAC1H,#016h ;---; Start of Prgram ;---LCALL init_lcd Clock: jb LAT3, SetAlarm jb LAT1, SetClock jb LAT2, SetTimerL jb MOM0, TimerModeL LCALL RefreshClock
jmp Clock TimerModeL: ljmp TimerMode SetTimerL: ljmp SetTimer SetAlarm:
;mov TMR3CN, #004h ;starts timer 3 mov 12h, #03h ;sets display set byte jb MOM3, AddHourA
jb MOM2, AddMinA
mov 0Ah, R3 ;moves alarm registers to display bytes mov 0Bh, R4
LCALL Refresh_Set ;calls set mode refresh jnb LAT3, GoClockL ;turns timers off jmp SetAlarm
AddMinA:
jb MOM2, AddMinA ;wait for button release mov Acc, #1h
add A, R3 ;incriments the minutes on the alarm
mov R3, Acc
mov Acc, #3Ch ;(60 base 10) checks so when you get to 60 you wrap subb A, R3
jz WrapMinA ;if A is zero wrap the minutes jmp SetAlarm
WrapMinA:
mov R3, #00h jmp SetAlarm AddHourA:
jb MOM3, AddHourA ;wait for button release mov Acc, #1h
add A, R4 ;incriments the hours on the alarm
mov R4, Acc
mov Acc, #17h ;(23 base 10) wraps when hours get to 23 subb A, R4
jz WrapHourA jmp SetAlarm WrapHourA: mov R4, #00h jmp SetAlarm GoClockL: ljmp GoClock ;end set alarm
SetClock:
;mov TMR3CN, #004h ;starts timer 3 mov 12h, #01h ;sets display set byte jb MOM2, AddMinC
jb MOM3, AddHourC
mov 0Ah, R1 ;moves clock registers to display registers mov 0Bh, R2
LCALL Refresh_Set ;calls set mode refresh
jnb LAT1, GoClock ;may have to make a new GoClock function... jmp SetClock
AddMinC:
jb MOM2, AddMinC ;wait for button release mov Acc, #1h
add A, R1 ;incriments the minutes on the timer
mov R1, Acc
mov Acc, #3Ch ;(60 base 10) checks so when you get to 60 you wrap subb A, R1
jz WrapMinC ;if A is zero wrap the minutes jmp SetClock
WrapMinC:
mov R1, #00h jmp SetClock AddHourC:
jb MOM3, AddHourC ;wait for button release mov Acc, #1h
add A, R2 ;incriments the hours on the alarm
mov R2, Acc
mov Acc, #24 ;24 wraps when hours get to 23 subb A, R2 jz WrapHourC jmp SetClock WrapHourC: mov R2, #00h jmp SetClock ;end set Clock
SetTimer:
;mov TMR3CN, #004h ;starts timer 3 mov 12h, #02h ;sets display set byte jb MOM2, AddMinT
jb MOM3, AddHourT
mov 0Ah, R5 ;moves timer registers to display bytes mov 0Bh, R6
LCALL Refresh_Set ;calls set mode refresh
mov 21h, R5 ;moves timer registers to actual registers
mov 22h, R6 ;actual being the ones that count down, R5, R6 hold total value jnb LAT2, GoClock ;may have to make a new GoClock function...
jmp SetTimer AddMinT:
jb MOM2, AddMinT ;wait for button release mov Acc, #1h
add A, R5 ;incriments the minutes on the timer
mov R5, Acc
mov Acc, #3Ch ;(60 base 10) checks so when you get to 60 you wrap subb A, R5
jz WrapMinT ;if A is zero wrap the minutes jmp SetTimer
mov R5, #00h jmp SetTimer AddHourT:
jb MOM3, AddHourT ;wait for button release mov Acc, #1h
add A, R6 ;incriments the hours on the alarm
mov R6, Acc
mov Acc, #17h ;(23 base 10) wraps when hours get to 23 subb A, R6 jz WrapHourT jmp SetTimer WrapHourT: mov R6, #00h jmp SetTimer ;end set timer GoClock:
;mov TMR3CN, #000h ;stops timer 3
mov 10h, #0FFh ;writes FFh to old display bits so display will refresh mov 11h, #0FFh ;as soon as you go into set mode
ljmp Clock
TimerMode:
jb MOM0, TimerMode ;waits for button to be relased LCALL Refresh_Display
TimerModeLoop: ;so the wrong jb MOM0 won't get selected jb MOM1, StartStopL jb MOM2, ResetTimerL jb MOM0, ChronoModeLR jb LAT1, ClockLL jb LAT2, ClockLL jb LAT3, ClockLL
;move timer memory 20h->22h to display*******
;comapre old instant values (23h->25h) with new to see if you update display
mov A, 23h ;compares the seconds cjne A, 20h, UpdateTimer
mov A, 24h
cjne A, 21h, UpdateTimer ;compares the minutes mov A, 25h
cjne A, 22h, UpdateTimer ;copmares the hours
jmp TimerModeLoop ;if values are equal no need to refresh display StartStopL:
ljmp StartSTop ClockLL:
jb MOM0, $ ;wait for button release
mov 23h, #0FFh ;sets old instant timer value so display will be refresed ;when they switch the mode back
ljmp Clock ResetTimerL: ljmp ResetTimer ChronoModeLR:
jb MOM0, $ ;wait for button release
mov 23h, #0FFh ;sets old instant timer value so display will be refresed ;when they switch the mode back
jmp ChronoMode
UpdateTimer:
LCALL Clear_LCD LCALL Cursor_Home
mov 23h, 20h ;update old instant timer values mov 24h, 21h mov 25h, 22h mov 0h, 22h ;hours LCALL Refresh_Display mov A, #':' ;colon LCALL Write_Text mov 0h, 21h ;minutes LCALL Refresh_Display mov A, #':' ;colon LCALL Write_Text
mov 0h, 20h ;seconds LCALL Refresh_Display
SETB EN ;moves to second half of display
CLR RS MOV P0,#0C0h LCALL WAIT_LCD CLR EN mov A, #' ' LCALL Write_Text mov A, #'t' LCALL Write_Text mov A, #'i' LCALL Write_Text mov A, #'m' LCALL Write_Text mov A, #'e' LCALL Write_Text mov A, #'r' LCALL Write_Text jmp TimerModeLoop StartStop:
jb MOM1, $ ;wait for button release
jb 40h, Stop ;check StartStop bit to know weather to start or stop
setb 40h ;changes StartStop bit
mov Acc, 22h ;checks to see if timer has run out jnz Skip1
mov Acc, 21h jnz Skip1 mov Acc, 20h
jz TimerModeLoopL ;won't start the timer if there is no time on it Skip1:
SETB TR1 ;starts timer
jmp TimerModeLoop Stop:
clr 40h ;changes start/stop bit
CLR TR1 ;stops the timer
ResetTimer:
jb MOM2, $ ;wait for button release
clr TR1 ;stops the timer
clr 40h ;changes the start stop bit
mov 20h, #00h ;resets seconds to zero and ther rest to default mov 21h, R5 mov 22h, R6 jmp TimerModeLoop TimerModeLoopL: ljmp TimerModeLoop ChronoMode: jb MOM1, StartStopC jb MOM2, ResetChronoL jb MOM0, ClockL jb LAT1, ClockL jb LAT2, ClockL jb LAT3, ClockL
;13h -> 15h Current Chrono Values mov A, 13h
cjne A, 26h, RefreshChrono ;26h = Old Chrono Value
;checks to see if display has changed and then updates jmp ChronoMode
ResetChronoL: ljmp ResetChrono ClockL:
jb MOM0, ClockL ;wait for button release
mov 26h, #0FFh ;sets old instant timer value so display will be refresed ;when they switch the mode back
ljmp Clock RefreshChrono:
;LCALLClear_LCD LCALL Cursor_Home
mov 26h, 13h ;updates old chrono value since we are refreshing mov 0h, 15h
LCALL Refresh_Display ;write hours to display mov A, #':'
LCALL Write_Text ;colon
mov 0h, 14h
LCALL Refresh_Display ;write minutes to display mov A, #':'
LCALL Write_Text ;colon
mov 0h, 13h
LCALL Refresh_Display ;write seconds to display
SETB EN ;moves to second half of display
CLR RS MOV P0,#0C0h LCALL WAIT_LCD CLR EN mov A, #' ' LCALL Write_Text mov A, #'c' LCALL Write_Text mov A, #'h' LCALL Write_Text mov A, #'r' LCALL Write_Text mov A, #'o' LCALL Write_Text mov A, #'n' LCALL Write_Text mov A, #'o' LCALL Write_Text jmp ChronoMode StartStopC:
jb MOM1, $ ;wait for button release
jb 43h, StopC ;check to start or stop timer
setb 43h ;chrono start stop bit
jmp ChronoMode StopC:
clr 43h
mov TMR3CN, #00h ;stops timer 3 jmp ChronoMode
ResetChrono:
jb MOM2, $ ;wait for button release
mov TMR3CN, #00h ;stops timer 3
clr 43h ;changes the startstop bit
mov 13h, #00h mov 14h, #00h mov 15h, #00h jmp ChronoMode jmp ChronoMode RefreshClock: mov A, R7
cjne A, 0Fh, Refresh ;check to see if display has changed jmp ExitRC
Refresh:
mov 0Fh, R7 ;updates old time counter LCALL Clear_LCD LCALL Cursor_Home ;hours mov 0h, R2 LCALL Refresh_Display mov A, #':' ;colon LCALL Write_Text ;minutes mov 0h, R1 LCALL Refresh_Display mov A, #':' ;colon
LCALL Write_Text ;seconds mov 0h, R7 LCALL Refresh_Display ExitRC: RET Refresh_Set:
mov A, 10h ;compare 0Ah and 10h
cjne A, 0Ah, ContinueUpdate
mov A, 11h ;compares 0Bh and 11h
cjne A, 0Bh, ContinueUpdate jmp ExitRS
ContinueUpdate: ;uses display bytes (this timer used for multiples sets)
mov 10h, 0Ah ;updates old values because display is refeshing mov 11h, 0Bh LCALL Clear_LCD LCALL Cursor_Home mov 0h, 0Bh ;hours LCALL Refresh_Display mov A, #':' ;colon
LCALL Write_Text ;write the acc to display ;minutes mov 0h, 0Ah LCALL Refresh_Display mov A, #' ' LCALL Write_Text mov A, #'S' LCALL Write_Text mov A, #'e' LCALL Write_Text
SETB EN ;moves to second half of display
CLR RS
MOV P0,#0C0h LCALL WAIT_LCD CLR EN
mov A, #'t'
LCALL Write_Text
mov A, 12h ;12h = Set display mode byte dec A
jz Display_Clock ;choses to write Set Clock, Set Alarm, or Set Timer ;subb A, #01h dec A jz Display_Timer ;subb A, #01h dec A jz Display_Alarm Display_Alarm: mov A, #' ' LCALL Write_Text mov A, #'A' LCALL Write_Text mov A, #'l' LCALL Write_Text mov A, #'a' LCALL Write_Text mov A, #'r' LCALL Write_Text mov A, #'m' LCALL Write_Text jmp ExitRS Display_Timer: mov A, #' ' LCALL Write_Text mov A, #'T' LCALL Write_Text mov A, #'i' LCALL Write_Text mov A, #'m' LCALL Write_Text mov A, #'e' LCALL Write_Text mov A, #'r' LCALL Write_Text jmp ExitRS
Display_Clock: mov A, #' ' LCALL Write_Text mov A, #'C' LCALL Write_Text mov A, #'l' LCALL Write_Text mov A, #'o' LCALL Write_Text mov A, #'c' LCALL Write_Text mov A, #'k' LCALL Write_Text jmp ExitRS ExitRS: RET ;---; Interupts Code
;---Timer0_Int: ;Alarm Timer
push Acc push B push PSW push 00h
MOV TH0,#0E7h ;High byte of timer0 0E7h (perfect annoying alarm pitch) MOV TL0,#000h ;Low byte of timer0, 00h
jnb LAT0, AlarmOff ;if alarm LAT is turned off, turn off alarm
djnz 0Dh, Alarming ;probably need to change this******* mov 0Dh, #0FFh
dec 0Eh ;decriments alarm time byte and checks it
mov Acc, 0Eh jz AlarmOff
Alarming:
djnz 2Bh, Flash
cpl 45h ;turns the beeps on and off
Flash:
jb 45h, Exit0 ;turns beeps on and off
jb 46h, TurnOn ;ocilates the sound
;Turn Off cpl 46h ;cpl P0.0
mov DAC0L, #00h ; DAC0 Low Byte Register mov DAC0H, #00h ; DAC0 High Byte Register mov DAC1L, #00h ; DAC0 Low Byte Register mov DAC1H, #00h ; DAC0 High Byte Register jmp Exit0
TurnOn: cpl 46h
mov DAC0L, #00h ; DAC0 Low Byte Register mov DAC0H, #016h; DAC0 High Byte Register mov DAC1L, #00h ; DAC0 Low Byte Register mov DAC1H, #016h; DAC0 High Byte Register jmp Exit0
AlarmOff:
clr TR0 ;turns alarm timer off
clr 42h clr 44h jmp Exit0 Exit0: pop 00h pop PSW pop B pop Acc RETI
Timer1_Int: ;Count Down Timer push Acc push B push PSW push 00h djnz 0Ch, Exit1
mov 0Ch, #20 ;makes it run 20 times (1 sec) mov Acc, 22h ;checks to see if timer has run out jnz Skip mov Acc, 21h jnz Skip mov Acc, 20h jz TimerAlarm Skip:
mov Acc, 20h ;only time seconds would be zero without the decriment getting it is
jz ZeroSeconds ;the first run, so this only applies to then
djnz 20h, Exit1 ;problem seconds can still be zero********(I think it is fixed) ZeroSeconds:
mov Acc, 21h jz CheckHour
dec 21h ;if seconds are zero decriment minutes
mov 20h, #59 ;reset seconds to 59
jmp Exit1 CheckHour:
mov Acc, 22h jz Exit1
dec 22h ;if minutes are zero also decriment hours
mov 21h, #59 ;resets minutes to 59
mov 20h, #59 ;resets seconds to 59
jmp Exit1 TimerAlarm:
CLR TR1 ;stops timer
setb TR0 ;starts alarm timer
mov 0Eh, #80h ;sets alarm time (time unknown)****************
setb 42h ;sets timer alarm bit
Exit1:
MOV TH1,#076 ;High byte of timer 1/20th of a second
MOV TL1,#01 ;Low byte of time1
pop 00h
pop PSW
pop B
pop Acc
RETI
Timer2_Int: ;Clock Timer
mov T2CON, #004h ;resets overflow bit push Acc
push B push PSW push 00h
djnz 08h, Exit2 ;makes timer run 20 times (1 sec) (wait for 20 overflows) mov 08h, #20 ;so timer will run 20 times (20 * 1/20sec = 1 sec)
mov Acc, #01h ;counts one sec
add A, R7 ;adds one sec to R0
mov R7, Acc mov Acc, #60 subb A, R7 jz IncMin jmp CheckAlarm IncMin:
mov R7, #0h ;clears the seconds
mov Acc, #1h add A, R1
mov R1, Acc ;adds one minute to R1
mov Acc, #60 subb A, R1 jz IncHour jmp CheckAlarm IncHour:
mov R1, #00h ;clears the minutes
mov Acc, #1h add A, R2
mov R2, Acc ;adds one hour to R2
mov Acc, #24 subb A, R2 jz ClearHour
jmp CheckAlarm ClearHour:
mov R2, #00h jmp CheckAlarm CheckAlarm:
jnb LAT0, Exit2 ;checks alarm enable lat, if not set, no alarm jb 42h, Exit2 ;checks to see if alarm is going off already mov A, R1
cjne A, 03h, Exit2 ;R3
mov A, R2
cjne A, 04h, Exit2 ;R4
setb TR0 ;starts alarm timer
mov 0Eh, #80h ;sets alarm time (time unknown)****************
setb 44h ;sets timer alarm bit
jmp Exit2 Exit2: pop 00h pop PSW pop B pop Acc RETI
Timer3_Int: ;chrono timer
anl TMR3CN, #04h ;resets overflow bit push Acc
push B push PSW push 00h
djnz 27h, Exit3
mov 27h, #20 ;makes it run 20 times (1 sec)
mov Acc, #01h ;counts one sec
add A, 13h ;adds one sec to 13h
mov 13h, Acc mov Acc, #60 subb A, 13h jz IncMinC
jmp Exit3 IncMinC:
mov 13h, #0h ;clears the seconds
mov Acc, #1h
add A, 14h
mov 14h, Acc ;adds one minute to 14h
mov Acc, #60 subb A, 14h jz IncHourC jmp Exit3 IncHourC:
mov 14h, #00h ;clears the minutes
mov Acc, #1h
add A, 15h
mov 15h, Acc ;adds one hour to 15h
mov Acc, #99 subb A, 15h jz ClearHourC jmp Exit3 ClearHourC: mov 15h, #00h jmp Exit3 Exit3: pop 00h pop PSW pop B pop Acc RETI ;---; LCD CODE ;---Refresh_Display: ;mov 0h, 0Bh
push 0h ;saves 0h for the ones position mov A, R0
mov B, #10
div AB ;acc will now store the "tens" position of the number add A, #16h ;maps "0" to mem address 16h and "9" to mem address 1Fh
mov A, @R0 ;puts the 10's value for seconds in the acc LCALL Write_Text
;mov 0h, 0Bh
pop 0h ;gets 0h again for ones position
mov A, R0 mov B, #10 div AB
mov A, B ;keeps remainder or the one's position add A, #16h
mov R0, Acc
mov A, @R0 ;indirect adresses the ones value (for the display) to the acc LCALL Write_Text RET WRITE_TEXT: SETB EN SETB RS clr RW MOV P0, A LCALL WAIT_LCD CLR EN RET init_lcd: SETB EN CLR RS clr RW
MOV P0, #38h ;sets 8bit input, 1 line display, and 5x7 dots LCALL WAIT_LCD
CLR EN ;30 old
LCALL WAIT_LCD SETB EN
CLR RS
MOV P0, #0Eh ;turne display on and cursor on LCALL WAIT_LCD
LCALL WAIT_LCD SETB EN
CLR RS
MOV P0, #06h ;display not shifted, and incriments LCALL WAIT_LCD CLR EN LCALL WAIT_LCD LCALL CLEAR_LCD RET CLEAR_LCD: SETB EN CLR RS clr RW MOV P0,#01h CLR EN LCALL WAIT_LCD RET CURSOR_HOME: SETB EN CLR RS clr RW MOV P0,#02h CLR EN LCALL WAIT_LCD RET WAIT_LCD:
;SETB EN ;Start LCD command
;CLR RS ;It's a command
;SETB RW ;It's a read command
;MOV P0, #07Fh ;Set all pins to FF initially ;MOV A, P0 ;Read the return value
;CLR EN ;Finish the command
;NL ACC,#40H ;Erase all bits but bit 7
;CLR RW ;Turn off RW for future commands mov R0, #00h djnz R0, $ mov R0, #00h djnz R0, $ mov R0, #00h djnz R0, $ mov R0, #00h djnz R0, $ mov R0, #00h djnz R0, $ mov R0, #00h djnz R0, $ mov R0, #00h djnz R0, $ mov R0, #00h djnz R0, $ RET END