; D:\mplab\gp16lf84\gp_0004.asm, January-23-2002, PTB. ; LIST p=16f84 include "P16F84.INC" include "d:\mplab\16f84_lc.inc" ; has lower case register names. __config _cp_off & _wdt_off & _pwrte_on & _rc_osc ; __idlocs 0xffff errorlevel -302 _opt256 equ b'00000111' ; OK, timer 1:256 _opt128 equ b'00000110' ; OK, timer 1:128 _opt64 equ b'00000101' ; OK, timer 1:64 _opt32 equ b'00000100' ; OK, timer 1:32 _opt16 equ b'00000011' ; OK, timer 1:16 _int equ b'00000000' ; OK ; 43210 a_pins equ b'11111' ; all tri-stated a_tris equ b'00000' ; all outputs, =0 ; |||||____ motor 1 enable ; ||||_____ motor 2 enable ; |||______ motor 3 enable ; ||_______ motor 4 enable ; | ; |________ tied to the 74AC245 enable pin. ; 76543210 b_pins equ b'11111111' ; 1= tri-stated b_tris equ b'11111001' ; 1= input, 0= output ; 3210FPSI s= Speed(1) = off, 0= on. ; |||||||| ; ||||||||_ ir-input ; ||||||| ; |||||||__ Speed, 0= fast, 1= slow ; ||||||___ PIEZO-OUTPUT(1) ; ||||| ; |||||____ feeler ; |||| ; ||||_____ affects _rbif ; |||______ affects _rbif ; ||_______ affects _rbif ; |________ affects _rbif bit0 equ 0 bit1 equ 1 bit2 equ 2 bit3 equ 3 bit4 equ 4 bit5 equ 5 bit6 equ 6 bit7 equ 7 #define bank0 status,rp0 #define bank1 status,rp0 #define z_flag status,z #define carry status,c #define _gie intcon,gie #define _intf intcon,intf #define _inte intcon,inte #define _t0if intcon,t0if ; timer overflow flag #define _rbie intcon,rbie #define _rbif intcon,rbif ; portb (4..7) only pin change flag #define _eeif eecon1,bit5 #define _wrerr eecon1,bit4 #define _wren eecon1,bit3 #define _wr eecon1,bit1 #define _rd eecon1,bit0 #define m1 porta,bit0 ; motor 1 - 2,3 in; 17,18 out #define m2 porta,bit1 ; motor 2 - 4,5 in; 15,16 out #define m3 porta,bit2 ; motor 3 - 6,7 in; 13,14 out #define m4 porta,bit3 ; motor 4 - 8,9 in; 11,12 out #define ena245 porta,bit4 ; --> 74AC245 OE pin #define ir_in portb,bit0 ; IR Module Input #define speed portb,bit1 ; 0= fast, 1= slow #define piezo portb,bit2 ; piezo element #define feel1 portb,bit3 ; 0= active ;edge change pins: #define limit0 portb,bit4 ; CW front rotation limit #define limit1 portb,bit5 ; CCW front rotation limit #define limit2 portb,bit6 ; CW rear rotation limit #define limit3 portb,bit7 ; CCW rear rotation limit #define mt1time .255-.210 ; front motor CW #define mt2time .255-.210 ; front motor CCW #define mt3time .255-.210 ; rear motor CW #define mt4time .255-.210 ; rear motor CCW ; the following works great! #define rt1time .255-.120 ; reverse front motor CW #define rt2time .255-.120 ; reverse front motor CCW #define rt3time .255-.180 ; reverse rear motor CW #define rt4time .255-.180 ; reverse rear motor CCW ; #define f1time .255-.254 ; fast front motor CW #define f2time .255-.254 ; fast front motor CCW #define f3time .255-.245 ; fast rear motor CW #define f4time .255-.245 ; fast rear motor CCW #define t1time .255-.120 ; turn front motor CW #define t2time .255-.150 ; turn front motor CCW #define t3time .255-.120 ; turn rear motor CW #define t4time .255-.200 ; turn rear motor CCW #define pauztim .255-.60 ; normal time between motor steps #define pz2tim .255-.10 ; shorter pause time #define pzcount .19 ; loop counter, needs odd # #define longtim .0 ; longest pause available #define walkng _action,bit0 ; b'0000000x' #define runng _action,bit1 ; b'000000x0' #define backng _action,bit2 ; b'00000x00' buncha equ 5 ; RAM RAM RAM RAM RAM RAM RAM RAM RAM ; CBLOCK 0x0C ; to 0x4F inclusive ; from EEPROM at Power-Up: _mt1time, _mt2time, _mt3time, _mt4time ; forward 0C..0F _rt1time, _rt2time, _rt3time, _rt4time ; reverse 10..13 _f1time, _f2time, _f3time, _f4time ; fast 14..17 _time1, _time2, _time3, _time4 ; setup 18..1B _action ; 0=normal, 2=fast, 4=reverse, 6=fast_reverse _loops ; reverse counter ; locals: _sqkvar, _sqkvar2, _sqkvar3, _count _timer, _rand, _temp, _pauzer, _random _goto, _goto2, _speeds, _loop _eeadr, _eedata _wtemp, _status, _wiggle, _eeloop ENDC ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ; @@@@ ; @ .@ ; @ . @ ; @ . @ ; @. @ ; @@@@ ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ; org 0 b Cold ; ;44444444444444444444444444444444 ; 4 ; 4 4 ; 4 4 ; 444444 ; 4 ; 4 ;44444444444444444444444444444444 ; org 4 ; movwf _wtemp ; save W ; swapf status,w ; move status to W (nibbles) ; movwf _status ; save status register ; ; do something here . . . ; ;Ixit swapf _status,w ; restore status register (nibbles) ; movwf status ; restores bank ; swapf _wtemp,f ; restore W (nibbles) ; swapf _wtemp,w ;_/ retfie ; ;-------------------------------- ; Cold clrf intcon movlw 0x0C ; clear out memory from 0x0C-> movwf fsr clrnxt clrf indf incf fsr ; x1xx-xxxx btfss fsr,6 ; is it 0x40 ? b clrnxt ; ->to 0x3F inclusive bsf bank1 ; yup, continue, bank 1 movlw _opt128 ; prescaler amount, 1:# movwf option_reg ;_/ movlw a_tris ; setup external pin directions movwf trisa ;_/ movlw b_tris ; setup external pin directions movwf trisb ;_/ bcf bank0 ; back to bank 0 movlw a_pins ; motors and 74ac245 off movwf porta ;_/ movlw b_pins ; slow cpu speed movwf portb ;_/ call Times ; get EEPROM data to local RAM movlw pzcount ; movwf _pauzer ;_/ clrf intcon ; no interrupts clrf tmr0 ; start timer after 2 cycles call RandNum andlw b'00001111' ; limit # to 0..16 iorlw b'00001000' ; force at least 8 instead of =0 movwf _rand ;_/ movlw .6 ; update reverse cycles counter movwf _loops ;_/ bcf ena245 ; turn on the 74AC245 motor driver movlw .9-.1 ; do a sweep-up/down beep call Blips ;_/ Balance call C_Front ; center the legs, still doesn't work right call C_Back ; center the legs, still doesn't work right ; ;-------------------------------- ; Check bsf speed ; slow decfsz _rand,f ; is it time to do a 'WIGGLE' ? b NotYet ; continue with checks call Wigl ; yup call RandNum ; update next time occurance andlw b'00011111' ; limit # to 1..31 iorlw b'00001000' ;__/ movwf _rand ;_/ NotYet btfss feel1 ; did feeler hit something ? b Reverse ; yes, goto reverse routine btfsc _intf ; did ir-module go down ? b Fast ; yes, IR-Module active ! ; ; and fall into Walk . . . ;-------------------------------- ; Walk call SetNorm ; sets _action too b Forward ; DOH! Reverse call SetRev ; sets _action too b Revward Fast bcf _intf ; clear caller bcf speed ; fast call SetFast ; sets _action too movlw .10-.2 ; do dn-up-dn call Blips ;_/ ; b Forward ; implied ; ;-------------------------------- ; Forward call Mtr1cw ; rotate Motor 1 CW btfss feel1 ; is feeler up ? b r4 ; no, down, active. btfsc runng ; skip if fast b m1f call Pause ; time between motors being active m1f btfss feel1 ; is feeler up ? b r4 ; no, down, active. call Mtr2cw ; rotate Motor 2 CW btfss feel1 ; is feeler up ? b r3 ; no, down, active. btfsc runng b m2f call Pause ; time between motors being active m2f btfss feel1 ; is feeler up ? b r3 ; no, down, active. call Mtr1ccw ; rotate Motor 1 CCW btfss feel1 ; is feeler up ? b r2 ; no, down, active. btfsc runng b m3f call Pause ; time between motors being active m3f btfss feel1 ; is feeler up ? b r2 ; no, down, active. call Mtr2ccw ; rotate Motor 2 CCW btfss feel1 ; is feeler up ? b Revward ; no, down, active. btfsc runng b m4f call Pause ; time between motors being active m4f btfss feel1 ; is feeler up ? b Revward ; no, down, active. clrf _action b Check ; start over ; ;-------------------------------- ; Revward call Mtr1cw ; rotate Motor 1 CW btfsc runng ; skip time between, if fast b r4 ;_/ call OneBlip ; time between motors being active r4 call Mtr2ccw ; rotate Motor 2 CCW btfsc runng b r3 call OneBlip ; time between motors being active r3 call Mtr1ccw ; rotate Motor 1 CCW btfsc runng b r2 call OneBlip ; time between motors being active r2 call Mtr2cw ; rotate Motor 2 CW btfsc runng b rxit call OneBlip ; time between motors being active rxit decfsz _loops,f b Revward movlw .6 ; update reverse cycles counter movwf _loops ;_/ clrf _action ; walk movlw .9-.1 ; do the up/down thingie call Blips ;_/ b Check ; start over ; ;-------------------------------- ; SetNorm movlw _time1 movwf _mt1time movlw _time2 movwf _mt2time movlw _time3 movwf _mt3time movlw _time4 movwf _mt4time movlw b'00000000' ; norm forward movwf _action return SetFast movlw _f1time movwf _mt1time movlw _f2time movwf _mt2time movlw _f3time movwf _mt3time movlw _f4time movwf _mt4time movlw b'00000010' ; fast forward movwf _action return SetRev movlw _rt1time movwf _mt1time movlw _rt2time movwf _mt2time movlw _rt3time movwf _mt3time movlw _rt4time movwf _mt4time movlw b'00000100' ; norm reversing movwf _action return SetFRev movlw _rt1time movwf _mt1time movlw _rt2time movwf _mt2time movlw _rt3time movwf _mt3time movlw _rt4time movwf _mt4time movlw b'00000110' ; fast reversing movwf _action return ; ;-------------------------------- ; Mtr1cw movfw _mt1time ; for this long M1cw bcf m1 ; start motor 1 moving CW movwf tmr0 ;_/ bcf _t0if ; clear TMR0 overflow flag mt1loop btfss limit0 ; return early if b mt1xit ; limit switch is hit btfss _t0if ; wait for overflow flag to activate b mt1loop ; forever ? bcf _t0if ; yes, it flipped, now clear it mt1xit bsf m1 ; all done, so turn motor off return ;_/ ; ;-------------------------------- ; Mtr1ccw movfw _mt2time ; for this long M1ccw bcf m2 ; start motor 1 moving CCW movwf tmr0 ;_/ bcf _t0if ; clear TMR0 overflow flag mt2loop btfss limit1 ; return early if b mt2xit ; limit switch is hit btfss _t0if ; wait for overflow flag to activate b mt2loop ; forever ? bcf _t0if ; yes, it flipped, now clear it mt2xit bsf m2 ; all done, so turn motor off return ;_/ ; ;-------------------------------- ; Mtr2cw movfw _mt3time M2cw bcf m3 ; start motor 2 moving CW movwf tmr0 bcf _t0if mt3loop btfss limit2 b mt3xit btfss _t0if b mt3loop bcf _t0if mt3xit bsf m3 return ; ;-------------------------------- ; Mtr2ccw movfw _mt4time M2ccw bcf m4 ; start motor 2 moving CCW movwf tmr0 bcf _t0if mt4loop btfss limit3 b mt4xit btfss _t0if b mt4loop bcf _t0if mt4xit bsf m4 return ; ;-------------------------------- ; Flash lights & do a dance ; Wigl movlw .4 ; initialize movwf _wiggle ;_/ lpmore movlw b'00001110' ; flash lights alternately movwf porta ; 74ac245 on, hold motors call OneBlip movlw b'00001101' ; flash lights alternately movwf porta ; 74ac245 on, hold motors call OneBlip movlw b'00001011' ; flash lights alternately movwf porta ; 74ac245 on, hold motors call OneBlip movlw b'00000111' ; flash lights alternately movwf porta ; 74ac245 on, hold motors call OneBlip decfsz _wiggle,f ; this many times around b lpmore ;_/ movlw b'00001111' ; all lights & motors, out & off movwf porta ;_/ movfw portb ; read & clear edge flags return ; ;-------------------------------- org 0x100 ; ; Center the front legs ; C_Front movlw .0 ; pseudo-forever call M1cw ; find switch rrf tmr0,w ; save the TMR0 leftover, DIV 2 andlw 0x7f ; mask rotated bit0 sublw .255 ; TMR0 counts up call M1ccw ; move halfway back ? return ; ;-------------------------------- ; Center the back legs ; C_Back movlw .0 ; pseudo-forever call M2cw ; find switch rrf tmr0,w ; save the TMR0 leftover, DIV 2 andlw 0x7f ; mask rotated bit0 sublw .255 ; TMR0 counts up call M2ccw ; move halfway back ? return ; ;-------------------------------- ; FPause movlw pz2tim b paus2 ;------- Pause movlw pauztim ; update up-counter paus2 movwf tmr0 ; start timer bcf _t0if ; make sure flag not set nop ;_/ p1 btfss _t0if ; is bit clear ? b p1 return ; ;-------------------------------- ; Beep movlw .50 ; frequency movwf _sqkvar3 ;_/ movlw .20 ; length movwf _sqkvar2 ;_/ movlw .5 ; cycles per step movwf _count ;_/ UpLoop bsf piezo ; piezo cycle, high call SweepUp ; piezo cycle, high nop nop bcf piezo ; piezo cycle, low call SweepUp ; piezo cycle, low decfsz _sqkvar2,f ; decrement #_cycles counter b UpLoop ; until #_cycles done return ; ;-------------------------------- ; SweepUp movfw _sqkvar3 ; cycles per step movwf _sqkvar ;_/ Sweep2 decfsz _sqkvar,f ; update cycles per step b Sweep2 ;_/ decfsz _count,f ; update cycle counter b Sweep3 ;when _count goes to 0, change frequency: ; movlw .5 ; reset cycles per step movwf _count ;_/ decf _sqkvar3,f ; raise frequency Sweep3 return ; ;-------------------------------- ; BeepDn movlw .50 ; frequency movwf _sqkvar3 ;_/ movlw .20 ; length movwf _sqkvar2 ;_/ movlw .5 ; cycles per step movwf _count ;_/ DnLoop bsf piezo ; piezo cycle, high call SweepDn ; piezo cycle, high nop nop bcf piezo ; piezo cycle, low call SweepDn ; piezo cycle, low decfsz _sqkvar2,f ; decrement #_cycles counter b DnLoop ; until #_cycles done return ; ;-------------------------------- ; SweepDn movfw _sqkvar3 ; cycles per step movwf _sqkvar ;_/ Sd2 decfsz _sqkvar,f ; update cycles per step b Sd2 ;_/ decfsz _count,f ; update cycle counter b Sd3 ;when _count goes to 0, change frequency: ; movlw .5 ; reset cycles per step movwf _count ;_/ incf _sqkvar3,f ; lower frequency Sd3 return ; ;-------------------------------- ; This works, finally - PTB - Dec-13-2001. ; No matter what speed it is running at, ; here it gets set to FAST, then restored ; to original before RETURNing. ; OneBlip clrw Blips movwf _goto2 ; save entry point btfss speed ; if speed = 0 then fast b blfast ; bcf _speeds,0 ; remember that I was going slow b mbcont blfast bsf _speeds,0 ; remember that I was going fast mbcont bcf speed ; always go fast DoBlip movlw high(DoBlip) ; trashes W movwf pclath ; set the PC-High movfw _goto2 ; get entry point back addwf pcl,f ; jump into table b do0 ; 1 beep b do1 ; 2 beeps b do2 ; 3 beeps b do3 ; 4 beeps b do4 ; 5 beeps b do5 ; 6 beeps b do6 ; 7 beeps b do7 ; 8 beeps b do8 ; dn-up-dn-up-dn b do9 ; dn-up-dn ; do7 call Beep ; 7 call FPause do6 call Beep ; 6 call FPause do5 call Beep ; 5 call FPause do4 call Beep ; 4 call FPause do3 call Beep ; 3 call FPause do2 call Beep ; 2 call FPause do1 call Beep ; 1 call FPause do0 call Beep ; 0 call FPause ; ; recall what speed I was at and restore it ; DoXit btfsc _speeds,0 ; if _speeds,0 =0 then slow b blfst ; else restore to fast bsf speed ; slow return blfst bcf speed ; fast return ; ;------- ; do8 call BeepDn call FPause call Beep call FPause call BeepDn call FPause call Beep call FPause call BeepDn b DoXit ; ;-------------------------------- ; do9 call BeepDn call FPause call Beep call FPause call BeepDn b DoXit ; ;-------------------------------- ; RandNum rlf _random,f rlf _random,f btfsc _random,4 xorlw 1 btfsc _random,5 xorlw 1 btfsc _random,3 xorlw 1 movwf _random return ; return with random(W) ; ;-------------------------------- ; Times movlw 0x0c ; start of RAM movwf fsr ; clear pointer clrf _eeadr movlw .18 ; bytes to get movwf _eeloop ;_/ TLoop call EErbyte ; get one byte from internal EEPROM movwf indf ; save byte into local RAM incf fsr ; next RAM byte location incf _eeadr ; next EEPROM byte decfsz _eeloop,f ; update down-counter b TLoop ; go back if not done, >0 return ; ;-------------------------------- ; EErbyte movfw _eeadr ; get preset address movwf eeadr ; write to eeprom address register bsf bank1 ; bank 1 bsf _rd ; enable read byte bcf bank0 ; bank 0 movfw eedata ; read data from eedata register return ; ;-------------------------------- ; EEwbyte movfw _eeadr ; get pre-set address movwf eeadr ; write to eeprom address register movfw _eedata ; get pre-set data byte movwf eedata ; write data to ee data register ;------- EEwrite bsf bank1 ; bank 1 bsf _wren ; enable write byte movlw 0x55 ; do this sequence for every byte movwf eecon2 ;____/ movlw 0xaa ;___/ movwf eecon2 ;__/ bsf _wr ;_/ return ; ;-------------------------------- ; ; CODEPAGE NAME=eedata START=0x2100 END=0x213F ; 64 bytes of onboard EEPROM ; ; (.255-decimal_number_wanted) for upcounter, TMR0. ; org 0x2100 de .255-.210 ; 1, front motor CW de .255-.210 ; 2, front motor CCW de .255-.210 ; 3, rear motor CW de .255-.210 ; 4, rear motor CCW de .255-.120 ; 5, reverse front motor CW de .255-.120 ; 6, reverse front motor CCW de .255-.180 ; 7, reverse rear motor CW de .255-.180 ; 8, reverse rear motor CCW de .255-.254 ; 9, fast front motor CW de .255-.254 ; 10, fast front motor CCW de .255-.245 ; 11, fast rear motor CW de .255-.245 ; 12, fast rear motor CCW de .255-.210 ; 13, front motor CW de .255-.210 ; 14, front motor CCW de .255-.210 ; 15, rear motor CW de .255-.210 ; 16, rear motor CCW de .0 ; 17, action de .6 ; 18, _loops update ; ;-------------------------------- ; END