⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 prog43.asm

📁 包括了各种常用的8051单片机的程序
💻 ASM
📖 第 1 页 / 共 2 页
字号:
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 + -