![]() |
||||||
| Pelatihan
Mikrokontroller Microcontroller Kits Simple
Mikrokontroller 89s51 Trainer + Include |
The Microcontroller Assembly Code
; started 1/8/01/ltm speed.asm
; Copyright 2000 - Lawrence T. Mazza
; assembly code for the 89C2051
; motor speed control
;
; 1/08/01 s1.asm - first version
; speed control is achieved by pulsing the FETs
; input value is % on time
; direction control is with H-bridge
; a brake can be utilized by turning on the pair
; of P- or N-channel fets
; 7 bit input for speed (1-100 used as percent)
; 1 bit input for direction (1=forward)
; 1 bit input for brake enable (1=brake)
; 4 bit output for motor control FETs
; 2 bit input for mode:
; 00 - binary input, 0-100 percent
; 01 - binary input, 100-0-100 percent for pot
; 10 - R/C input on bit 0
; 1/09/01 s2.asm - changed to fixed window
; cycle is set at 1 millisecond. the motor goes on
; depending on the input bits. after that, it goes
; off for the remainder of the window
; 2/16/01 can't remove all the processor overhead, so any
; value over 95% is considered full power. also,
; there is a 15 usec length offset on all pulses.
; set up motor outputs as active high. using npn/pnp
; transistors to drive fets to run high voltage motor.
; 2/23/01 s3.asm - added 100-0-100 control
; 2/26/01 s4.asm - re-write of s2.asm
; fewer calls to reduce overhead
;
; ============= primary controls ===================
$MOD51
$TITLE(speed.asm)
$PAGEWIDTH(132)
$NOPAGING
; ============= timing dwells and counters =============
;values yield 1 millisecond interrupts using 12.0000 MHz XTAL
th1_val EQU 0FCh ;value for t1 high byte
tl1_val EQU 028h ;value for t1 low byte
; ============= register declarations ==================
mode_byte SET r0 ;holds the current mode
on_reg SET r1 ;motor on dwell
timer1 SET r2 ;timer/counter register
timer2 SET r3 ;timer/counter register
temp1 SET 010h ;temp storage
temp2 SET 011h ;temp storage
hold_a SET 012h ;place to store accumulator
bit_reg SET 013h ;holds the speed bits
; ============= constant declarations ================
on_full EQU 95d ;more than this, on full
pudelay EQU 15d ;power up delay for LCD to init (ms)
stack EQU 40h ;start addr of stack pointer
tick_time EQU 01h ;wait time for on/off frequency
; ============= port declarations =====================
d0 SET 090h ;p1.0 data bit 0, R/C input
d1 SET 091h ;p1.1 data bit 1
d2 SET 092h ;p1.2 data bit 2
d3 SET 093h ;p1.3 data bit 3
d4 SET 094h ;p1.4 data bit 4
d5 SET 095h ;p1.5 data bit 5
d6 SET 096h ;p1.6 data bit 6
dir SET 097h ;p1.7 direction bit, 1=forward
mode0 SET 0B0h ;p3.0 mode bit
mode1 SET 0B1h ;p3.1 mode bit
brakeen SET 0B2h ;p3.2 brake enable, 1=en
nfet2 SET 0B3h ;p3.3 right nfet in schematic
pfet2 SET 0B4h ;p3.4 right pfet
nfet1 SET 0B5h ;p3.5 left nfet
pfet1 SET 0B7h ;p3.7 left pfet
; ========================================
ORG 0000h ;reset starts here
base: jmp main ;jump over interrupt area
; ========================================
ORG 0003h ;external interrupt 0 vector
xint0: clr tr0
reti
; =========================================
ORG 000Bh ;tf0 inrpt table starts here
timer0_int: jmp timer0_more ;needs more room
; =========================================
purge_reti: reti ;used to clear a reti
;=========================================
ORG 001Bh ;tf1 inrpt table starts here
timer1_int: call loadt1 ;reload the timer
setb c ;set the carry flag
reti ;return from interrupt
; Copyright 2001 Lawrence T Mazza =================
ORG 00E0h
DB 001h, 020h
DB 043h, 06Fh, 070h, 079h, 072h, 069h, 067h, 068h, 074h
DB 020h, 032h, 030h, 030h, 031h
DB 04Ch, 061h, 077h, 072h, 065h, 06Eh, 063h, 065h, 020h
DB 054h, 020h, 04Dh, 061h, 07Ah, 07Ah, 061h
; ==========================================
ORG 0100h ;let's start the program here
; ===========================================
loadt1: mov th1, #th1_val ;load timer0 with byte values that
mov tl1, #tl1_val ;yield .001sec pulses @ XTAL speed
ret
; ===========================================
setup: ;sets all vars and output pins to idle condition
set_ports: mov P1, #0FFh ;set data port high
;p1.7 is mode0 bit
;p3.0 mode0 1 control
;p3.1 dir 1 direction
;p3.2 brake 1 off
;p3.3 nfetrt 0 off
;p3.4 pfetrt 0 off
;p3.5 nfetlt 0 off
;p3.6 none 0 off
;p3.7 pfetlt 0 off
mov P3, #07h ;set P3 - 0000 0111 set_regs: mov timer1, #pudelay ;load the p/u timer variable set_timers: setb ea ;allow interrupt enables
setb et1 ;enable timer1 interrupt flag
mov tmod, #11h ;set trs to 16-bit
mov tcon, #00h ;clear all timers
call loadt0 ;load the timers
call loadt1
ret
; ==========================================
tick: mov timer1, #tick_time ;small time to wait
call loadt0 ;reset the timer
tick_wait: mov a, timer1
jnz tick_wait ;wait until done
ret
; ==========================================
forward: clr pfet1 ;make sure other pfet is off
setb pfet2 ;turn on the + side
setb nfet1 ;turn on the - side
ret
; ===========================================
reverse: clr pfet2 ;make sure other pfet is off
setb pfet1 ;turn on the + side
setb nfet2 ;turn on the - side
ret
; ============================================
off: clr et1 ;disable the timer interrupt
clr pfet1 ;turn off the left pfet
clr pfet2 ;turn off the right pfet
clr nfet1 ;turn off the left nfet
clr nfet2 ;turn off the right nfet
ret
; ===========================================
chop: ;only chop nfet because it can
;handle the switching
clr nfet1 ;turn off the left nfet
clr nfet2 ;turn off the right nfet
ret
; ===========================================
brake: setb nfet1 ;turn on the left nfet
setb nfet2 ;turn on the right nfet
ret
; ===========================================
wait_10: ;10 u-sec dwell period
nop
nop
nop
dec a ;decrement the bit count
ret
; ===========================================
main: mov sp, #stack ;set the stack
call setup ;set everything up
power_up: setb tr1 ;start timer1
; ===========================================
main_loop:
running: mov a, P1 ;get the speed bits
anl a, #7Fh ;remove direction bit
jz stop ;if bits=0, then brake
mov c, mode0 ;get mode bit
jc left_right ;go to two sided mode
on: mov c, dir ;get the direction bit
jc go_forward ;+ means forward or +100
go_reverse: cjne a, #on_full, ch_high_r
full_rev: clr et1 ;disable the timer interrupt
call reverse
jmp running ;don't chop at all
ch_high_r: jnc full_rev ;if higher, c=0, put full on
setb et1 ;enable the timer interrupt
call reverse
jmp motor_on ;start the chopping process
go_forward: cjne a, #on_full, ch_high_f
full_for: clr et1 ;disable the timer interrupt
call forward
jmp running ;don't chop at all
ch_high_f: jnc full_for ;if higher, c=0, put full on
setb et1 ;enable the timer interrupt
call forward
jmp motor_on ;start the chopping process
left_right: mov c, dir ;get direction bit (high bit in this case)
jc go_forward ;same as forward mode
cpl a ;reverse mode requires backward bits
anl a, #7Fh ;clear the direction bit
jmp go_reverse ;go do a reverse loop
motor_on:
nop
nop
nop
nop
nop
nop
nop
dec a
jnz motor_on ;if not 0, do it again
call chop ;turn off the fets
clr c ;clear the carry bit
motor_chop: jnc motor_chop ;wait until the window closes
jmp running ;run another loop
stop: call off ;turn off all fets
mov c, brakeen ;get the brake enable bit
jnc running ;0, so don't brake, just coast
apply_brake:call brake ;turn on both nfets
ch_zero: mov a, P1 ;get the input bids
anl a, #7Fh ;remove the direction bit
jz ch_zero
jmp running ;go look again
; ==========================================
END
Comments,
questions and discussion about this topic
|
|
||||