Gast
#5015455
Hallo liebe Gemeinde,
Ich lerne momentan DDS principle (direct digital synthesis).
Ich möchte das Prinzip benutzen um einen Motor zu steuern.
Auf der Texas Instrument Seite habe ich einen Code gefunden, der DDS
Prinzip benutzt hat. Der Code läuft Supper und werden zwei PWM Signale
erzeugt und um 90° von einander verschoben und das sind die
Voraussetzungen um den Motor drehen zu können.
Ich habe der Code verstanden aber nur bis der Timer Interrupt, da
verstehe ich leider nicht mehr, was da passiert. Die Datei ist
eingefügt. siehe Bitte (stepper.c)
Könnte jemand mir bitte das erklären, wie das wirklich funktioniert? wie
geschieht die 90° Verschiebung? . Oder was tut genau die Funktion im
Interrupt? wird der DAC des µC benutzt? ich benutze msp430g2553
der Code:
/*
* stepper.c
*
*
*/
#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
}
}
}
Vielen Dank im Voraus
Lg
Fabian