How to drive stepperdriver with Dspic33EP256GP502

Started by basparky, Apr 23, 2021, 07:08 PM

Previous topic - Next topic

basparky

Hi All,

I have found my way on the new forum and ready to get myself a Positron package. Very happy we can continue together!

For a little project i have purchased a DRV8825 stepper driver. it needs step and dir input from my Dspic to get the steppermotor running.
I have setup the hardware and got the motor running at 20 rpmor soby a static pulse.

This Dspic has output compare outputs forpulsing or enough tmers to setup a timer interrupt to generate the pulse.

I need to ramp up and down the motor at in 160 (full)steps/288degrees. and need to run the motor at high speed, 2400 rpm if possible.

Any suggestions how to do this? Are there stepper motor examples available?

Many thanks for any suggestions!

Regards,
Bas

Giuseppe

hi I found this library for Arduino could be a starting point to translate for the basic.
https://github.com/laurb9/StepperDriver

RGV250

#2
Hi,
This is something I wrote for a friend a while ago, as far as I recall it worked for his purposes.
It is for 8bit but should convert easily.
BTW, the bit about the enable before direction change, I dont think you need that, he just wanted a safeguard.
'****************************************************************
'*  Name    :                                                   *
'*  Author  : Bobby Garrett                                     *
'*  Notice  : Copyright (c) 2019 Bobby Garrett                  *
'*          : All Rights Reserved                               *
'*  Date    : 12/09/2019                                        *
'*  Version : 1.0                                               *
'*  Notes   : Read channel 0 of on-board ADC                    *
'*          : then send square-wave output                      *
'*          : and enable and direction                          *
'****************************************************************

        Include "Proton18_4.Inc"

        Declare Adin_Res = 10                  'Set the resolution to 10
        Declare Adin_Tad = FRC                 'Choose the RC osc for ADC samples
        Declare Adin_Stime = 100               'Allow 100us for charge time

        Dim Raw As Word
        Dim Quanta As Float
        Dim Range As Byte                      'If max > 265 change to word
        Dim ScaledPotValue As Word
   
        Dim PulseCount As Word
        Symbol MinValue = 10
        Symbol MaxValue = 100
       
'****************************************************************           
'* Variables for Timer1                                         *
'****************************************************************                                       
        Dim TIMER1 As TMR1L.Word
        Dim TIMER_1_BITS As Byte
        Dim TIMER_1_OFFSET As Word

'****************************************************************           
'* Symbols for Interrupts                                       *
'**************************************************************** 
        Symbol IPEN = RCON.7
        Symbol TMR1IP = IPR1.0   
        Symbol TMR1IF = PIR1.0 
        Symbol TMR1IE = PIE1.0 
        Symbol GIEH = INTCON.7   
        Symbol GIEL = INTCON.6
             
        Symbol TMR1ON = T1CON.0 
       
'****************************************************************
'* Set up Timer 1                                               *
'****************************************************************     
        TIMER_1_BITS = %10000000               'Timer 1 configuration bits             
                                               'Timer 1 - 1:1 prescaler and act as timer                         
        TIMER_1_OFFSET = 64535                 'Timer 1 offset for approx 1mS Interrupt)
                                               'Configured for 4 Mhz xtal       
       
        PIE1 = %00000001
        PIR1 = %00000001 
               
'****************************************************************
'* Set up Port A                                                *
'****************************************************************             
        TRISA.0 = 1                            'Setup bit-0 of PortA as an input
        ADCON1 = %10000010                     'Set PORTA analog and right justify result

'****************************************************************
'* Set up Port D                                                *
'****************************************************************   
        TRISD.0 = 0
        TRISD.1 = 0
        TRISD.2 = 0
       
'****************************************************************
'* Interrupt service vector initialization                      *
'****************************************************************

        On_Hardware_Interrupt GoTo INTERRUPT_ROUTINE   
                                                         
        GoTo OVER_INT 

'****************************************************************       
'* Interrupt Service Routine                                    *
'****************************************************************
INTERRUPT_ROUTINE:
        Context Save           

        If PIR1.0 = 1 Then
        GoSub Timer_Int
'Set / clear relevant bits before returning from interupt
        PIR1.0 = 0                             'Clear Timer 1 overflow interrupt bit
        TIMER1 = TIMER_1_OFFSET                'Re-load timer
        Set T1CON.0                            'Re-start timer
        EndIf       
       
        Context Restore                        'Exit ISR and re-enable interrupts 
       
'Timer interrupt, increment a counter every x mS.
Timer_Int:         
        Clear T1CON.0                          'Stop timer
       
        Inc PulseCount                         'Increment the counter
        If PulseCount >= 1000 Then PulseCount = 0  'This should never happen
        Return
'End of timer Interrupt   

OVER_INT:           
     
'****************************************************************
'* Start of Main Code                                           *
'****************************************************************
START:
        DelayMS 100                            'Wait for things to stabilise

'Set up TIMER1                           
        T1CON = TIMER_1_BITS
        TIMER1 = TIMER_1_OFFSET                'Load timer 1
        T1CON.0 = 1                            'Start Timer running
        PIR1.0 = 0                             'Clear timer 1 overflow bit
        PIE1 = 1                               'Enable Timer1 interrupt   
       
        INTCON = %11000000                     'Turn interrupts on

Again:
       Raw = ADIn 0                            'Read the ADC

        Range = MaxValue - MinValue            'Calculate the range (100 - 10 = 90)
        Quanta = Range / 1023                  'Quantasize the result (90 / 1023 = 0.08798)
        ScaledPotValue = (Raw * Quanta) + 10
        ScaledPotValue = ScaledPotValue / 2

        If PORTB.0 = 1 Then GoTo OverDirection 'Do not allow direction change while
                                               'enable is on
        DelayMS 50                             'wait 50ms before allowing switching direction in
                                               'case it causes a problem if changed over before
                                               'enable button released
                                               
        If PORTB.1 = 1 Then                    'Change direction output
            PORTD.2 = 1
        Else
            PORTD.2 = 0
        EndIf 
   
OverDirection:       
        If PORTB.0 = 1 Then                     
            PORTD.1 = 1                        'If enable is on then set the output
            GoSub PulseTrain                   'and send the pulses out
        ElseIf PORTB.0 = 0 Then
            LATD.1 = 0                         'If enable is off set the pulse low
            LATD.0 = 0                         'and disable the enable output
        EndIf
               
        GoTo Again                             'Do it forever
       
PulseTrain:       
        If PulseCount >= ScaledPotValue Then
            Toggle PORTD.0
            PulseCount = 0
        EndIf
        Return       




Tenaja

There is an algorithm written just for PIC24, which IIRC has a reduced instruction set compared to the dsPIC's. I think this article has it, but if not, search for many similar terms.
https://www.embedded.com/generate-stepper-motor-speed-profiles-in-real-time/

It was written in C, but should not be hard to convert. Or, just take that algo and giterdone.