📄 prog43.asm
字号:
TempTask EQU 012h ; Temperature Task Number
TimeLo EQU 013h ; 24 Bit Counter Value
TimeHi EQU 014h
TimeFrac EQU 015h
Hours EQU 016h ; Actual Time
Minutes EQU 017h
Seconds EQU 018h
Increment EQU 019h ; Increment Value
TempWait EQU 01Ah ; Wait 2 Seconds for Each Temperature Update
TempCount EQU 01Bh ; Bit Counter for the Temperature
TempSP0 EQU 01Ch ; Data Written to/Read from the DS1820
TempSP1 EQU 01Dh
TempDlay EQU 01Eh ; Delay Value for DS1820 Operations
Application: ; Simple Test Application
mov CKCON,#%00001000 ; Use Internal /4 Clock for Timer0
mov TMOD,#%00000001 ; Timer0 - Uses Internal Clock
; - Run in Mode 1
mov TCON,#%00010101 ; Start Timer0 running
StartTask (LCDTaskStart,#0C0h); Start the LCD Task
mov LCDTask,R0
StartTask (TimeTaskStart,#000h); Start the Time Task
mov TimeTask,R0
StartTask (TempTaskStart,#040h); Start the Temperature Task
mov TempTask,R0
EndTask ; End the Application Task and Let Other Tasks Execute
TimeTaskStart: ; The beginning of the Timer Task
mov Hours,#0 ; Initialize the RTC Values
mov Minutes,#0
mov Seconds,#0
SendMsg (LCDTask,#10) ; Send an LCD Time Update Request
mov TimeLo,#0 ; The 24 Bit Second Fraction
mov TimeHi,#0
mov TimeFrac,#0
mov Increment,#1 ; Only Increment By 1 (Button To Change)
TimeTaskLoop: ; Loop Around Here once each Second
WaitInt(1) ; Wait 65,536 usecs
inc TimeFrac ; Increment the Current Fraction of a Second
mov A,TimeFrac ; Have we Counted 16x?
cjne A,#16,TimeTaskLoop ; If we Don't have 16, then "no"
mov A,TimeLo ; Take 1,000,000 From the Current Seconds
clr C
subb A,#040h
mov TimeLo,A
mov A,TimeHi ; Now, Subtract the Middle 8 Bits
subb A,#042h
mov TimeHi,A
mov A,TimeFrac ; Reset the Time Fraction
subb A,#00Fh ; Take Away 15 From the Fraction
mov TimeFrac,A
inc Seconds ; Increment the Seconds
jb P1.0,TimeSecCheck ; If P1.0 is Time Set Button
mov Seconds,#60 ; If the Button is Pressed, Increment the Minutes
TimeSecCheck: ; Check to See if the Seconds are > 59
mov A,Seconds
clr C
subb A,#60 ; Do we Have 60 Seconds?
jnc TimeMinIncrement ; If Carry Set, then No
mov Increment,#1 ; Reset The Increment Value to the Start Value
ajmp TimeTaskLoop ; Wait another Second
TimeMinIncrement:
mov Seconds,#0 ; Reset the Seconds
mov A,Increment ; Update the Minutes
add A,Minutes
mov Minutes,A
clr C ; Are Minutes > 59?
subb A,#60
jc TimeDisplay ; If Carry Set, No - Display the Time
mov Minutes,#0
inc Hours ; Increment the Hours
mov A,Hours ; Have we Looped Around?
clr C
subb A,#24
jc TimeDisplay
mov Hours,#0 ; Reset the Hours
TimeDisplay: ; Update the LCD's Time Display
SendMsg (LCDTask,#10) ; Send an LCD Time Update Request
jb P1.0,TimeTaskLoop ; If the Button is High, Then Return
mov A,Increment ; Set a New Increment Value
setb C ; Want to Move Up to 63 on the Increments
rlc a
anl A,#03Fh ; Leave with no more than 63 for the Increment
mov Increment,A
ajmp TimeTaskLoop
TempTaskStart: ; The beginning of the DS1820 Temperature Sensor Task
mov TempWait,#0 ; Reset TempWait
TempTaskLoop: ; Loop Around Here for Each Task
WaitInt (1) ; Going To Wait 2 Seconds before Executing
inc TempWait ; Increment the Wait Variable
mov A,TempWait ; Have we Gone 2 Seconds Yet?
cjne A,#32,TempTaskLoop ; If Not Equal to 32, Then Loop Around Again
mov TempWait,#0
acall DSReset ; Reset the DS1820
mov A,#0CCh ; Start the Temperature Read Operation
acall SendDS
mov A,#044h
acall SendDS
mov TempDlay,#078h ; Wait for the Operation to Execute
TempWait1:
djnz TempDlay,TempWait1
acall DSReset ; Now, Read the Temperature
mov A,#0CCh
acall SendDS
mov A,#0BEh
acall SendDS
mov TempDlay,#01Eh
TempWait2:
djnz TempDlay,TempWait2
acall GetDS
mov TempSP0,A
mov TempDlay,#01Eh
TempWait3:
djnz TempDlay,TempWait3
acall GetDS
mov TempSP1,A
mov TempDlay,#01Eh
TempWait4:
djnz TempDlay,TempWait4
acall DSReset ; Reset the DS1820
SendMsg (LCDTask,#4)
ajmp TempTaskLoop
DSReset: ; Reset the DS1820
clr P0.1 ; Drop the DS1820's Line
mov TempDlay,#078h ; Wait 480 usecs
DSResetWait1:
djnz TempDlay,DSResetWait1
setb P0.1
DSResetWait2: ; Now, Wait 1 msec
djnz TempDlay,DSResetWait2
ret
SendDS: ; Send the Byte in "A" to the DS1820
mov TempCount,#8 ; Sending 8 Bits
clr IE.7 ; Disable Interrupts During this Operation
SendDSLoop: ; Loop Here for Each Bit
rrc a ; Put the LSB into the Carry Flag
clr P0.1 ; Drop the Line Low
jnc SendDSDlay ; Do we Delay the Line low?
setb P0.1 ; No, Sending a "1"
SendDSDlay: ; Delay 30 Instruction Cycles before Setting Pin
mov R0,#9
SendDSWait:
djnz R0,SendDSWait
setb P0.1
mov R0,#7 ; Wait 21 Cycles before sending the next bit
SendDSWait2:
djnz R0,SendDSWait2
djnz TempCount,SendDSLoop
setb IE.7 ; Enable Interrupts Again
ret
GetDS: ; Get 8 Bits from the DS1820
mov TempCount,#8 ; Sending 8 Bits
clr IE.7 ; Disable Interrupts During this Operation
GetDSLoop: ; Loop Here for Each Bit
clr P0.1 ; Toggle the I/O Pin
setb P0.1
nop
setb C ; Now, See what is Returned
jb P0.1,GetDSSave ; Is the Bit Still High?
clr C
GetDSSave: ; Save the Carry Flag as the Bit Read
rrc a
mov R0,#5 ; Delay 16 Cycles for the DS1820 to Reset
GetDSWait:
djnz R0,GetDSWait
djnz TempCount,GetDSLoop
setb IE.7 ; Enable Interrupts Again
ret
LCDTaskStart: ; LCD Task, Display Data on the LCD
clr P1.7 ; Turn Off the LCD Pins
clr P1.5
clr P1.4
WaitInt (1) ; Wait 20 mscec+ for the LCD to Reset
WaitInt (1)
mov P3,#030h ; Reset the LCD
setb P1.7 ; Toggle "E" Clock
clr P1.7
WaitInt (1) ; Wait for the Command to Take
setb P1.7 ; Toggle "E" Clock Again
clr P1.7
WaitInt (1) ; Delay for the Command to Complete
setb P1.7 ; Toggle "E" one Last Time
clr P1.7
WaitInt (1)
mov A,#038h ; Want an 8 Bit LCD Operation
acall SendINS
mov A,#010h ; Turn Off the LCD
acall SendINS
mov A,#001h ; Clear the LCD
acall SendINS
WaitInt(1) ; Wait 500 mSecs After Previous
mov A,#00Ch ; Turn on the Display
acall SendINS
mov A,#'T' ; Put the "Time: xx:xx XX" String on the Display
acall SendCHAR
mov A,#'i'
acall SendCHAR
mov A,#'m'
acall SendCHAR
mov A,#'e'
acall SendCHAR
mov A,#':'
acall SendCHAR
mov A,#' '
acall SendCHAR
mov A,#'x'
acall SendCHAR
mov A,#'x'
acall SendCHAR
mov A,#':'
acall SendCHAR
mov A,#'x'
acall SendCHAR
mov A,#'x'
acall SendCHAR
mov A,#' '
acall SendCHAR
mov A,#'X'
acall SendCHAR
mov A,#'X'
acall SendCHAR
mov A,#0C0h ; Put in "Temp: xxxx C"
acall SendINS
mov A,#'T'
acall SendCHAR
mov A,#'e'
acall SendCHAR
mov A,#'m'
acall SendCHAR
mov A,#'p'
acall SendCHAR
mov A,#':'
acall SendCHAR
mov A,#' '
acall SendCHAR
mov A,#'x'
acall SendCHAR
mov A,#'x'
acall SendCHAR
mov A,#'x'
acall SendCHAR
mov A,#'x'
acall SendCHAR
mov A,#' '
acall SendCHAR
mov A,#'C'
acall SendCHAR
LCDTaskLoop: ; Loop Here and Process Each Command Sent to LCD
WaitMsg ; Wait for a message to be sent to it
ReadMsg (TimeTask)
xrl A,#0FFh ; Do We Have a Message to Update the Time?
jz LCDTempRead ; No, Update the Temperature
AckMsg (TimeTask) ; Acknowledge the Message
mov A,#089h ; Display the Time
acall SendINS
mov A,Minutes ; Display the Minutes First
mov B,#10
div ab
add A,#'0'
acall SendCHAR
mov A,B
add A,#'0'
acall SendCHAR
mov A,#086h ; Now, Display the Hours
acall SendINS
mov A,Hours ; Do We Have AM or PM?
clr C
subb A,#12
jc LCDHaveHours ; AM, Live With It
subb A,#12 ; Convert to PM
LCDHaveHours: ; Now, Do we Have Noon/Midnight?
add A,#12 ; Restore To Normal Time
jnz LCDDisplayHours ; No, Display the Hours
mov A,#12
LCDDisplayHours: ; Display the Hours
mov B,#10 ; Convert to Decimal
div ab
add A,#'0'
acall SendCHAR
mov A,B
add A,#'0'
acall SendCHAR
mov A,#08Ch ; Now, Display "AM" or "PM"
acall SendINS
mov A,Hours
clr C
subb A,#12
mov A,#'A' ; Start with "AM"
jc LCDDisplayAPM
mov A,#'P'
LCDDisplayAPM:
acall SendCHAR
mov A,#'M'
acall SendCHAR
ajmp LCDTaskLoop ; Wait for the Next Request
LCDTempRead: ; Read the Temperature Passed to the Task
ReadMsg (TempTask)
mov A,#0C6h ; Move the Cursor to Temperature Part of the Display
acall SendINS
mov A,TempSP1 ; Get the Positive/Negative Temperature
mov C,ACC.0 ; Marked in Bit 0 of SP1
mov A,#' ' ; Assume Positive and Can Display
jnc LCDTempDisplay
clr A ; Invert the Temperature
clr C
subb A,TempSP0
mov TempSP0,A
mov A,#'-' ; Mark as Negative
LCDTempDisplay: ; Display the Temperature
acall SendCHAR
mov A,TempSP0 ; Now, Display the Temperature
clr C ; Divide Temperature by 2 to get Celcius
rrc A
mov B,#100 ; Get the Hundreds of Degrees
div ab
add A,#'0'
acall SendCHAR
mov A,B ; Get the tens of Degrees
mov B,#10
div ab
add A,#'0'
acall SendCHAR
mov A,B ; Display the Ones of Degrees
add A,#'0'
acall SendCHAR
AckMsg (TempTask) ; Acknowledge the Message
ajmp LCDTaskLoop
SendINS: ; Send Instruction to the LCD
setb P1.5 ; Set the RW Line
clr P1.4 ; Clear the RS Line
setb P3.7 ; Make Sure the Polling Line is High
SendINSLoop: ; Loop Here Until the LCD is Active
setb P1.7 ; Enable the "E" Flag
jnb P3.7,SendINSSkip ; If Bit 7 is Low, Send the Character
clr P1.7 ; Turn off the "E" Flag
NextTask ; Else, Loop Through the Operation
ajmp SendINSLoop
SendINSSkip: ; Now, We can Output the Character
clr P1.7 ; Turn off the "E" Bit
clr P1.5 ; Turn off the LCD Read Operation
mov P3,A ; Output the Character to Send
setb P1.7 ; Toggle the "E" Flag
clr P1.7
ret ; Return to the Caller
SendCHAR: ; Send Character to the LCD
setb P1.5 ; Set the RW Line
clr P1.4 ; Clear the RS Line
setb P3.7 ; Make Sure the Polling Line is High
SendCHARLoop: ; Loop Here Until the LCD is Active
setb P1.7 ; Enable the "E" Flag
jnb P3.7,SendCHARSkip ; If Bit 7 is Low, Send the Character
clr P1.7
NextTask ; Else, Loop Through the Operation
ajmp SendCHARLoop
SendCHARSkip: ; Now, We can Output the Character
clr P1.7 ; Turn off the "E" Flag
clr P1.5 ; Turn off the LCD Read Operation
setb P1.4 ; Send out the Character
mov P3,A ; Output the Character to Send
setb P1.7 ; Toggle the "E" Flag
clr P1.7
ret ; Return to the Caller
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -