วันอาทิตย์ที่ 20 พฤศจิกายน พ.ศ. 2559

arduino mega 1280 2560 3 phase sine wave pwm

//Auto Rerun 3 sinus motor controller Arduino mini 168 Arduino 328 P #define UN (400.0) //napiecie znamionowe silnika #define FN (50.0) //czestotliwosc znamionowa silnika #define P (UN/FN) //wsp. okreslajacy proporcje napiecia do czestotliwoci znamionowej #define T_PWM (0.000255) //okres sygnalu PWM - ustawiony przez preskaler w licznikach #define T_MAX (4.0) //okreslenie maksymalnego okresu napiecia wyjsciowego #define T_MIN (0.02) //minimalny okres napiecia wyjsciowego #define K_MAX floor(T_MAX/T_PWM) //liczba wartosci okresu dla T_MAX #define K_MIN ceil(T_MIN/T_PWM) //liczba wartosci okresu dla T_MIN volatile static unsigned int dlugosc_tab_sin; //zmienna zawierajaca liczbe wartosci w pelnym //okresie napiecia wyjsciowego static unsigned int i = 0; //zmienna pomocniacza volatile static unsigned int licznik_glowny = 0;//zmienna wystepujaca w przerwaniu czyklicznie //^ co okres T_PWM zwiekszajaca swoja wartosc o 1 static unsigned int next_value_sin = 0; //zmienna ktora wartosc sin nalezy obliczyc static double t_param=100; //parametr okreslajacy okres napiecia wyjsciowego static float t = T_PWM; //T_PWM static float omega_t; //pulsacja napiecia wyjsciowego pomnozona przez T_PWM static float t_out; //okres wyjsciowy napiecia static float U_o_param; //parametr okreslajacy wielkosc napiecie wyjsciowego //^ obliczony na podstawie t_out i U_in static unsigned int ocr0a, ocr0b, ocr1a;//zmienne pomocnicze do przechowywania obl. wypelnien static unsigned int ocr1b, ocr2a, ocr2b;//^ static double sin_in; //zmienna zawierajaca parametr funkcji sin static double blad = 1; //zmienna uzyta do zatrzymania generowania napiecia przy przeciazeniu static unsigned int analog=0; //zmienna zawierajaca zmierzona wartosc static double U_in = 0; //zmienna przechowujนca pomiar napiecia ukladu posredniczacego static double U_rms_max; //maksymalna aktualnie mozliwa do generacji wartosc skuteczna napiecia static bool a=0; //zmienna logiczna do realizacji dwoch naprzemiennych pomiarow int main() { io_init(); //inicjalizacja wejsc i wyjsc timers_init(); //inicjalizacja licznikow PWM adc_init(); //inicjalizacja przetwornika ADC while(1) //nieskonczona petla z programem glownym { if(i==185) //warunek okreslajacy wejscie do funkcji zmiany { //parametrow napiecia wysjciowego, wywolanie co okolo 100ms zmien_predkosc(); //funkcja zmiany parametrow napiecia wyjsciowego i=0; } next_value_sin = licznik_glowny%dlugosc_tab_sin; //kolejna wartoœๆ sinusa do obliczenia sin_in=omega_t*next_value_sin; /*obliczenie wartosci do rejestrow okreslajacych wypelnienie sygnalu wyjscioweg*/ ocr0a = round(blad*(U_o_param*(sin(sin_in)+1)*254/2)+1);//pin 6 ocr0b = ocr0a - 1; ocr1a = round(blad*(U_o_param*(sin(sin_in-2.09)+1)*254/2)+1);//pin 9 ocr1b = ocr1a - 1; ocr2a = round(blad*(U_o_param*(sin(sin_in+2.09)+1)*254/2)+1);//pin 11 ocr2b = ocr2a - 1; /*uaktualnienie wartosci w rejestrach*/ cli(); //zabronienie na obsloge przerwan na wypadek gdyby //podczas uaktualniania wystapilo przerwanie OCR0A = ocr0a; //pin 6 OCR0B = ocr0b; //pin 5 OCR1AL = ocr1a; //pin 9 OCR1BL = ocr1b; //pin 10 OCR2A = ocr2a; //pin 11 OCR2B = ocr2b; //pin 3 sei(); //zezwolenie na obsloge przerwan i++; } } void adc_init() { ADCSRA |= _BV(ADEN);//uruchomienie przetwornika ADCSRA |= _BV(ADPS2);//ustawienie preskalera ADCSRA |= _BV(ADPS1);//^ ADCSRA |= _BV(ADPS0);//^ ADMUX |= _BV(REFS0);// napiecie odniesienia ustawione jako napiecie zasilania ADMUX |= ADMUX &= 0b11110000; //wybranie wejscia ADC0 do pomiaru } void timers_init() { cli(); // obsloga przerwan zabroniona //timer0 init TCCR0A |= _BV(COM0A1) | _BV(COM0B0) | _BV(COM0B1) | _BV(WGM00); TCCR0B |= _BV(CS01); //preskaler 8 TIMSK0 |= _BV(TOIE0); //flaga od wartosci 0 wlaczona //timer1 init TCCR1A |= _BV(COM1A1) | _BV(COM1B0) | _BV(COM1B1) | _BV(WGM10); TCCR1B |= _BV(CS11); //preskaler 8 //timer2 init TCCR2A |= _BV(COM2A1) | _BV(COM2B0) | _BV(COM2B1) | _BV(WGM20); TCCR2B |= _BV(CS21); //preskaler 8 //zerowanie wartosci licznik๓w TCNT0 = 0; TCNT1L = 0; TCNT2 = 0; /* licznik zlicza w g๓re do 255, nastepnie w d๓ณ: /\/\/\ przy wartosci 255 jest przerwanie przy ktorym dokonuje sie pomiarow napiec i pradow */ sei(); //zezwolenie na obsloge przerwan } void io_init() { pinMode(6, OUTPUT); //OC0A pinMode(5, OUTPUT); //OC0B pinMode(9, OUTPUT); //OC1A pinMode(10, OUTPUT);//OC1B pinMode(11, OUTPUT);//OC2A pinMode(3, OUTPUT); //OC2B pinMode(2, INPUT); pinMode(4, INPUT); pinMode(12, OUTPUT); pinMode(13, OUTPUT); } ISR(TIMER0_OVF_vect) //przerwanie przy wartosci 0 licznika0 { analog = ADC; if(a) { U_in = 0.0709*analog; ADMUX |= _BV(MUX0); //wybranie wejscia ADC1 do pomiaru pradu } else { ADMUX |= ADMUX &= 0b11110000; //wybranie wejscia ADC0 do pomiaru napiecia if(analog>579) { blad = 0; //jezeli przeciazenie wylaczenie generacji napiecia digitalWrite(12, HIGH); //zapalenie diody } } ADCSRA |= _BV(ADSC);//start odczytywania pomiaru a=a^1; //bramka XOR neguje wartosc logiczna a licznik_glowny++; if(licznik_glowny>=dlugosc_tab_sin) licznik_glowny = 0; } void zmien_predkosc() { t_param = map(analogRead(3),0,1023,0,100); U_rms_max = U_in*0.62; //wartosc 0.62 wyzanczona eksperymentalnie bool up; //zmienna logiczna, informuje o nacisnietym przycisku zwieksz czestotliwosc bool down; //zmienna logiczna, informuje o nacisnietym przycisku zmiejsz czestotliwosc up = digitalRead(4); //odczyt: czy nacisniety przycisk zwieksz czestotliwosc down = digitalRead(2); //odczyt: czy nacisniety przycisk zmiejsz czestotliwosc if(up==1) t_param--; //jezeli nacisniety przycisk zwieksz czestotliwosc to zmiejsz okres if(down==1) t_param++; //jezeli nacisniety przycisk zmniejsz czestotliwosc to zwieksz okres if(t_param<0) t_param=0; //zabezpieczenie przekroczenia wartosci skrajnych if(t_param>100) t_param=100;//^ dlugosc_tab_sin = ceil((K_MAX-K_MIN)*t_param/500+K_MIN);//ilosc wartosci wypelnien w jednym okresie t_out = T_PWM*dlugosc_tab_sin; //obliczenie okresu napiecia wyjsciowego omega_t = t*2*PI/t_out; //obliczenie pulsacji napiecia wyjsciowego U_o_param = (P/t_out)/U_rms_max; //obliczenie parametru okreslajacego wielkosc napiecia wyjsciowego if(t_out>1) U_o_param = 0.5*(18.5/U_rms_max); //napi๊cie na wyjsciu przy niskiej czestotliwosci 10V if(U_o_param>1) U_o_param=1; //zabezpieczenie przekroczenia wartosci skrajnych blad = 1; //jezeli przeciazenie wylaczenie generacji napiecia //digitalWrite(13, HIGH); //zapalenie diody //jezeli przeciazenie wylaczenie generacji napiecia digitalWrite(12, LOW); //zapalenie diody }

1 ความคิดเห็น:

  1. B1) | _BV(WGM20);
    TCCR2B |= _BV(CS21); //preskaler 8
    //zerowanie wartosci licznik๓w
    TCNT0 = 0;
    TCNT1L = 0;
    TCNT2 = 0;
    /* licznik zlicza w g๓re do 255, nastepnie w d๓ณ: /\/\/\
    przy wartosci 255 jest przerwanie przy ktorym dokonuje sie
    pomiarow napiec i pradow
    */
    sei(); //zezwolenie na obsloge przerwan
    }
    void io_init()
    {
    pinMode(6, OUTPUT); //OC0A
    pinMode(5, OUTPUT); //OC0B
    pinMode(9, OUTPUT); //OC1A
    pinMode(10, OUTPUT);//OC1B
    pinMode(11, OUTPUT);//OC2A
    pinMode(3, OUTPUT); //OC2B
    pinMode(2, INPUT);
    pinMode(4, INPUT);
    pinMode(12, OUTPUT);
    pinMode(13, OUTPUT);
    }
    ISR(TIMER0_OVF_vect) //przerwanie przy wartosci 0 licznika0
    {
    analog = ADC;
    if(a)
    {
    U_in = 0.0709*analog;
    ADMUX |= _BV(MUX0); //wybranie wejscia ADC1 do pomiaru pradu
    }
    else
    {
    ADMUX |= ADMUX &= 0b11110000; //wybranie wejscia ADC0 do pomiaru napiecia
    if(analog>579)
    {
    blad = 0; //jezeli przeciazenie wylaczenie generacji napiecia
    digitalWrite(12, HIGH); //zapalenie diody
    }
    }
    ADCSRA |= _BV(ADSC);//start odczytywania pomiaru
    a=a^1; //bramka XOR neguje wartosc logiczna a
    licznik_glowny++;
    if(licznik_glowny>=dlugosc_tab_sin) licznik_glowny = 0;
    }
    void zmien_predkosc()
    {
    t_param = map(analogRead(3),0,1023,0,100);
    U_rms_max = U_in*0.62; //wartosc 0.62 wyzanczona eksperymentalnie
    bool up; //zmienna logiczna, informuje o nacisnietym przycisku zwieksz czestotliwosc
    bool down; //zmienna logiczna, informuje o nacisnietym przycisku zmiejsz czestotliwosc
    up = digitalRead(4); //odczyt: czy nacisniety przycisk zwieksz czestotliwosc
    down = digitalRead(2); //odczyt: czy nacisniety przycisk zmiejsz czestotliwosc
    if(up==1) t_param--; //jezeli nacisniety przycisk zwieksz czestotliwosc to zmiejsz okres
    if(down==1) t_param++; //jezeli nacisniety przycisk zmniejsz czestotliwosc to zwieksz okres
    if(t_param<0) t_param=0; //zabezpieczenie przekroczenia wartosci skrajnych if(t_param>100) t_param=100;//^
    dlugosc_tab_sin = ceil((K_MAX-K_MIN)*t_param/500+K_MIN);//ilosc wartosci wypelnien w jednym okresie
    t_out = T_PWM*dlugosc_tab_sin; //obliczenie okresu napiecia wyjsciowego
    omega_t = t*2*PI/t_out; //obliczenie pulsacji napiecia wyjsciowego
    U_o_param = (P/t_out)/U_rms_max; //obliczenie parametru okreslajacego wielkosc napiecia wyjsciowego
    if(t_out>1) U_o_param = 0.5*(18.5/U_rms_max); //napi๊cie na wyjsciu przy niskiej czestotliwosci 10V
    if(U_o_param>1) U_o_param=1; //zabezpieczenie przekroczenia wartosci skrajnych
    blad = 1; //jezeli przeciazenie wylaczenie generacji napiecia
    //digitalWrite(13, HIGH); //zapalenie diody
    //jezeli przeciazenie wylaczenie generacji napiecia
    digitalWrite(12, LOW); //zapalenie diody
    }

    ตอบลบ