This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

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

4 Replies

  • Hi Hassan,

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

    Phil Beard
    Motor Applications Team

  • 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

  • In reply to Cameron LaFollette:

    Hello Cameron,

    Sorry for my late answer. I was abroad
    Very well explained.
    I tried to understand the speed of the stepper, but I could not figure out how fast is it. Since the unit is missing.
    and the other question is: How is the relationship between the frequency and the decimal numbers in the folowing code section in the header "stepper.h".
    * rotate stepper with a specified amount of steps. The sign of "count" specifies the direction.
    * speed sets the rotation speed:
    * 32767 = 10 kHz
    * 3268 = 1 kHz
    * 327 = 100 Hz
    * 32 = 10 Hz
    * 3 = 1 Hz
    * All values inbetween are possible, the relation is linear
    *
    * The rotate function also enables the driver stages
    *
    * This function returns, even if the motor rotation is not finished (= asynchronous)*/


    Thank you in advance
    Hassan

This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.