Hallo, wir brauchen dringend Hilfe, Also, Ziel unseres Programms ist es einen Drehstrommotor (DASM) Sanft hochlaufen zulassen. Zur Verwendung kommt eine W4-Sparschaltung für rechts und linkslauf. Dabei ist L2 direkt am Motorangeschlossen und L1 und L3 werden angeschnitten. Der Mikrocontroller steuert die Zündimpulse für die Triacs. Für den Rechtslauf werden die Triacs T1 und T2 angesteuert. Die Zündimpulsbreite beträgt 1ms. Beim Nulldurchgang werden Timer1 und Timer 4 gestartet, wobei der Startwert für Timer 1 der Zündwinkel Alpha ist, (Timer 4=0). Die Aufgabe von Timer 4 ist lediglich Timer 3 zu starten nämlich nach 80°.(Phasenverschiebung + Ungenauigkeit des Nulldurchgangs (20°)). TCNT1 = Alpha; TCNT4 =0; Der Nulldurchgang erfolgt durch eine Nulldurchgangserkennung wodurch die Zündimpulse auf das Netzsynchronisiert werden. (klares TTL Signal 0V->5V) Beim Erkennen des Nulldurchgangs werden die Timer gestartet. Nun zum Problem. Unser Ziel ist es den Motor Dynamisch hochlaufen zu lassen, dafür müssen aber alle Winkel von ca. 120°->30° Funktionieren. Also haben wir die Winkel erstmahl statisch verändert -> Statisches anschneiden der Spannungen. Also zuerst einmal der Motor Dreht sich (Rechtslauf). Aber nicht gut/bzw. extrem unrund. Die Bauteile scheinen auch in Ordnung zu sein. Für Tipps und Anregungen ist unsere Dankbarkeit gewiss. Der Quellcode ist als Datei angehängt. /************************************PHASENANSCHNITTSTEUERUNG*********** *************************************** Microcontroller: ATMEGA2561 Clock: 16.0000MHz AVR Hardware: Timer1, Timer3, externe Hardware: W4-Reversiersparschaltung Verfasser: Severin Touotsap & Tobias Domnik //------------------------------------------------------------------ // // PowerModul // //------------------------------------------------------------------ // // Zündimpulsgenerierung für W2 Schaltung (Rechtslauf) // //------------------------------------------------------------------ // INT 1 = Nulldurchgang L12 // Es wird für den positiven und negativen Nulldurchgang der // Verketteten Spannung ein Interrupt ausgelöst(INT1). // Da in der positiven und negativen Halbwelle stets die gleichen // Zündvorgänge stattfinden. // Das Programm soll mit einem festen Winkel von Alpha = 60 Grad Die // Triacs T1 und T2 zünden. */ #include <avr/io.h> #include <stdint.h> #include <util/delay.h> #include <avr/interrupt.h> #define DDRT1 DDRG //Datenrichtung für das W2 Stellglied #define DDRT2 DDRF #define PORTT1 PORTG #define PORTT2 PORTF #define T1 PG5 //rechts L1 Ausgangsbits für das W2 Stellglied #define T2 PF3 //rechts L3 int alpha1_90 =52713; //60°=54646; //90°=52713; int alpha3_90 =54935; //60°=56868; //90°=54935; //********************************************************************** ********** // Funktionen //********************************************************************** ********** // Initialisierung W2 Stellglied // diese funktionen in main 1x aufrufen /*****************************PORT-Initialisierung*****************/ void w2Init(void) { // DDRD=0x00; //Eingang Nulldurchgang // Initialisierung Datenrichtung für das W2 Stellglied(als Äusgange festgelegt) DDRT1 |= (1<<T1); //DDRTn sind per (#define) definiert worden DDRT2 |= (1<<T2); //Ausgänge für LED initialisieren DDRB |= (1<<PB1);//(1<<PB1) | (1<<PB2) | (1<<PB3); // Ausprobieren ob alle Led noch leuchten????? } /*****************************Initialisierung Timer/Counter1*********************************/ void Timer1Init(void) { //Timer Clock = CPU Clock / 8 //Mode = 0 (Normal) //TCCR1B= 0x02;//TCCR1B |= (0<<CS10) | (1<<CS11)| (0<<CS12);// CPU Takt / 8 TCCR1B=0x00; //stop Timer // Damit Timer bei 0 anfängt TCCR1A= 0x00; //normal Mode // Inkrementale Aufzählung // Interrupts TimerCounter1 aktivieren TIMSK1 |=(1<<OCIE1A) | (1<<TOIE1); // TIMSK1=0b00000011; //compare Register A // Initialisierung Externe Interrupts / Nulldurchgangserkennung // ND L12 //INT1 Ein = PORTD Pin 1 EIMSK |= (1<<INT1); // EIMSK |= 0b00000010; //enable INT1 // 0x01// Damit wird INT1 aktiviert EICRA |= (1<<ISC11) | (1<<ISC10); /*EICRA |= 0b00001100//0x0c; //00000011 rising; 0x04 anyEdge // INT1 reagiert auf steigende Flanke*/ ///OCR1A= 20000; //OCR1B= 20000; // ist überflüssig nur ein Wert wird verglichen //ICR1 = 0x4e20; //20000 TCNT1= alpha1_90; OCR1A=63535 ; TCCR1B= 0x02; //Vorteiler 8 //start Timer } /*****************************Initialisierung Timer/Counter3*********************************/ void Timer3Init(void) { TCCR3B=0x00; //stop Timer // Damit Timer bei 0 anfängt TCCR3A= 0x00; //normal Mode // Inkrementale Aufzählung // Interrupts TimerCounter1 aktivieren TIMSK3 |= (1<<OCIE3A) | (1<<TOIE3); // TIMSK3=0b00000011; //compare Register A B //OCR3A= 20000; //OCR3B= 20000; // ist überflüssig nur ein Wert wird verglichen //ICR3 = 0x4e20; //20000 TCNT3= alpha3_90; TCCR3B= 0x02; //Vorteiler 8 //start Timer } /*****************************Initialisierung Timer/Counter0*********************************/ void Timer4Init (void){ TCCR4B= 0x00; //stopp Timer TCCR4A= 0x00; //normal Mode TIMSK4= 0x02; //compA EIMSK |= (1<<INT1); // EIMSK |= 0b00000010; //enable INT1 // 0x01// Damit wird INT1 aktiviert EICRA |= (1<<ISC11) | (1<<ISC10); /*EICRA |= 0b00001100//0x0c; //00000011 rising; 0x04 anyEdge // INT1 reagiert auf steigende Flanke*/ TCNT4=0; //1 Takt = 64us bis255=9,984ms // 69 Takte =4,444ms// OCR4A =8880; TCCR4B= 0x02; //0b00000101 //Vorteiler 1024 } /******************************EXTERNER Interrupt*****************/ ISR (INT1_vect) { //INT1 hinter RESET höchste Priorität //Netzsynchronisation // wird jedesmal aufgerufen wenn der Netznullgang kommt TCNT1= alpha1_90; // Timer1 wird bei Nulldurchgang auf null gesetzt TCNT4= 0; // Timer0 wird bei Nulldurchgang auf null gesetzt } /******************************TIMER4 CompareA*****************/ ISR (TIMER4_COMPA_vect) // 4,44 ms { TCNT3= alpha3_90; OCR3A=63535 ; TCNT4=0; } /******************************TIMER1 CompareA*****************/ ISR (TIMER1_COMPA_vect) { cli(); zuendEinL1(); sei(); } /******************************TIMER1 OVF*****************/ ISR (TIMER1_OVF_vect){ cli(); TCNT1= 43535;//65535-pi-1ms OCR1A= 63535;//65535-2000 zuendAusL1(); sei(); } /******************************TIMER3 CompareA*****************/ ISR (TIMER3_COMPA_vect) { cli(); zuendEinL3(); sei(); } /******************************TIMER3 OVF*****************/ ISR (TIMER3_OVF_vect){ cli(); TCNT3= 43535;//65535-pi-1ms OCR3A= 63535;//65535-600 Takte zuendAusL3(); sei(); } /***************************ZÜNDMUSTER_RECHSTSLAUF ********************/ void zuendEinL1(void) { PORTT1 |= (1<<T1); //triac für rechtslauf zünden PORTB &= ~(1<<PB1); // Grüne Led geht an } void zuendAusL1(void) { PORTT1 &= ~ (1<<T1); //triac für rechtslauf auf low setzten } void zuendEinL3(void) { PORTT2 |= (1<<T2); //triac für rechtslauf zünden PORTB &= ~(1<<PB1); // Grüne Led geht an } void zuendAusL3(void) { PORTT2 &= ~ (1<<T2); //triac für rechtslauf auf low setzten } //********************************INITIALISIERUNG******************* void Init() { w2Init(); Timer1Init(); Timer4Init(); Timer3Init(); } //*****************************HAUPT-PROGRAMM********************/ int main() { cli(); //disable Interrupts Init(); sei(); //alles initialisiert //enable Interrupts while(1) { } }
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.