Tutorial Microcontroller MCS-51 ATMEL ISP

Pelatihan Mikrokontroller
15 Januari 2011

Microcontroller Kits
Programmer and Target 89s51

Simple Mikrokontroller 89s51 Trainer


Standart
Mikrokontroller 89s51 Trainer


Super Mikrokontroller Trainer 89s51

All Kits

+

Include

Programmer
via USB

 

 

BACK

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