program to drive 3 phase hard drive stepper

Chris
2012-03-22
2013-05-30
  • Chris

    Chris - 2012-03-22

    here is something ive been working on that i think some people may find useful. this program will drive a 3 phase stepper motor (the one i used was from a laptop hard drive) without the use of hall effect sensors (it starts in a blind open loop, until its fast enough to read the back electromotive force). ive gotten this program to drive the motor at least 7,000 rpm in open loop mode, and is very stable in closed loop, it will reset back to open loop if the motor stalls. if anyone has any questions, such as where the pins go to what ( i think ive labeled them as constants and comments pretty well) just ask and ill answer. this is a contribution to give back for all the help ive gotten on this forum before, hope you enjoy.
    oh and by the way this code is meant to run on an 11input/output (7 used 3 of which are ANALOG and 4 are OUTPUTS) 16f616

    ;Chip Settings
    #chip 16F616,8
    #config BOD=OFF, BOR=OFF, OSC=INTRC_OSC_NOCLKOUT, MCLRE=OFF
    ;Defines (Constants)
    #define phase_a portc.5
    #define phase_b portc.4
    #define phase_c portc.3
    #define phase_locked_led porta.2
    ;Variables
    Dim milli_seconds As byte
    Dim locked As bit
    Dim step_sequence As byte
    Dim phase_in As byte
    Dim timer_temp As word
    Dim micro_seconds As word
    ;Interrupt Handlers
    On Interrupt Timer0Overflow Call timer0_overflow
    On Interrupt Timer1Overflow Call open_loop_ramp
    InitTimer1 Osc, PS1_1/8
    StopTimer 1
    ClearTimer 1
    InitTimer0 Osc, PS0_1/64
    open_loop_ramp
    Dir PORTC.0 In
    Dir PORTC.1 In
    Dir PORTC.2 In
    Do Forever
        step_sequence = 1
        Dir phase_b Out
        Dir phase_a In
        Set phase_b Off
        Set phase_c On
        check_cross
        step_sequence = 2
        Dir phase_a Out
        Set phase_a On
        Set phase_b Off
        Dir phase_c In
        check_cross
        step_sequence = 3
        Dir phase_c Out
        Set phase_a On
        Dir phase_b In
        Set phase_c Off
        check_cross
        step_sequence = 4
        Dir phase_b Out
        Dir phase_a In
        Set phase_b On
        Set phase_c Off
        check_cross
        step_sequence = 5
        Dir phase_a Out
        Set phase_a Off
        Set phase_b On
        Dir phase_c In
        check_cross
        step_sequence = 6
        Dir phase_c Out
        Set phase_a Off
        Dir phase_b In
        Set phase_c On
        check_cross
    Loop
    Sub timer0_overflow
        If milli_seconds=0 Then
            locked = 1
            Exit Sub
        End If
        micro_seconds = micro_seconds-1
        If micro_seconds=0 Then
            If milli_seconds>0 Then
                micro_seconds = 99
                milli_seconds = milli_seconds-1
            End If
        End If
    End Sub
    Sub check_cross
        phase_in = 250
        If locked=1 Then
            Set phase_locked_led On
            ClearTimer 1
            startTimer 1
            Do Until phase_in<200 or locked=0
                'the part of the sequence where B is input
                If step_sequence=3 or step_sequence=6 Then
                    'read phase A
                    phase_in = readAD(an4)
                End If
                'the part of the sequence where C is input
                If step_sequence=2 or step_sequence=5 Then
                    'read phase B
                    phase_in = readAD(an5)
                End If
                'the part of the sequence where A is input
                If step_sequence=1 or step_sequence=4 Then
                    'read phase C
                    phase_in = readAD(an6)
                End If
            Loop
            StopTimer 1
            timer_temp = Timer1
            ClearTimer 1
            startTimer 1
            Wait Until Timer1<=timer_temp or locked=0
            StopTimer 1
        End If
        If locked=0 Then
            Wait milli_seconds ms
            Wait micro_seconds 10us
        End If
    End Sub
    Sub open_loop_ramp
        Set phase_locked_led Off
        micro_seconds = 99
        milli_seconds = 20
        locked = 0
    End Sub
    
     
  • Nobody/Anonymous

    Fascinating! 
    I have a couple of questions…
    How would you set it to give a fixed rpm?
    Are you driving the motor direct from the 16F616 pins?
    I thought that these motors require 12V and quite a bit of current. 
    I have been using a L6232B to bump up the current and voltage, but it complicates things quite a bit and it gets alarmingly hot at high rpm. 

     

Log in to post a comment.

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:





No, thanks