Avr ile 3 phase vfd

MRE_06

Üye
Katılım
24 Mar 2015
Mesajlar
232
Puanları
6
Yaş
35
Merhaba. 3 faz Ac induction motor kontrolü için bir kart tasarladım. Motor 200w. Kullandığım işlemci atmega64a . Motor kontrol yöntemin spwm. Daha önce böyle bir çalışma yapmış olan arkadaşlar varsa özellikle software kısmı için yardımlarınızı bekliyorum. Avr494 application note ve microchip An900 application note ları üzerinden gidiyorum şuan. Ilk amacım hız kontrol potansiyometre ile
 
Burada anlatilan space vektor ile surus yontemi. Bu biraz daha karisik. Benim projem için spwm yeterli. Cevap için teşekkürler

Kod:
#ifndef F_CPU
#define F_CPU 8000000UL
#endif

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include <math.h>

/* Reference clock needs to be measured for the crystal per board (about 8MHz).
 * It is then divided by 510.
 * 8M / 510 = 15686.2740
 */
#define REFCLK 15686.274 // TODO: measure me and adjust

// output frequency
#define FREQ_MIN 0   // default: 0
#define FREQ_MAX 60 // default: 60

// pot values might not permit cranking full range so adjust here 
#define POT_MAX 1023 // default: 1023


/*
 * LUT for sin(t) generated (by spreadsheet) using this formula:
 * x = ROUND( (255/2) * (1+SIN((2*PI()) * (t/256))) )
 *
 * where 0 <= t <= 255 ; keeping one period of sine in nvram
 *
 * Keeping LUT is way faster than calculating all the time
 */
const uint8_t sin256[] PROGMEM =
{
//  0   1   2   3   4   5   6   7   8   9   a   b   c   d   e   f
  128,131,134,137,140,143,146,149,152,155,158,162,165,167,170,173, // 00:0f
  176,179,182,185,188,190,193,196,198,201,203,206,208,211,213,215, // 10:1f
  218,220,222,224,226,228,230,232,234,235,237,238,240,241,243,244, // 20:2f
  245,246,248,249,250,250,251,252,253,253,254,254,254,255,255,255, // 30:3f
  255,255,255,255,254,254,254,253,253,252,251,250,250,249,248,246, // 40:4f
  245,244,243,241,240,238,237,235,234,232,230,228,226,224,222,220, // 50:5f
  218,215,213,211,208,206,203,201,198,196,193,190,188,185,182,179, // 60:6f
  176,173,170,167,165,162,158,155,152,149,146,143,140,137,134,131, // 70:7f
  128,124,121,118,115,112,109,106,103,100, 97, 93, 90, 88, 85, 82, // 80:8f
   79, 76, 73, 70, 67, 65, 62, 59, 57, 54, 52, 49, 47, 44, 42, 40, // 90:9f
   37, 35, 33, 31, 29, 27, 25, 23, 21, 20, 18, 17, 15, 14, 12, 11, // a0:af
   10,  9,  7,  6,  5,  5,  4,  3,  2,  2,  1,  1,  1,  0,  0,  0, // b0:bf
    0,  0,  0,  0,  1,  1,  1,  2,  2,  3,  4,  5,  5,  6,  7,  9, // c0:cf
   10, 11, 12, 14, 15, 17, 18, 20, 21, 23, 25, 27, 29, 31, 33, 35, // d0:df
   37, 40, 42, 44, 47, 49, 52, 54, 57, 59, 62, 65, 67, 70, 73, 76, // e0:ef
   79, 82, 85, 88, 90, 93, 97,100,103,106,109,112,115,118,121,124  // f0:ff
};

// phase offsets (n * 255 / 3)
#define A_OFFSET 0   // (0x00)
#define B_OFFSET 85  // (0x55)
#define C_OFFSET 170 // (0xaa)

int freq; // output frequency
const double TUN_K=( 4294967296.0 / REFCLK ); // tuning coefficient

// variables in ISR
volatile uint8_t icnt;            //
volatile uint8_t icnt1;           //
volatile uint8_t c4ms;            // counter incremented every 4ms
volatile unsigned long phaccu; // phase accumulator
volatile unsigned long tune;   // dds tuning word


void GPIO_SETUP(void);
void SETUP_TIMERS(void);

int main(void)
{
    
    GPIO_SETUP();
    sei();
    SETUP_TIMERS();
    
    while(1)
    {
    if(c4ms > 250)
    {
        
        c4ms = 0;
        freq = 50;
        TIMSK&=~(1<<TOIE1); // disable Timer1 interrupt
        tune = TUN_K*freq;       // update DDS tuning word
        TIMSK|=(1<<TOIE1);    // re-enable Timer2 interrupt
    }   
    }
}



void GPIO_SETUP(void)
{
    //OUTPUT PINS
    DDRB|=(1<<PORTB5)|(1<<PORTB6)|(1<<PORTB7); //High Side PWM
    DDRE|=(1<<PORTE3)|(1<<PORTE4)|(1<<PORTE5); //Low Side PWM
    DDRD|=(1<<PORTD1); //Overcurrent LED
    //INPUT PINS
    DDRF&=~(1<<PORTF0); //ADC0
    DDRF&=~(1<<PORTF1); //ADC1
    DDRC&=~(1<<PORTC0); // PEDAL
    DDRC&=~(1<<PORTC1); //MOD_SELECT
}

void SETUP_TIMERS(void)
{
    
   TIMSK&=~(1<<TOIE0);
   TIMSK&=~(1<<TOIE2);
  
   /* Enable Timer 1
  
   TIMSK|=(1<<TOIE1);
  
    /* Enable Timer 3
  
   ETIMSK|=(1<<TOIE3);
  
 
 
  TCCR1B |=(1<<CS10);


TCCR1A|=(1<<WGM10);


  TCCR1A |=(1<<COM1A1)|(1<<COM1B1)|(1<<COM1C1);    // Clear OC1A on compare match -- and --
 
 
 
  TCCR3B |=(1<<CS30);

 
TCCR3A|=(1<<WGM30);

 
  TCCR3A |=(1<<COM3A1)|(1<<COM3A0)|(1<<COM3B1)|(1<<COM3B0)|(1<<COM3C1)|(1<<COM3C0);   
 
}

/**
 * Timer 1 interrupt - 15.6kHz ~= 64us
 * Fout = (tuning word * REFCLK) / 2^32
 * Runtime: 8us (incl stack push + pop)
 */


ISR(TIMER1_OVF_vect)
{
    
    
    phaccu += tune;      // soft DDS, phase accu with 32 bits
    icnt = phaccu >> 24; // use upper 8 bits for phase accu as frequency information

    // read byte from sin256 table using the phase offset as the address
    // place into output compare registers
    OCR1A = pgm_read_byte_near(sin256 + (uint8_t)(icnt + A_OFFSET));
    OCR3A = pgm_read_byte_near(sin256 + (uint8_t)(icnt + A_OFFSET));
    OCR1B = pgm_read_byte_near(sin256 + (uint8_t)(icnt + B_OFFSET));
    OCR3B = pgm_read_byte_near(sin256 + (uint8_t)(icnt + B_OFFSET));
    OCR1C = pgm_read_byte_near(sin256 + (uint8_t)(icnt + C_OFFSET));
    OCR3C = pgm_read_byte_near(sin256 + (uint8_t)(icnt + C_OFFSET));

    if (icnt1++ == 125) // increment variable c4ms every 4 milliseconds
    {
        c4ms++;
        icnt1 = 0;
    }
    
}

Yukarıdaki komutla sinus üretebiliyorum yalnız çıkış frekansı sürekli 2khz civarı sabebi nedir ? Bilen olursa sevinirim
 

Forum istatistikleri

Konular
128,128
Mesajlar
915,267
Kullanıcılar
449,844
Son üye
mehmet.ali.turhan.99@gmai

Yeni konular

Geri
Üst