; ****** <META http-equiv="Bulletin-Text" content=""> ************************************************************************ ; ; LiniStepper v2 ; PIC 16F84 / 16F628 / 16F628A code (updated 628A June 2007) ; Copyright Aug 2002 - Nov 2009 - Roman Black http://www.romanblack.com ; ; PIC assembler code for the LiniStepper stepper motor driver board. ; 200/400/1200/3600 steps ; ; v2.0 New version 2.0; 2nd Nov 2009. ; * modified v1 source to work with new Lini v2 PCB. ; * STEP and DIR are the same, but POWER is now "ENABLE" (active LOW) ; (so the POWER pin function is inverted in Lini v2) ; v2.1 Updated 16th Nov 2010. ; Now incorporates update suggested by Brian D Freeman; improves ; performance by skipping the current calculation on the hi-lo ; transition of the step input. ; ; (set mplab TABS to 5 for best viewing this .asm file) ;****************************************************************************** ;============================================================================== ; mplab settings ERRORLEVEL -224 ; suppress annoying message because of option/tris ERRORLEVEL -302 ; suppress message because of bank select in setup ports LIST b=5, n=97, t=ON, st=OFF ; ; absolute listing tabs=5, lines=97, trim long lines=ON, symbol table=OFF ;============================================================================== ; processor defined ;include <p16f84A.inc> ;include <p16f628.inc> include <p16f628A.inc> ; processor config IFDEF __16F84A __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC ENDIF IFDEF __16F628 __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC & _MCLRE_ON & _BODEN_OFF & _LVP_OFF ENDIF IFDEF __16F628A __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC & _MCLRE_ON & _BODEN_OFF & _LVP_OFF ENDIF ;============================================================================== ; Variables here ;------------------------------------------------- IFDEF __16F84A #define RAM_START 0x0C #define RAM_END RAM_START+d'68' ; 16F84 has only 68 ram ENDIF IFDEF __16F628 #define RAM_START 0x20 #define RAM_END RAM_START+d'96' ; F628 has 96 ram ENDIF IFDEF __16F628A #define RAM_START 0x20 #define RAM_END RAM_START+d'96' ; F628A has 96 ram ENDIF ;------------------------------------------------- CBLOCK RAM_START status_temp ; used for int servicing w_temp ; used for int servicing step ; (0-71) ustep position! steptemp ; for calcs phase ; stores the 4 motor phase pins 0000xxxx current1 ; for current tween pwm current2 ; for current tween pwm inputs ; stores new input pins inputs_last ; stores last states of input pins ENDC ;------------------------------------------------- ; PIC input pins for porta #define STEP 0 ; / = move 1 step, \=do nothing #define DIR 1 ; lo= cw, hi=ccw #define POWER 2 ; lo=full power, hi=half power ; (Note! POWER pin was inverted for v2 !!!) ;------------------------------------------------- ; Custom instructions! #define skpwne skpnz ; after subxx, uses zero #define skpweq skpz ; after subxx, uses zero #define skpwle skpc ; after subxx, uses carry #define skpwgt skpnc ; after subxx, uses carry ;============================================================================== ; CODE GOES HERE org 0x0000 ; Set program memory base at reset vector 0x00 reset goto main ; ;============================================================================== ; INTERRUPT vector here org 0x0004 ; interrupt routine must start here int_routine ;------------------------------------------------- ; first we preserve w and status register movwf w_temp ; save off current W register contents movf STATUS,w ; move status register into W register movwf status_temp ; save off contents of STATUS register ;------------------------------------------------- ; we get here every 256 timer0 ticks 3900Hz ; int body code here if you want ;------------------------------------------------- ; finally we restore w and status registers and ; clear TMRO int flag now we are finished. int_exit bcf INTCON,T0IF ; reset the tmr0 interrupt flag movf status_temp,w ; retrieve copy of STATUS register movwf STATUS ; restore pre-isr STATUS register contents swapf w_temp,f swapf w_temp,w ; restore pre-isr W register contents retfie ; return from interrupt ;------------------------------------------------- ;============================================================================== ;****************************************************************************** ; MOVE MOTOR sets 8 portb output pins to control motor ;****************************************************************************** ; NOTE!! var step is used for sequencing the 0-71 steps ; uses tables! so keep it first in the code and set PCLATH to page 0 ;------------------ move_motor ; goto label ;------------------ ;------------------------------------------------- ; this code controls the phase sequencing and current ; settings for the motor. ; there are always 72 steps (0-71) ; we can split the main table into 2 halves, each have identical ; current sequencing. That is only 12 entries for hardware current. ; Then can x3 the table to get 36 table entries which cover all 72 steps. ; the 36 entries jump to 36 code pieces, which set the current values ; for the 2 possible tween steps... We need 2 current values, one ; for the x2 value and one for the x1 value. ;------------------------------------------------- ; PHASE SEQUENCING (switch the 4 coils) ; there are 4 possible combinations for the phase switching: ; each have 18 steps, total 72 steps: ; A+ B+ range 0 step 0-17 ; A- B+ range 1 18-35 ; A- B- range 2 36-53 ; A+ B- range 3 54-71 ;------------------------------------------------- ; find which of the 4 ranges we are in movf step,w ; get step movwf steptemp ; store as working temp movf steptemp,w ; sublw d'35' ; sub to test skpwle ; goto half_hi ; wgt, steptemp is 36-71 (upper half) ;------------------------- half_low ; wle, steptemp is 0-35 movf steptemp,w ; sublw d'17' ; sub to test skpwle ; goto range1 ; wgt range0 ; wle movlw b'00000101' ; 0101 = A+ B+ goto phase_done ; range1 movlw b'00001001' ; 1001 = A- B+ goto phase_done ; ;------------------------- half_hi ; steptemp is 36-71 ; NOTE! must subtract 36 from steptemp, so it ; will become 0-35 and ok with table later! movlw d'36' ; subtract 36 from steptemp, subwf steptemp,f ; (now steptemp is 0-35) ; now find the range movf steptemp,w ; sublw d'17' ; sub to test skpwle ; goto range3 ; wgt range2 ; wle movlw b'00001010' ; 1010 = A- B- goto phase_done ; range3 movlw b'00000110' ; 0110 = A+ B- phase_done ; note! steptemp is always 0-35 by here movwf phase ; store phase values ;------------------------------------------------- ; at this point we have the phasing done and stored as the last ; 4 bits in var phase; 0000xxxx ; now we have 36 possible current combinations, which we can do ; by separate code fragments, from a jump table. ; as we have 2 power modes; full and low power, we ; need 2 tables. ;------------------------------------------------- btfsc inputs,POWER ; select table to use goto table_lowpower ; ;------------------------------------------------- ; HIGH POWER TABLE ;------------------------------------------------- table_highpower ; movf steptemp,w ; add steptemp to the PCL addwf PCL,f ; ; here are the 36 possible values; ;------------------------- goto st00 ; * (hardware 6th steps) goto st01 ; (pwm tween steps) goto st02 ; (pwm tween steps) goto st03 ; * goto st04 ; goto st05 ; goto st06 ; * goto st07 ; goto st08 ; goto st09 ; * goto st10 ; goto st11 ; goto st12 ; * goto st13 ; goto st14 ; goto st15 ; * goto st16 ; goto st17 ; goto st18 ; * goto st19 ; goto st20 ; goto st21 ; * goto st22 ; goto st23 ; goto st24 ; * goto st25 ; goto st26 ; goto st27 ; * goto st28 ; goto st29 ; goto st30 ; * goto st31 ; goto st32 ; goto st33 ; * goto st34 ; goto st35 ; ;------------------------------------------------- ; LOW POWER TABLE ;------------------------------------------------- ; as low power mode is for wait periods we don't need to ; maintain the full step precision and can wait on the ; half-step (400 steps/rev). This means much easier code tables. ; The nature of the board electronics is not really suited ; for LOW power microstepping, but it could be programmed here ; if needed. ; NOTE!! uses my hi-torque half stepping, not normal half step. ; doing half stepping with the 55,25 current values gives; ; 55+25 = 80 ; max current 100+100 = 200 ; typical (high) current 100+50 = 150 ; so low power is about 1/2 the current of high power mode, ; giving about 1/4 the motor heating and half the driver heating. ; for now it uses only half-steps or 8 separate current modes. ; we only have to use 4 actual current modes as ; the table is doubled like the table_highpower is. ; NOTE!! I have left the table full sized so it can be modified ; to 1200 or 3600 steps if needed. ;------------------------------------------------- table_lowpower ; movf steptemp,w ; add steptemp to the PCL addwf PCL,f ; ; here are the 36 possible values; ;------------------------- ; A+ B+ (A- B-) goto lp00 ; goto lp00 ; goto lp00 ; goto lp00 ; goto lp00 ; 55,25 (100,45) current low (high) goto lp00 ; goto lp00 ; goto lp00 ; goto lp00 ; goto lp09 ; goto lp09 ; goto lp09 ; goto lp09 ; goto lp09 ; 25,55 (45,100) goto lp09 ; goto lp09 ; goto lp09 ; goto lp09 ; ;------------------------- ; A- B+ (A+ B-) goto lp18 ; goto lp18 ; goto lp18 ; goto lp18 ; goto lp18 ; 25,55 (45,100) goto lp18 ; goto lp18 ; goto lp18 ; goto lp18 ; goto lp27 ; goto lp27 ; goto lp27 ; goto lp27 ; goto lp27 ; 55,25 (100,45) goto lp27 ; goto lp27 ; goto lp27 ; goto lp27 ; ;------------------------------------------------- ; all tables done, no more tables after this point! ;------------------------------------------------- ; next are the 36 code fragments for the high power table. ; CURRENT INFO. ; hardware requires that we send the entire 8 bits to the motor ; at one time, to keep pwm fast. ; ----xxxx, where xxxx is the coils on/off phasing (done) ; xxxx----, where xxxx is the current settings for the A and B phases; ; xx------, where xx is current for A phase ; --xx----, where xx is current for B phase ; hardware currents for 6th stepping have 4 possible values; ; 00 = 0% current ; 01 = 25% current ; 10 = 55% current ; 11 = 100% current ;------------------------------------------------- ; PWM INFO. ; hardware gives us 6th steps, or 1200 steps/rev. ; to get 3600 steps/rev we need TWO more ; "tween" steps between every proper hardware 6th step. ; to do this we set 2 currents, current1 and current2. ; then we do FAST pwm, with 2 time units at current2, ; and 1 time unit at current1. ; this gives a current which is between the two currents, ; proportionally closer to current2. (2/3 obviously) ; this gives the ability to get 2 evenly spaced "tween" currents ; between our hardware 6th step currents, and go from 1200 to 3600. ; the next 36 code fragments set the 2 currents desired, then ; we goto a fast-pwm loop (same loop used for all currents) ; which modulates between the 2 currents and gives final ; output current. ;------------------------------------------------- st00 ; (6th step) movf phase,w ; get coil phasing (is 0000xxxx) iorlw b'11000000' ; set currents; 100,0 movwf current2 ; movwf current1 ; goto pwm ; st01 ; (tween step) movf phase,w ; get coil phasing iorlw b'11000000' ; set 100,0 movwf current2 ; movf phase,w ; iorlw b'11010000' ; set 100,25 movwf current1 ; goto pwm ; st02 ; (tween step) movf phase,w ; get coil phasing iorlw b'11010000' ; set 100,25 movwf current2 ; movf phase,w ; iorlw b'11000000' ; set 100,0 movwf current1 ; goto pwm ; ;------------------------- st03 ; (6th step) movf phase,w ; iorlw b'11010000' ; set 100,25 movwf current2 ; movwf current1 ; goto pwm ; st04 ; movf phase,w ; iorlw b'11010000' ; set 100,25 movwf current2 ; movf phase,w ; iorlw b'11100000' ; set 100,55 movwf current1 ; goto pwm ; st05 ; movf phase,w ; iorlw b'11100000' ; set 100,55 movwf current2 ; movf phase,w ; iorlw b'11010000' ; set 100,25 movwf current1 ; goto pwm ; ;------------------------- st06 ; (6th step) movf phase,w ; iorlw b'11100000' ; set 100,55 movwf current2 ; movwf current1 ; goto pwm ; st07 ; movf phase,w ; iorlw b'11100000' ; set 100,55 movwf current2 ; movf phase,w ; iorlw b'11110000' ; set 100,100 movwf current1 ; goto pwm ; st08 ; movf phase,w ; iorlw b'11110000' ; set 100,100 movwf current2 ; movf phase,w ; iorlw b'11100000' ; set 100,55 movwf current1 ; goto pwm ; ;------------------------- st09 ; (6th step) movf phase,w ; iorlw b'11110000' ; set 100,100 movwf current2 ; movwf current1 ; goto pwm ; st10 ; movf phase,w ; iorlw b'11110000' ; set 100,100 movwf current2 ; movf phase,w ; iorlw b'10110000' ; set 55,100 movwf current1 ; goto pwm ; st11 ; movf phase,w ; iorlw b'10110000' ; set 55,100 movwf current2 ; movf phase,w ; iorlw b'11110000' ; set 100,100 movwf current1 ; goto pwm ; ;------------------------- st12 ; (6th step) movf phase,w ; iorlw b'10110000' ; set 55,100 movwf current2 ; movwf current1 ; goto pwm ; st13 ; movf phase,w ; iorlw b'10110000' ; set 55,100 movwf current2 ; movf phase,w ; iorlw b'01110000' ; set 25,100 movwf current1 ; goto pwm ; st14 ; movf phase,w ; iorlw b'01110000' ; set 25,100 movwf current2 ; movf phase,w ; iorlw b'10110000' ; set 55,100 movwf current1 ; goto pwm ; ;------------------------- st15 ; (6th step) movf phase,w ; iorlw b'01110000' ; set 25,100 movwf current2 ; movwf current1 ; goto pwm ; st16 ; movf phase,w ; iorlw b'01110000' ; set 25,100 movwf current2 ; movf phase,w ; iorlw b'00110000' ; set 0,100 movwf current1 ; goto pwm ; st17 ; movf phase,w ; iorlw b'00110000' ; set 0,100 movwf current2 ; movf phase,w ; iorlw b'01110000' ; set 25,100 movwf current1 ; goto pwm ; ;------------------------- ;------------------------- st18 ; (6th step) movf phase,w ; iorlw b'00110000' ; set 0,100 movwf current2 ; movwf current1 ; goto pwm ; st19 ; movf phase,w ; iorlw b'00110000' ; set 0,100 movwf current2 ; movf phase,w ; iorlw b'01110000' ; set 25,100 movwf current1 ; goto pwm ; st20 ; movf phase,w ; iorlw b'01110000' ; set 25,100 movwf current2 ; movf phase,w ; iorlw b'00110000' ; set 0,100 movwf current1 ; goto pwm ; ;------------------------- st21 ; (6th step) movf phase,w ; iorlw b'01110000' ; set 25,100 movwf current2 ; movwf current1 ; goto pwm ; st22 ; movf phase,w ; iorlw b'01110000' ; set 25,100 movwf current2 ; movf phase,w ; iorlw b'10110000' ; set 55,100 movwf current1 ; goto pwm ; st23 ; movf phase,w ; iorlw b'10110000' ; set 55,100 movwf current2 ; movf phase,w ; iorlw b'01110000' ; set 25,100 movwf current1 ; goto pwm ; ;------------------------- st24 ; (6th step) movf phase,w ; iorlw b'10110000' ; set 55,100 movwf current2 ; movwf current1 ; goto pwm ; st25 ; movf phase,w ; iorlw b'10110000' ; set 55,100 movwf current2 ; movf phase,w ; iorlw b'11110000' ; set 100,100 movwf current1 ; goto pwm ; st26 ; movf phase,w ; iorlw b'11110000' ; set 100,100 movwf current2 ; movf phase,w ; iorlw b'10110000' ; set 55,100 movwf current1 ; goto pwm ; ;------------------------- st27 ; (6th step) movf phase,w ; iorlw b'11110000' ; set 100,100 movwf current2 ; movwf current1 ; goto pwm ; st28 ; movf phase,w ; iorlw b'11110000' ; set 100,100 movwf current2 ; movf phase,w ; iorlw b'11100000' ; set 100,55 movwf current1 ; goto pwm ; st29 ; movf phase,w ; iorlw b'11100000' ; set 100,55 movwf current2 ; movf phase,w ; iorlw b'11110000' ; set 100,100 movwf current1 ; goto pwm ; ;------------------------- st30 ; (6th step) movf phase,w ; iorlw b'11100000' ; set 100,55 movwf current2 ; movwf current1 ; goto pwm ; st31 ; movf phase,w ; iorlw b'11100000' ; set 100,55 movwf current2 ; movf phase,w ; iorlw b'11010000' ; set 100,25 movwf current1 ; goto pwm ; st32 ; movf phase,w ; iorlw b'11010000' ; set 100,25 movwf current2 ; movf phase,w ; iorlw b'11100000' ; set 100,55 movwf current1 ; goto pwm ; ;------------------------- st33 ; (6th step) movf phase,w ; iorlw b'11010000' ; set 100,25 movwf current2 ; movwf current1 ; goto pwm ; st34 ; movf phase,w ; iorlw b'11010000' ; set 100,25 movwf current2 ; movf phase,w ; iorlw b'11000000' ; set 100,0 movwf current1 ; goto pwm ; st35 ; movf phase,w ; iorlw b'11000000' ; set 100,0 movwf current2 ; movf phase,w ; iorlw b'11010000' ; set 100,25 movwf current1 ; goto pwm ; ; high power table done! ;------------------------------------------------- ; next are the 4 code fragments for the low power table. ; (no PWM is used) ;------------------------------------------------- lp00 ; movf phase,w ; iorlw b'10010000' ; set 55,25 movwf current2 ; movwf current1 ; goto pwm ; lp09 ; movf phase,w ; iorlw b'01100000' ; set 25,55 movwf current2 ; movwf current1 ; goto pwm ; lp18 ; movf phase,w ; iorlw b'01100000' ; set 25,55 movwf current2 ; movwf current1 ; goto pwm ; lp27 ; movf phase,w ; iorlw b'10010000' ; set 55,25 movwf current2 ; movwf current1 ; goto pwm ; ;------------------------------------------------- ;------------------------------------------------------------------------------ ;****************************************************************************** ; Main ;****************************************************************************** ; ;------------------ main ; goto label ;------------------ ;--------------------------------------------- ; do initial setup for ports and ints and stuff call setup ; this is our only proper call... ; it is called only once, and does not really need ; to be a function. ;--------------------------------------------- ; main operating loop is here. ;--------------------------------------------- goto move_motor ; will set the motor to step 0, ; and loop permanently from there ;--------------------------------------------- goto main ; safe loop, should never get here anyway. ;============================================================================== ;****************************************************************************** ; NEW INPUTS input change was detected ;****************************************************************************** ; ;------------------ new_inputs ; goto tag ;------------------ ;------------------------------------------------- ; when we enter here: ; * one or more PORTA inputs have just changed ; * inputs_last contains last PORTA inputs values ; * inputs contains new PORTA inputs values ;------------------------------------------------- ; must first detect which input pins changed. ; ---x---- RA4 * mode bit1 ( 00=200 step 01=400 step ; ----x--- RA3 * mode bit0 10=1200 step 11=3600 step ) ; -----x-- RA2 * power (Lini v2; now 0 = full power!) ; ------x- RA1 * direction ; -------x RA0 * step ; if step went hi, we move the step (step++ or step--) ; if step went low, ignore ; ignore change in direction pin ; ignore change in power pin ; ignore change in mode pins ; (all pins besides step are handled automatically in move_motor) ;------------------------------------------------- movf inputs,w ; xor to compare new inputs with last values xorwf inputs_last,f ; now inputs_last has the diff. btfss inputs_last,STEP ; test if step input changed goto ni_end ; ; step input changed! btfsc inputs,STEP ; test if change was lo-hi or hi-lo goto trans_hi ; lo-hi, so process a step! ; hi-lo, so ignore this transition bcf inputs_last,STEP ; record new state of step pin goto pwm ; fast exit back to pwm() ;------------------------------------------------- ; step input changed lo-hi! ; now must make a step forward or back, based ; on the state of the dir pin. ; here it gets complex as we have 4 operating modes, ; determined by the state of the 2 input pins RA4 and RA3; ; ---00--- 200 steps ; ---01--- 400 steps ; ---10--- 1200 steps ; ---11--- 3600 steps ; there are 4 separate code systems to handle stepping ; in the 4 modes; ;------------------------------------------------- trans_hi ; find which of the 4 modes we are in btfss inputs,4 ; test hi bit goto mode_lo ; mode_hi ; must be 1200 or 3600 btfss inputs,3 ; test lo bit goto mode_1200 ; ;------------------------------------------------- mode_3600 ; 3600 mode (72/1) ; each step is 1 btfss inputs,DIR ; test direction input goto m36_up ; m36_down decf step,f ; step-- btfss step,7 ; test for roll under <0 goto ni_end ; ok ; rolled under! movlw d'71' ; force to top step (72-1) movwf step ; goto ni_end ; m36_up incf step,f ; step++ movf step,w ; test for roll over >71 sublw d'71' ; sub to test skpwle ; clrf step ; wgt, rolled over so force to step 0 goto ni_end ; ;------------------------------------------------- mode_1200 ; 1200 mode (72/3) ; each step is mod 3 (0,3,6,9,12 - 66, 69 etc) btfss inputs,DIR ; test direction input goto m12_up ; m12_down movlw d'3' ; amount to subtract subwf step,f ; step-=3 btfss step,7 ; test for roll under <0 goto ni_end ; ok ; rolled under! movlw d'69' ; force to top step (72-3) movwf step ; goto ni_end ; m12_up movlw d'3' ; amount to add addwf step,f ; step+=3 ; movf step,w ; test for roll over >69 sublw d'69' ; sub to test skpwle ; clrf step ; wgt, rolled over so force to step 0 goto ni_end ; ;------------------------------------------------- mode_lo ; must be 200 or 400 btfss inputs,3 ; test lo bit goto mode_200 ; ;------------------------------------------------- mode_400 ; 400 mode (72/9) ; note! we do special half stepping here. ; there are ONLY 8 valid steps: ; 4, 13, 22, 31, 40, 49, 58, 67 ; these steps give 100,45 and 35,100 combos, good ; enough for now. (should average 100,41) btfss inputs,DIR ; test direction input goto m4_up ; m4_down movlw d'9' ; amount to subtract subwf step,f ; step-=9 btfss step,7 ; test for roll under <0 goto ni_end ; ok ; rolled under! movlw d'67' ; force to top (full) step movwf step ; goto ni_end ; m4_up movlw d'9' ; amount to add addwf step,f ; step+=9 ; movf step,w ; test for roll over sublw d'67' ; sub to test skpwgt ; goto ni_end ; wle, is ok movlw d'4' ; wgt, rolled over so force to bottom step 5 movwf step ; goto ni_end ; ;------------------------------------------------- mode_200 ; 200 mode (72/18) ; NOTE!! this has special needs as we can't use ; step 0, we need to stay on the "2 steps on" steps. ; there are ONLY 4 valid steps; 9, 27, 45, 63 btfss inputs,DIR ; test direction input goto m2_up ; m2_down movlw d'18' ; amount to subtract subwf step,f ; step-=18 btfss step,7 ; test for roll under <0 goto ni_end ; ok ; rolled under! movlw d'63' ; force to top (full) step (72-(18/2)) movwf step ; goto ni_end ; m2_up movlw d'18' ; amount to add addwf step,f ; step+=18 ; movf step,w ; test for roll over sublw d'63' ; sub to test skpwgt ; goto ni_end ; wle, is ok movlw d'9' ; wgt, rolled over so force to bottom step 9 movwf step ; goto ni_end ; ;------------------------------------------------- ni_end movf inputs,w ; save a copy of the inputs movwf inputs_last ; goto move_motor ; go and make it all happen ;------------------------------------------------------------------------------ ;****************************************************************************** ; PWM is the fast pwm loop ;****************************************************************************** ; NOTE!! we enter the code in the middle of the loop! ;------------------------------------------------- ; the 2 target currents were set in the move_motor code. ; what this function does is spend 2 time units at current2, ; and 1 time unit at current1. ; actual is 8 clocks at current2 ; and 4 clocks at current 1 ; total 12 cycles, so 333 kHz with 16MHz resonator. ; this gives an average pwm current of 2/3 the way between ; current2 and current1. ; the routine is kept short to keep pwm frequency high, so it ; is easy to smooth in hardware by the ramping caps. ; IMPORTANT! is timed by clock cycles, don't change this code! ; it also checks for any change in input pins here ; the 8/4 code seen here was supplied by Eric Bohlman (thanks!) ;------------------------------------------------- pwm_loop ; first output current1 to motor movf current1,w ; get currents and phase switching movwf PORTB ; send to motor! nop ; timing delay nop ; ; (4 cycles) ;------------------------- pwm ; main entry! ; better to enter at current2 for motor power. ; now output current2 movf current2,w ; movwf PORTB ; send to motor! nop ; safe wait 250nS ; now test input pins movf PORTA,w ; get pin values from port xorwf inputs_last,w ; xor to compare new inputs with last values skpnz goto pwm_loop ; z, inputs not changed, so keep looping ; (8 cycles) ;------------------------------------------------- ; nz, one or more input pins have changed! xorwf inputs_last,w ; restore xored value back to the orig inputs value movwf inputs ; goto new_inputs ; ;------------------------------------------------- ;------------------------------------------------------------------------------ ;****************************************************************************** ; SETUP sets port directions and interrupt stuff etc, ;****************************************************************************** ; NOTE!! is the only proper funtion, is done before other activity ;------------------ setup ; routine tag ;------------------ ;------------------------------------------------- ; Note! there are added bits for the 16F628! ; here we set up peripherals and port directions. ; this will need to be changed for different PICs. ;------------------------------------------------- ; OPTION setup movlw b'10000010' ; ; x------- ; 7, 0=enable, 1=disable, portb pullups ; -x------ ; 6, 1=/, int edge select bit ; --x----- ; 5, timer0 source, 0=internal clock, 1=ext pin. ; ---x---- ; 4, timer0 ext edge, 1=\ ; ----x--- ; 3, prescaler assign, 1=wdt, 0=timer0 ; -----x-- ; 2,1,0, timer0 prescaler rate select ; ------x- ; 000=2, 001=4, 010=8, 011=16, etc. ; -------x ; ; banksel OPTION_REG ; go proper reg bank movwf OPTION_REG ; load data into OPTION_REG banksel 0 ; ;------------------------------------------------- ; note! check for 16F628 (and A) and do extra setup for it. IFDEF __16F628 banksel VRCON ; do bank 1 stuff clrf VRCON ; disable Vref clrf PIE1 ; disable pi etc banksel 0 ; clrf T1CON ; disable timer1 clrf T2CON ; disable timer2 clrf CCP1CON ; disable CCP module movlw b'00000111' ; disable comparators movwf CMCON ; ENDIF IFDEF __16F628A banksel VRCON ; do bank 1 stuff clrf VRCON ; disable Vref clrf PIE1 ; disable pi etc banksel 0 ; clrf T1CON ; disable timer1 clrf T2CON ; disable timer2 clrf CCP1CON ; disable CCP module movlw b'00000111' ; disable comparators movwf CMCON ; ENDIF ;------------------------------------------------- ; PORTB pins direction setup ; 1=input, 0=output clrf PORTB ; ; movlw b'00000000' ; all 8 portb are outputs ; banksel TRISB ; go proper reg bank movwf TRISB ; send mask to portb banksel 0 ; ;------------------------------------------------- ; PORTA pins direction setup ; 1=input, 0=output clrf PORTA ; ; NOTE!! all 5 PORTA pins are inputs movlw b'00011111' ; ; ---x---- ; RA4 ; ----x--- ; RA3 ; -----x-- ; RA2 ; ------x- ; RA1 ; -------x ; RA0 banksel TRISA ; go proper reg bank movwf TRISA ; send mask to porta banksel 0 ; ;------------------------------------------------- movlw 0x00 ; set up PCLATH for all jump tables on page 0 movwf PCLATH ; (all tables are in move_motor) ;------------------------------------------------- ; CLEAR RAM! for lower bank movlw RAM_START ; first byte of ram movwf FSR ; load pointer ram_clear_loop clrf INDF ; clear the ram we pointed to incf FSR,f ; inc pointer to next ram byte movf FSR,w ; get copy of pointer to w sublw RAM_END ; test if PAST the last byte now skpweq ; goto ram_clear_loop ; ;------------------------------------------------- ; here we can set the user variables and output pins movlw 0x00 ; for step 0 of 0-71 movwf step ; loaded ready for jump table movf PORTA,w ; get initial value for inputs movwf inputs ; movwf inputs_last ; ;------------------------------------------------- ; set up INTCON register last movlw b'00000000' ; set the bit value ; x------- ; bit7 GIE global int enable, 1=enabled ; -x------ ; bit6 EE write complete enable, 1=en ; --x----- ; bit5 TMR0 overflow int enable, 1=en ; ---x---- ; bit4 RB0/INT enable, 1=en ; ----x--- ; bit3 RB port change int enable, 1=en ; -----x-- ; bit2 TMR0 int flag bit, 1=did overflow and get int ; ------x- ; bit1 RB0/INT flag bit, 1=did get int ; -------x ; bit0 RB port int flag bit, 1=did get int movwf INTCON ; put in INTCON register ;------------------------------------------------- return ; ;------------------------------------------------------------------------------ ;============================================================================== ; this code is only to display 1k of the memory usage chart ; in the absolute listing! ; page 0 256 byte block-------------------- ;org 0x40-2 ;nop ;org 0x80-1 ;nop ;org 0xC0-1 ;nop ;org 0x100-1 ;nop ; page 1 256 byte block-------------------- ;org 0x140-2 ;nop ;org 0x180-1 ;nop ;org 0x1C0-1 ;nop ;org 0x200-1 ;nop ; page 2 256 byte block-------------------- org 0x240-2 nop org 0x280-1 nop org 0x2C0-1 nop org 0x300-1 nop ; page 3 256 byte block-------------------- org 0x340-2 nop org 0x380-1 nop org 0x3C0-1 nop org 0x400-1 nop IFDEF __16F628A ; page 4 256 byte block-------------------- org 0x440-2 nop org 0x480-1 nop org 0x4C0-1 nop org 0x500-1 nop ; page 5 256 byte block-------------------- org 0x540-2 nop org 0x580-1 nop org 0x5C0-1 nop org 0x600-1 nop ; page 6 256 byte block-------------------- org 0x640-2 nop org 0x680-1 nop org 0x6C0-1 nop org 0x700-1 nop ; page 7 256 byte block-------------------- org 0x740-2 nop org 0x780-1 nop org 0x7C0-1 nop org 0x800-1 nop ENDIF ;------------------------------------------------------------------------- end ;------------------------------------------------------------------------- ;============================================================================== ;============================================================================== ;============================================================================== ;------------------------------------------------- ; NOTE!! example! below is the original (non-pwm) table for the ; 24x hardware 6th steps. ; this will be useful to code a minimum-rom microstepper ; if you don't need 3600 and can make do with 1200 steps. ; same system as the main code; ; ----xxxx are the phase sequencing ; xxxx---- are the current values ; (this code table has been used and tested!) ;------------------------------------------------- ; COMMENTED OUT! ;movlw b'11000101' ; 0, 100,0 A+ B+ 00=0 01=25 ;movlw b'11010101' ; 1, 100,25 A+ B+ 10=55 11=100 ;movlw b'11100101' ; 2, 100,55 A+ B+ ;movlw b'11110101' ; 3, 100,100 A+ B+ ;movlw b'10110101' ; 4, 55,100 A+ B+ ;movlw b'01110101' ; 5, 25,100 A+ B+ ;------------------------- ;movlw b'00111001' ; 6, 0,100 A- B+ ;movlw b'01111001' ; 7, 25,100 A- B+ ;movlw b'10111001' ; 8, 55,100 A- B+ ;movlw b'11111001' ; 9, 100,100 A- B+ ;movlw b'11101001' ; 10, 100,55 A- B+ ;movlw b'11011001' ; 11, 100,25 A- B+ ;------------------------- ;movlw b'11001010' ; 12, 100,0 A- B- ;movlw b'11011010' ; 13, 100,25 A- B- ;movlw b'11101010' ; 14, 100,55 A- B- ;movlw b'11111010' ; 15, 100,100 A- B- ;movlw b'10111010' ; 16, 55,100 A- B- ;movlw b'01111010' ; 17, 25,100 A- B- ;------------------------- ;movlw b'00110110' ; 18, 0,100 A+ B- ;movlw b'01110110' ; 19, 25,100 A+ B- ;movlw b'10110110' ; 20, 55,100 A+ B- ;movlw b'11110110' ; 21, 100,100 A+ B- ;movlw b'11100110' ; 22, 100,55 A+ B- ;movlw b'11010110' ; 23, 100,25 A+ B- EXAMPLE! full table example here, 0-71 steps showing every step... ;------------------------- 0 100,0 A+ B+ 1 100,8 (pwm tween) 2 100,17 (pwm tween) 3 100,25 A+ B+ 4 100,35 (pwm tween) 5 100,45 (pwm tween) 6 100,55 A+ B+ 7 100,70 (pwm tween) 8 100,85 (pwm tween) 9 100,100 A+ B+ (rest of table is same, tweens not shown) 10 11 12 55,100 A+ B+ 13 14 15 25,100 A+ B+ 16 17 ;------------------------- 18 0,100 A- B+ 19 20 21 25,100 A- B+ 22 23 24 55,100 A- B+ 25 26 27 100,100 A- B+ 28 29 30 100,55 A- B+ 31 32 33 100,25 A- B+ 34 35 ;------------------------- 36 100,0 A- B- 37 38 39 100,25 A- B- 40 41 42 100,55 A- B- 43 44 45 100,100 A- B- 46 47 48 55,100 A- B- 49 50 51 25,100 A- B- 52 53 ;------------------------- 54 0,100 A+ B- 55 56 57 25,100 A+ B- 58 59 60 55,100 A+ B- 61 62 63 100,100 A+ B- 64 65 66 100,55 A+ B- 67 68 69 100,25 A+ B- 70 71 ;-------------------------------------------------
file: /Techref/io/stepper/linistep/Lini_asm_v21.asm, 36KB, , updated: 2019/6/10 21:10, local time: 2024/8/14 17:15,
13.58.158.56:LOG IN
|
©2024 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions? <A HREF="http://sxlist.com/techref/io/stepper/linistep/Lini_asm_v21.asm"> io stepper linistep Lini_asm_v21</A> |
Did you find what you needed? |
Welcome to sxlist.com!sales, advertizing, & kind contributors just like you! Please don't rip/copy (here's why Copies of the site on CD are available at minimal cost. |
Welcome to sxlist.com! |
.