Quantcast
Channel: Motor drivers forum - Recent Threads
Viewing all articles
Browse latest Browse all 22023

CCS/DRV8836: DDS priciple

$
0
0

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


Viewing all articles
Browse latest Browse all 22023

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>