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