📄 51bot42c.asm
字号:
; 51Bot42c - Reading an TV IR Remote Control and Running the
; 61Bot Motors and Controlling the Speed of the Motors.
;
;
; This Application will Read the Incoming I/R Commands.
;
; A Sony TV Remote Control is Used.
;
;
; I/R Data (Repeated Every 45 msec):
;
; -------+ +----+ +----+ +----+
; | | | | | | |
; | | | | | | o o o
; +--------------+ +--------+ +----+
;
; | | | | | |
; | Start Bit | |"0" Bit | |"1" |
; | < 3 msec | | 1 msec | |<1 |
; |High| > 1.5 | |msec|
; |<0.5| msec |
; |msec|
;
;
; This Application Uses the 75.76 KHz Interrupt Signal for a Motor PWM
; Output.
;
; For PROG42, the LED will be used instead of a Motor PWM Control.
;
; Timer 1 Interrupt Rate: 75.76 KHz (for a 18.94 KHz PWM Frequency)
;
; Serial Interface Speed: 2400 bps (Actually)
;
; 51Bot42a - Change the Initial and "Off" Value to Not use the PWM
; 51Bot42b - Run the PWM at 1/2 Value to See How it works
; 51Bot42c - Add the PWM Speed to the Motors
;
; I/R Values:
IR2 EQU 017EFh ; "2" on Remote Control
IR4 EQU 013EFh ; "4" on Remote Control
IR6 EQU 015EFh ; "6" on Remote Control
IR8 EQU 011EFh ; "0" on Remote Control
IRPower EQU 0156Fh ; "Power" Key on Remote Control
;
; Myke Predko
; 98.03.25
;
; Hardware Notes:
; AT89C2051 is used as the Microcontroller
; - Oscillator Speed is 20 MHz
; Wheel PWM Control is at P1.3
; Left Motor Control 1 is at P1.6
; Left Motor Control 2 is at P1.2
; Right Motor Control 1 is at P1.7
; Right Motor Control 2 is at P1.4
; LED Control is at P1.5
;
; Left I/R Receiver At P3.2 (_Int0)
; Right I/R Receiver At P3.3 (_Int1)
; Constant Declarations
TimerReload EQU 0EAh ; Value to Reload the Timer With
; Variable Declarations
define OnCount=R3 ; Use Registers for PWM Variables
define OffCount=R4
Flags EQU 020h ; Current Operation Flags
OffValue EQU 021h ; Note that Bit 2 is used to check for 4
IRState EQU 0 ; Set When Reading I/R Data
IRComplete EQU 1 ; Set When Finished with I/R Read
IRButton EQU 030h ; Value Read In (2 Bytes)
IRCount EQU 032h ; Number of Bits to Read
OnValue EQU 033h ; Reload Value for the PWM "On"
; Macros
; Mainline
org 0 ; Execution Starts Here
ajmp MainLine ; Jump Over to the Mainline
org 003h ; Interrupt Pin 0 - Left I/R Receiver
mov IE,#%10001011 ; Just Int 0 For Incoming Data
ajmp IRInt
org 00Bh ; Timer 0
clr IRState ; Don't Have Anything to Do Here
mov IE,#%10001101 ; Just Leave Buttons Ready for Interrupts
clr P1.3 ; Turn Off the Motors
reti
org 013h ; Interrupt Pin 1 - Right I/R Receiver
mov IE,#%10001110 ; Just Int 1 For Incoming Data
ajmp IRInt
org 01Bh ; Timer 1 (PWM and RS-232 Interrupt Handler)
Tmr1Int:
cjne OffCount,#0,PWMOff
PWMOn: ; The PWM is On
setb P1.5 ; Output a High Value
setb P1.3 ; Turn On the Motor
djnz OnCount,IntEnd ; If OnCount != 0, Then Loop Around
mov OnCount,OnValue
mov OffCount,OffValue
IntEnd:
reti
PWMOff: ; Turn off the PWM
clr P1.5 ; Output a Low Value
clr P1.3 ; Turn OFF the Motor
jb 10,IntEnd ; Is the Value Always Low?
dec OffCount ; No, Decrement the Counter
reti
IRInt: ; Handle the Button Interrupt
jb IRState,IRRead ; If IRState Set, Then Executing Interrupt
; Else, Have to Set up for a New Interrupt
setb IRState ; Set the IR State Interrupt
clr IRComplete ; Don't Have a Valid Value
mov IRButton,#0 ; Clear the I/R Button
mov IRButton+1,#0
mov IRCount,#12 ; Going to Read 12 Going Lows
mov TL0,#0 ; Going to Delay 4 msec for End of Start Pulse
mov TH0,#LOW(256 - 26)
clr TCON.5 ; Clear the Tmr0 Overflow Flag
reti ; Return to Mainline
IRRead: ; Now, Read the Value
push ACC ; Save the Accumulator
clr C
mov A,TH0 ; Load the Timer Value and Set According to Time Remaining
subb A,#(256 - 4) ; Have we Waited 8 or 11 Cycles?
mov A,IRButton
rlc A
mov IRButton,A
mov A,IRButton+1 ; Remember it is a 16 Bit Value
rlc A
mov IRButton+1,A
mov TL0,#0 ; Wait Up to 2 msec for the Next Delay
mov TH0,#LOW(256 - 13)
dec IRCount ; Decrement the Bit Count
mov A,IRCount ; Is it equal to Zero?
jz IRDone
pop ACC ; Restore the Accumulator
reti ; Return to Executing
IRDone: ; Have Read the IR Value
setb C ; Put in the Last Set Bit
mov A,IRButton
rlc A
mov IRButton,A
mov A,IRButton+1
rlc A
mov IRButton+1,A
clr IRState ; Have Finished with the Code
setb IRComplete ; Indicate that the Button is Ready
mov TL0,#0 ; Run for 1/10th of a Second
mov TH0,#0
pop ACC
reti ; Return to the Mainline
MainLine: ; Mainline of the Program
mov P1,#%00100011 ; Turn Off the Motors Initially
clr IRState ; Clear the Flags Variables
clr IRComplete
mov OffValue,#2 ; Start with the PWM Half On All the Time
mov OffCount,#2
mov OnValue,#2
mov OnCount,#2
mov SCON,#%01010000 ; Run Serial Port in 8 Bit Mode
mov TMOD,#%00100001 ; Timer0 - Uses Internal Clock
; - Run in Mode 1
; Timer1 - Uses Internal Clock
; - Run in Mode 2
mov TH1,#TimerReload ; Enable Timer1 To Reload 32x 2400
mov TL1,#TimerReload
mov TCON,#%01010101 ; Start Timer0 & Timer1 running
; Make Edge Triggered Interrupts
anl PCON,#07Fh ; Make Sure SMOD is Reset
mov IE,#%10001101 ; Enable Int 0 & 1 Pin
; AND Timer1 Interrupt
Loop: ; Loop Around Here
jnb IRComplete,Loop ; Nothing to Handle
mov A,IRButton ; Now, Do we Have the Number "2"?
cjne A,#LOW(IR2),Test4 ;
mov A,IRButton+1
cjne A,#HIGH(IR2),Test4
acall Forward ; Go Forward
ajmp Loop
Test4: ; Check for "4" Pressed (and Turn Left)
mov A,IRButton ; Now, Do we Have the Number "2"?
cjne A,#LOW(IR4),Test6 ;
mov A,IRButton+1
cjne A,#HIGH(IR4),Test6
acall Left ; Turn Left
ajmp Loop
Test6: ; Check for "6" Pressed (and Turn Right)
mov A,IRButton ; Now, Do we Have the Number "2"?
cjne A,#LOW(IR6),Test8 ;
mov A,IRButton+1
cjne A,#HIGH(IR6),Test8
acall Right ; Turn Right
ajmp Loop
Test8: ; Check for "8" Pressed (and Go Backwards)
mov A,IRButton ; Now, Do we Have the Number "2"?
cjne A,#LOW(IR8),Loop ; - If Not Pressed, Go Back
mov A,IRButton+1
cjne A,#HIGH(IR8),Loop
acall Backward ; Go Backwards
ajmp Loop
Stop: ; Stop the Motors
mov P1,#%00100011 ; Turn Off the Motors
ret
Left: ; Turn Left
mov A,#%00100011 ; Clear the P1 Bits NOT Doing Motion
anl A,P1
orl A,#%11001000 ; Enable the Robot to Go Forwards
mov P1,A
ret
Right: ; Turn Right
mov A,#%00100011 ; Clear the P1 Bits NOT Doing Motion
anl A,P1
orl A,#%00011100 ; Enable the Robot to Go Forwards
mov P1,A
ret
Backward: ; Go Backwards
mov A,#%00100011 ; Clear the P1 Bits NOT Doing Motion
anl A,P1
orl A,#%01011000 ; Enable the Robot to Turn Right
mov P1,A
ret
Forward: ; Go Forward
mov A,#%00100011 ; Clear the P1 Bits NOT Doing Motion
anl A,P1
orl A,#%10001100 ; Enable the Robot to Turn Right
mov P1,A
ret
LED_ON: ; Turn On the LED
clr P1.5 ; Clear the LED Bit
ret
LED_OFF: ; Turn OFF the LED
setb P1.5
ret
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -