Submitted by:
Ron Bihler
Technical Glass, Inc.
This application note gives an example of using a TICkit 57 programmed with FBasic to run a stepper motor using 4 transistors as current amplifiers for the stepper motor phases. The program also includes code to enter parameters using two push-button switches and an LCD screen. All files for this note can be downloaded as a ZIP file, AN001.ZIP
As can be seen in the schematic above, a unipolar stepper motor (3M3401) is driven directly from a TICkit 57 via 4 3055T transistors. The common side of the stepper motor windings connect to the positive motor supply. The ground side of the motor windings are switched. The stepper motor and the transistors can be obtained from Jameco Electronics.
The Program to control this circuit is below. Much of the code below deals with the LCD display and the buttons to create a wrist-watch type of interface for setting drilling depth and rate. The basic algorithm for generating the motor phases consists of using an array with 4 entries, one entry for each coil pattern of each phase. The index to this array is incremented or decremented depending on the direction of motor travel:
; Program to control a vertical drilling rig with diamond bit for drilling ; precision scientific quartz glass instrument ; Written by Ron Bihler - Technical Glass Inc DEF tic57e LIB fbasic.lib GLOBAL byte xbuss_mask 0y00110001b GLOBAL byte lcd_data_reg 0y00110001b GLOBAL byte lcd_cont_reg 0y00110000b GLOBAL byte pos 3b GLOBAL byte step_code [4] 3b 6b 12b 9b GLOBAL word cur_count 1w GLOBAL word dstep 0w GLOBAL word targ_count 0w LIB lcdinit4.lib LIB lcd_word.lib LIB lcdstrin.lib LIB ee.lib GLOBAL byte trash GLOBAL byte lcd_mode 0b GLOBAL byte a_high 0xffb GLOBAL byte b_high 0xffb ALLOC word stored_dstep ALLOC word stored_targ_ct DEF operate 0b DEF button_one pin_a1 ; mode button DEF button_two pin_a2 ; inc/dec button ; 20mhz up/dwn 50 slw 400 DEF upstep 50w DEF dwnstep 50w DEF slwstep 400w FUNC none lcd_clear ; Clear LCD BEGIN lcd_cont( 0y00000001b ) ENDFUN FUNC none lcd_pos ; Position LCD PARAM byte place BEGIN lcd_cont( or( 0y10000000b, place )) ENDFUN FUNC none lcd_cursor_off ; function to turn the cursor off BEGIN lcd_cont( 0y00001100b ) ENDFUN FUNCTION none rstep ; Reverse step PARAM word steps ; Number of steps PARAM word rate ; step rate ( 10us delays between steps ) LOCAL word copy BEGIN =( copy, steps ) REPEAT ++(pos) IF ==(pos,4b) =(pos,0b) ENDIF dport_set( step_code[pos] ) pulse_out_high( debug_pin, rate) ; this is just a delay --(copy) UNTIL ==(copy,0w) ENDFUN FUNCTION none fstep ; Forward Step PARAM word steps ; Number of steps PARAM word rate ; Step Rate ( 10us delays between steps ) LOCAL word copy BEGIN =( copy, steps) REPEAT IF ==(pos,0b) =(pos,4b) ENDIF --(pos) dport_set(step_code[pos]) pulse_out_high( debug_pin, rate) ; this is just a delay --(copy) UNTIL ==(copy,0w) ENDFUN FUNCTION none ret ; return stepper to zero position; Contact depressed PARAM word steps ; Number of steps to return ; (used to make sure motor is moving freely) PARAM word rate ; Step rate LOCAL word copy BEGIN =( copy, +( steps, 50w )) ; just incase some steps were lost REPEAT ++(pos) IF ==(pos,4b) =(pos,0b) ENDIF dport_set( step_code[pos] ) pulse_out_high( debug_pin, rate ) --(copy) IF ==(copy,0b) ; Error checking to make sure motor moves properly lcd_pos(0b) lcd_string( "Error Returning ") REPEAT LOOP ENDIF UNTIL pin_in( pin_a4 ) ENDFUN FUNCTION none main BEGIN lcd_init() rs_param_set( debug_pin ) dport_set(0b) ;Set d-line low dtris_set(0b) ;Set d-line to output ret( 9999, upstep ) ;Return stepper position to stop dport_set( 0b ) lcd_cursor_off() =( targ_count, ee_read_word( stored_targ_cth )) =( dstep, ee_read_word( stored_dsteph )) =( lcd_mode, operate ) lcd_clear() lcd_pos( 0b ) lcd_string( "COUNT: " ) lcd_write_num( cur_count ) lcd_pos( 64b ) lcd_string( "TARGET: " ) lcd_write_num( targ_count ) lcd_pos( 16b ) lcd_string( "Increment :") lcd_write_num(dstep) lcd_pos(80b) lcd_string( "Change Mode " ) lcd_pos( 92b ) lcd_string( "Hold A" ) REP IF pin_in( button_one ) =( a_high, 0xffb ) IF and(==(lcd_mode,0b),==(pin_in(button_two),0b)) lcd_pos(80b) lcd_string("A=Pause, B=Stop ") REPEAT lcd_pos(8b) lcd_write_num(cur_count) fstep(cur_count,dwnstep) fstep(50w,slwstep) ret(+(cur_count,50w),upstep) DELAY(200w) =(cur_count,+(cur_count,dstep)) IF OR(==(pin_in(button_two),0b),==(pin_in(button_one),0b)) ret(9999,upstep) STOP ENDIF UNTIL >(cur_count,targ_count) IF pin_in(button_one) =(cur_count,1w) ENDIF REPEAT UNTIL pin_in(button_two) lcd_pos(8b) lcd_write_num(cur_count) dport_set(0b) lcd_pos(80b) lcd_string( "Change Mode " ) lcd_pos( 92b ) lcd_string( "Hold A " ) ENDIF ELSE =( a_high, 0b ) IF ==( lcd_mode, 0b ) lcd_pos( 92b ) lcd_string( "Press B" ) ENDIF WHILE ==( pin_in( button_one), 0b ) IF pin_in( button_two ) =( b_high, 0xffb ) ELSE IF ==( b_high, 0xffb ) =( b_high, 0b ) IF ==( lcd_mode, 6b ) =( lcd_mode, 0b ) ELSE ++( lcd_mode ) ENDIF IF ==( lcd_mode, 0b ) lcd_clear() lcd_pos( 0b ) lcd_string( "COUNT: " ) lcd_write_num( cur_count ) lcd_string(" ") lcd_pos(16b) lcd_string("Increment : ") lcd_write_num(dstep) lcd_pos( 64b ) lcd_string( "TARGET: " ) lcd_write_num( targ_count ) lcd_string(" ") lcd_pos( 80b ) lcd_string( "Change Mode" ) lcd_pos( 92b ) lcd_string( "Press B" ) ELSEIF or( ==( lcd_mode, 1b ), ==( lcd_mode, 2b )) lcd_pos( 0b ) IF ==(lcd_mode,1b) lcd_string( "Count Set MODE + " ) ELSE lcd_string( "Count Set MODE - " ) ENDIF lcd_pos( 64b ) lcd_string( "COUNT: " ) lcd_write_num( cur_count ) lcd_pos( 80b ) lcd_string( "To Change " ) lcd_pos( 92b ) lcd_string( "Press A " ) IF ==( lcd_mode, 1b ) --( cur_count ) ELSE ++( cur_count ) ENDIF ELSEIF or( ==( lcd_mode, 3b ), ==( lcd_mode, 4b )) lcd_pos( 0b ) IF ==(lcd_mode,3b) lcd_string( "Target Set MODE + " ) ELSE lcd_string( "Target Set MODE - " ) ENDIF lcd_pos( 64b ) lcd_string( "TARGET: " ) lcd_write_num( targ_count ) lcd_pos( 80b ) lcd_string( "To Change " ) lcd_pos( 92b ) lcd_string( "Press A" ) IF ==( lcd_mode, 3b ) --( targ_count ) ELSE ++( targ_count ) ENDIF ELSEIF or( ==( lcd_mode, 5b ), ==( lcd_mode, 6b )) lcd_pos( 0b ) IF ==(lcd_mode,5b) lcd_string( "Increment Set MODE + " ) ELSE lcd_string( "Increment Set MODE - " ) ENDIF lcd_pos( 64b ) lcd_string( "Increment: " ) lcd_write_num( dstep ) lcd_pos( 82b ) lcd_string( "To Change " ) lcd_pos( 92b ) lcd_string( "Press A" ) IF ==( lcd_mode, 5b ) --( dstep ) ELSE ++( dstep ) ENDIF ENDIF ENDIF ENDIF LOOP IF ==( lcd_mode, 0b ) lcd_pos( 92b ) lcd_string( "Hold A " ) ELSEIF ==( lcd_mode, 1b ) ++( cur_count ) lcd_pos( 72b ) lcd_write_num( cur_count ) ELSEIF ==( lcd_mode, 2b ) --( cur_count ) lcd_pos( 72b ) lcd_write_num( cur_count ) ELSEIF ==( lcd_mode, 3b ) ++( targ_count ) lcd_pos( 72b ) lcd_write_num( targ_count ) ee_write( stored_targ_ctl, targ_count ) ELSEIF ==( lcd_mode, 4b ) --( targ_count ) lcd_pos( 72b ) lcd_write_num( targ_count ) ee_write( stored_targ_ctl, targ_count ) ELSEIF ==( lcd_mode, 5b ) ++( dstep ) lcd_pos( 75b ) lcd_write_num( dstep ) lcd_string(" ") ee_write( stored_dstepl, dstep ) ELSEIF ==( lcd_mode, 6b ) --( dstep ) lcd_pos( 75b ) lcd_write_num( dstep ) lcd_string(" ") ee_write( stored_dstepl, dstep ) ENDIF ENDIF LOOP ENDFUN
Protean Logic Inc. Copyright 05/05/04 Top of Page