• Not Answered

CCS/DRV8836: DDS priciple

Part Number: DRV8836

Tool/software: Code Composer Studio

Hello Mr. admin,

I am learning now how to generate a pwm signale  with DDS principle.

I found in TI WIKI a firmeware for an DRV8836 edited by Kai Gossner. The frimware generate two PWM signale and one of them is shifted to 90°, and this exactly what i want. But i don't realy understood it how it realy work. could you please explain me how it work? more precise, what happened in the Timer interrupt?the code is  below:

/*
* stepper.c
*
* Author: Kai Gossner
*/

#include <msp430.h>
#include "stepper.h"

/* Bit number of PORT2 where APH pin is connected*/
#define STEPPER_APH (1)
/* Bit number of PORT2 where BPH pin is connected*/
#define STEPPER_BPH (4)
/* Bit number of PORT2 where AEN pin is connected*/
#define STEPPER_AEN (0)
/* Bit number of PORT2 where BEN pin is connected*/
#define STEPPER_BEN (3)


/* graycode pattern to drive the stepper motor */
static const uint8_t s_step_pattern[4] = { (1<<STEPPER_APH) | (0<<STEPPER_BPH),
(1<<STEPPER_APH) | (1<<STEPPER_BPH),
(0<<STEPPER_APH) | (1<<STEPPER_BPH),
(0<<STEPPER_APH) | (0<<STEPPER_BPH) };

static volatile uint16_t s_stepper_phaseaccumulator = 0;
static volatile uint16_t s_stepper_phaseadder = 0;
static volatile uint32_t s_stepper_position = 0;
static int8_t s_stepper_direction = 1; /* +1 = CW, -1 = CCW*/
static volatile uint32_t s_stepper_count = 0;

void stepper_init(void)
{
TACTL = TASSEL_2 + MC_1 + TAIE; // SMCLK, contmode, interrupt
TACCR0 = 100-1; // setup timer overflow every 100us
_BIS_SR(GIE); // Enter LPM0 w/ interrupt

/* set all stepper control pins to output and low*/
P2OUT = P2OUT & ~((1<<STEPPER_AEN) | (1<<STEPPER_BEN) | (1<<STEPPER_APH) | (1<<STEPPER_BPH));
P2DIR |= (1<<STEPPER_AEN) | (1<<STEPPER_BEN) | (1<<STEPPER_APH) | (1<<STEPPER_BPH);
}


void stepper_driver_off(void)
{
P2OUT = P2OUT & ~((1<<STEPPER_AEN) | (1<<STEPPER_BEN));
}


void stepper_driver_on(void)
{
P2OUT = P2OUT | ((1<<STEPPER_AEN) | (1<<STEPPER_BEN));
}


void stepper_rotate(int32_t count, uint16_t speed)
{
stepper_driver_on();

if (count > 0)
s_stepper_direction = 1;
else
{
s_stepper_direction = -1;
count = -count;
}

s_stepper_count = count;
s_stepper_phaseadder = speed;

TACTL |= TAIE; // turn timer ISR on to rotate the motor
}

bool stepper_is_rotating(void)
{
return (TACTL & TAIE) != 0;
}


// Timer_A3 Interrupt Vector (TA0IV) handler
// This ISR is called every 1ms and will drive the stepper motor
#pragma vector=TIMER0_A1_VECTOR
__interrupt void Timer_A(void)
{
static uint16_t old_phaseacc;

old_phaseacc = s_stepper_phaseaccumulator;
TA0IV;
s_stepper_phaseaccumulator += s_stepper_phaseadder;

if ( (old_phaseacc ^ s_stepper_phaseaccumulator) & 0x8000 ) // check if highest bit has overflown
{
s_stepper_position += s_stepper_direction;
P2OUT = (P2OUT & (~((1<<STEPPER_APH) | (1<<STEPPER_BPH)))) | s_step_pattern[s_stepper_position & 0x03];
s_stepper_count--;
if (s_stepper_count == 0)
{
TACTL &= ~TAIE; // turn timer ISR off, because motor is not rotated anymore
}
}
}

Thank in Advance

Best regards
Hassan

3 Replies

  • Hi Hassan,

    Could you post the link to the wiki that you found this code in?

    Phil Beard
    Motor Applications Team

    ------------------------------------------------------------------------------------------------------------------------------------------------
                  Please Click the Verify Answer button on this post if your question has been answered.  Thank you
    ------------------------------------------------------------------------------------------------------------------------------------------------

  • In reply to Phil Beard:

    Hi Phil,
    of corse !
    processors.wiki.ti.com/.../MSP430StepperMotor
    I want really understand it! Especially the 90 ° shift between the two signals
    Thank in advance
    Best regards
    Hassan
  • In reply to Boudache Hassan:

    Hi Boudache,
    That interrupt is being called much faster than the frequency of the PWM output. It waits until the counter variables exceed a certain value and then traverses through the next step configuration in the array. You'll notice that each array element has 2 pins, and that only one of them changes at a time.

    So each time the 0x8000 bit is set in either old_phaseacc or s_stepper_phaseaccumulator, the stepper position (index for step pattern array) is incremented. Then APH and BPH outputs are cleared and set to the new step pattern on the same line (#102), you'll notice the index is &'ed with 0x3 to prevent index overflow.

    Let me know if that does not answer your question.

    Best regards,

    Cameron P. LaFollette


    If this answers your question, PLEASE, click on the  Verify Answer  button below! :-)