Hallo Zusammen, also, wir möchten einen Phasenanschnittsteuerung über eine W4 Sparschaltung Realisieren, die es ermöglichen soll eine DAM im 1+4 Quadranten Sanft Hochlaufen zu lassen bzw. zu Reversieren. Gesteuert wird das ganze über einen Poti mit 1024 Werten/Bits. Abhängig von den Stellung des Ptotis wird eine Rampenfunktion für Alpha generiert und zwar so, dass wenn der Poti in der Mittesteht (Potiwert 400-600) der Maschine steht. Potiwert 400->0 Linkslauf Potiwert 400->600 Stillstand Potiwert 600->1023 Rechtslauf. Für sich genommen Funktionieren Linkslauf und Rechtslauf auch wunderbar, das Problem entsteht erst wenn alle Programmteile zusammengefügt werden. Hier kommt es zu einem Rütteln was auf Fehlzündungen hindeutet, bzw. auch schon zur Zerstörung Triacs geführt hat. Im Stillstand werden alle Zündimpulse ausgeschaltet, zusätzlich alle Timer und Comparewerte zurückgesetzt und zu guter letz die Initialisierung wiederholt und auf Nummer sicherzugehen, da eine Falsches Zünden der Triacs diese ja zerstören würde. Der µC ist eine Atmega16. Vielen Dank schonmahl für Anregungen und Tipps. Quellcode. /************************************PHASENANSCHNITTSTEUERUNG*********** *************************************** Microcontroller: ATMEGA2561 Clock: 16.0000MHz AVR Hardware: Timer1, Timer3, externe Hardware: W4-Reversiersparschaltung //------------------------------------------------------------------ // // PowerModul // #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 DDRT3 DDRA #define DDRT4 DDRF #define PORTT1 PORTG #define PORTT2 PORTF #define PORTT3 PORTA #define PORTT4 PORTF #define T1 PG5 //rechts L1 Ausgangsbits für das W4 Stellglied #define T2 PF3 //rechts L3 #define T3 PA2 //Links L3 #define T4 PF1 // Links L1 Ausgangsbits für das W4 Stellglied //********************************************************************** **********//POTI uint16_t ADC_Wert; //int ADC_Wert_min_R = 600; //int ADC_Wert_max_R = 1023; float alpha1=0; float alpha2=0; int alpha1_min=12777; int alpha1_max=18888; int alpha2_min=32777; int alpha2_max=38888; float alpha1_Aus =0; float alpha2_Aus =0; int alpha1_min_Aus =18888; int alpha1_max_Aus =18888; int alpha2_min_Aus =38888; int alpha2_max_Aus =38888; //********************************************************************** ********** //*************************************ADC****************************** ********** void AdcInit (void) { ADMUX |= (0<<MUX0) | (0<<MUX1) | (1<<MUX2); //ADC4 ADMUX |= (1<<REFS0); //externe Referenzspannung nutzen 5 V ADCSRA |=(1<<ADEN); //ADC überhaupt zu aktivieren. ADMUX |= (0<< ADLAR); // Die 8 bit kommen in das Low-Register ADCSRA |=(1<<ADSC); //Messvorgang startet. ADCSRA |=(1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);//Vorteiler 128 } uint16_t ADC_Lesen(void) { uint16_t result = 0; ADCSRA |=(1<<ADEN); //ADC aktivieren. ADCSRA |= (1<<ADSC); // eine Wandlung "single conversion" while (ADCSRA & (1<<ADSC) ); // auf Abschluss der Konvertierung warten ADCSRA &= ~(1<<ADEN); // ADC wieder deaktivieren result = ADCW; return result; // ADC auslesen und zurückgeben } //********************************************************************** ********** // Funktionen //********************************************************************** ********** // Initialisierung W2 Stellglied // diese funktionen in main 1x aufrufen /*****************************PORT-Initialisierung*****************/ void w4Init(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); DDRT3 |= (1<<T3); DDRT4 |= (1<<T4); PORTT1= 0x00; // PORTG high aktiv PORTT2= 0x00; // PORTF high aktiv PORTT3= 0x00; // PORTA high aktiv PORTT4= 0x00; // PORTF high aktiv //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<<OCIE1C) | (1<<OCIE1B) | (1<<OCIE1A) | (1<<TOIE1); // TIMSK1=0b00001111; //compare Register A B C // 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*/ TCNT1 = 0; // Timer1 auf Null setzen OCR1C=7222; TCCR1B= 0x02; //Vorteiler 8 //start Timer } /*****************************Initialisierung Timer/Counter4*********************************/ void Timer4Init(void) { TCCR4B=0x00; //stop Timer // Damit Timer bei 0 anfängt TCCR4A= 0x00; //normal Mode // Inkrementale Aufzählung // Interrupts TimerCounter1 aktivieren TIMSK4 |= (1<<OCIE4B) | (1<<OCIE4A) | (1<<TOIE4); // TIMSK1=0b00001111; //compare Register A B // 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*/ TCNT4 = 0; // Timer1 auf Null setzen TCCR4B= 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<<OCIE3B) | (1<<OCIE3A) | (1<<TOIE3); // TIMSK1=0b00001111; //compare Register A B TCNT3 = 0; // Timer3 auf Null setzen// TCCR3B= 0x02; //Vorteiler 8 //start Timer } /*****************************Initialisierung Timer/Counter5*********************************/ void Timer5Init(void) { TCCR5B=0x00; //stop Timer // Damit Timer bei 0 anfängt TCCR5A= 0x00; //normal Mode // Inkrementale Aufzählung // Interrupts TimerCounter1 aktivieren TIMSK5 |= (1<<OCIE5B) | (1<<OCIE5A) | (1<<TOIE5); // TIMSK1=0b00001111; //compare Register A B TCNT5 = 0; // Timer1 auf Null setzen TCCR5B= 0x02; //Vorteiler 8 //start Timer } /******************************EXTERNER Interrupt*****************/ ISR (INT1_vect) //INT1 hinter RESET höchste Priorität //Netzsynchronisation { // wird jedesmal aufgerufen wenn der Netznullgang kommt alphawerteInterrupt1(); }//ISR(INT1_vect) /***************************ZÜNDMUSTER_RECHSTSLAUF ********************/ ISR (TIMER1_COMPA_vect) { zuendmustereinL1(); //positive Halbwelle //zuendEinL1(); } ISR (TIMER1_COMPB_vect) { zuendmustereinL1(); //Negative Halbwelle //zuendEinL1(); } ISR (TIMER1_COMPC_vect) { alphawertetimer1compC(); }//ISR_timer1_compC ISR (TIMER4_COMPA_vect) { zuendmusterausL1(); //positive Halbwelle //zuendAusL1(); } ISR (TIMER4_COMPB_vect) { zuendmusterausL1(); //Negative Halbwelle //zuendAusL1(); } ISR (TIMER3_COMPA_vect) { zuendmustereinL3(); //positive Halbwelle //zuendEinL3(); } ISR (TIMER3_COMPB_vect) { zuendmustereinL3(); //Negative Halbwelle //zuendEinL3(); } ISR (TIMER5_COMPA_vect) { zuendmusterausL3(); //Positive Halbwelle //zuendAusL3(); } ISR (TIMER5_COMPB_vect) { zuendmusterausL3(); //Negative Halbwelle //zuendAusL3(); } //********************************INITIALISIERUNG******************* void Init() { w4Init(); Timer1Init(); Timer4Init(); Timer3Init(); Timer5Init(); AdcInit(); } //*****************************HAUPT-PROGRAMM********************/ int main() { cli(); //disable Interrupts Init(); sei(); //alles initialisiert while(1) { ADC_Wert= ADC_Lesen(); } } /****************************************************Funktionen********* ****************************************************/ void zuendungaus(void) { Init(); PORTT1 &= ~ (1<<T1); //triac für rechtslauf auf low setzten //zuendAusL1(); PORTT2 &= ~ (1<<T2); //triac für rechtslauf auf low setzten //zuendAusL3(); PORTT3 &= ~ (1<<T3); //triac für Linkslauf auf low setzten //zuendAusL3(); PORTT4 &= ~ (1<<T4); //triac für Linkslauf auf low setzten //zuendAusL1(); TCNT1= 0; OCR1A= 0; OCR1B= 0; TCNT4= 0; OCR4A= 0; OCR4B= 0; //----------------------------------------------------------------- TCNT3= 0; OCR3A= 0; OCR3B= 0; TCNT5= 0; OCR5A= 0; OCR5B= 0; }//Zuendungaus void alphawerteInterrupt1(void) { if ((ADC_Wert >= 600) && (ADC_Wert <= 1023)) { if ((ADC_Wert >= 1013) && (ADC_Wert <= 1023)) { vollsteuerungL1 (); }//if//vollsteuerung//rechtslauf if ((ADC_Wert >= 600) && (ADC_Wert < 1013)) { alpha1=(((alpha1_min - alpha1_max)/(1013-600))* (ADC_Wert-600))+ alpha1_max; //rechtslauf(); alpha2=(((alpha2_min - alpha2_max)/(1013-600))* (ADC_Wert-600))+ alpha2_max; TCNT1= 0; // Timer1 wird bei Nulldurchgang auf null gesetzt OCR1A=alpha1 ; OCR1B=alpha2; //----------------------------------------- alpha1_Aus=(((alpha1_min_Aus - alpha1_max_Aus)/(1013 - 600))* (ADC_Wert - 600))+ alpha1_max_Aus; alpha2_Aus=(((alpha2_min_Aus - alpha2_max_Aus)/(1013 - 600))* (ADC_Wert - 600))+ alpha2_max_Aus; TCNT4= 0; // Timer4 wird bei Nulldurchgang auf null gesetzt OCR4A= alpha1_Aus; //18888; OCR4B= alpha2_Aus; //38888; } }//if//rechtslauf if ((ADC_Wert >= 0) && (ADC_Wert <= 400)) { if ((ADC_Wert >=0) && (ADC_Wert <= 10)) { vollsteuerungL1 (); }//if//vollsteuerung//linkslauf if ((ADC_Wert > 10) && (ADC_Wert <= 400)) { alpha1=(((alpha1_max - alpha1_min)/(400-10))* ADC_Wert)+ alpha1_min; //linkslauf(); alpha2=(((alpha2_max - alpha2_min)/(400-10))* ADC_Wert)+ alpha2_min; TCNT1= 0; // Timer1 wird bei Nulldurchgang auf null gesetzt OCR1A=alpha1 ; OCR1B=alpha2; //--------------------------------------- alpha1_Aus=(((alpha1_max_Aus - alpha1_min_Aus)/(400 - 10))* (ADC_Wert - 10))+ alpha1_min_Aus; alpha2_Aus=(((alpha2_max_Aus - alpha2_min_Aus)/(400 - 10))* (ADC_Wert - 10))+ alpha2_min_Aus; TCNT4= 0; // Timer4 wird bei Nulldurchgang auf null gesetzt OCR4A= alpha1_Aus; //18888; OCR4B= alpha2_Aus; //38888; } }//if//Linkslauf if ((ADC_Wert > 400) && (ADC_Wert < 600)) { zuendungaus(); }//if//Zuendungaus }//alphawerteInterrupt1 void alphawertetimer1compC(void) { if ((ADC_Wert >= 600) && (ADC_Wert <= 1023)) { if ((ADC_Wert >= 1013) && (ADC_Wert <= 1023)) { vollsteuerungL3 (); }//if//vollsteuerung//rechtslauf if ((ADC_Wert >= 600) && (ADC_Wert < 1013)) { alpha1=(((alpha1_min - alpha1_max)/(1013-600))* (ADC_Wert-600))+ alpha1_max; //rechtslauf(); alpha2=(((alpha2_min - alpha2_max)/(1013-600))* (ADC_Wert-600))+ alpha2_max; OCR3A=alpha1; OCR3B=alpha2; //---------------------------------------------------------- alpha1_Aus=(((alpha1_min_Aus - alpha1_max_Aus)/(1013 - 600))* (ADC_Wert - 600))+ alpha1_max_Aus; alpha2_Aus=(((alpha2_min_Aus - alpha2_max_Aus)/(1013 - 600))* (ADC_Wert - 600))+ alpha2_max_Aus; OCR5A= alpha1_Aus; //18888; OCR5B= alpha2_Aus; //38888; } }//if//rechtslauf if ((ADC_Wert >= 0) && (ADC_Wert <= 400)) { if ((ADC_Wert >=0) && (ADC_Wert <= 10)) { vollsteuerungL3 (); }//if//vollsteuerung//linkslauf if ((ADC_Wert > 10) && (ADC_Wert <= 400)) { alpha1=(((alpha1_max - alpha1_min)/(400-10))* ADC_Wert)+ alpha1_min; //linkslauf(); alpha2=(((alpha2_max - alpha2_min)/(400-10))* ADC_Wert)+ alpha2_min; TCNT3= 0; // Timer3 wird nach 3,33ms (60°) auf null gesetzt OCR3A=alpha1; OCR3B=alpha2; //------------------------------------------------------------------ alpha1_Aus=(((alpha1_max_Aus - alpha1_min_Aus)/(400 - 10))* (ADC_Wert - 10))+ alpha1_min_Aus; alpha2_Aus=(((alpha2_max_Aus - alpha2_min_Aus)/(400 - 10))* (ADC_Wert - 10))+ alpha2_min_Aus; TCNT5= 0; // Timer5 wird nach 3,33ms (60°) auf null gesetzt OCR5A= alpha1_Aus; //18888; OCR5B= alpha2_Aus; //38888; } }//if//Linkslauf if ((ADC_Wert > 400) && (ADC_Wert < 600)) { zuendungaus(); }//if//Zuendungaus }//alphawertetimer1compC void zuendmustereinL3(void) { if ((ADC_Wert >= 0) && (ADC_Wert <= 400)) { PORTT2 &= ~ (1<<T2); //????????????????????????????????? PORTT3 |= (1<<T3); //triac für Linkslauf zünden //zuendEinL3(); PORTB &= ~(1<<PB1); // Grüne Led geht an //linkslauf(); } if ((ADC_Wert > 400) && (ADC_Wert < 600)) { zuendungaus(); } if ((ADC_Wert >= 600) && (ADC_Wert <= 1023)) { PORTT3 &= ~ (1<<T3);//??????????????????????????????? PORTT2 |= (1<<T2); //triac für rechtslauf zünden //zuendEinL3(); PORTB &= ~(1<<PB1); // Grüne Led geht an//rechtslauf(); } } void zuendmusterausL3(void) { if ((ADC_Wert >= 0) && (ADC_Wert <= 400)) { PORTT3 &= ~ (1<<T3); //triac für Linkslauf auf low setzten //zuendAusL3();//linkslauf(); } if ((ADC_Wert > 400) && (ADC_Wert < 600)) { zuendungaus(); } if ((ADC_Wert >= 600) && (ADC_Wert <= 1023)) { PORTT2 &= ~ (1<<T2); //triac für rechtslauf auf low setzten //zuendAusL3();//rechtslauf(); } } void zuendmustereinL1(void) { if ((ADC_Wert >= 0) && (ADC_Wert <= 400)) { PORTT1 &= ~ (1<<T1);//??????????????????????????????? PORTT4 |= (1<<T4); //triac für Linkslauf zünden //zuendEinL1(); PORTB &= ~(1<<PB1); // Grüne Led geht an //linkslauf(); } if ((ADC_Wert > 400) && (ADC_Wert < 600)) { zuendungaus(); } if ((ADC_Wert >= 600) && (ADC_Wert <= 1023)) { PORTT4 &= ~ (1<<T4); //????????????????????????????????????????ß PORTT1 |= (1<<T1); //triac für rechtslauf zünden //zuendEinL1(); PORTB &= ~(1<<PB1); // Grüne Led geht an //rechtslauf(); } } void zuendmusterausL1(void) { if ((ADC_Wert >= 0) && (ADC_Wert <= 400)) { PORTT4 &= ~ (1<<T4); //triac für Linkslauf auf low setzten //zuendAusL1();//linkslauf(); } if ((ADC_Wert > 400) && (ADC_Wert < 600)) { zuendungaus(); } if ((ADC_Wert >= 600) && (ADC_Wert <= 1023)) { PORTT1 &= ~ (1<<T1); //triac für rechtslauf auf low setzten //zuendAusL1();//rechtslauf(); } } void vollsteuerungL1 (void){ TCNT1= 0; OCR1A= 2777; OCR1B= 22777; TCNT4= 0; OCR4A= 0; OCR4B= 0; } void vollsteuerungL3 (void){ TCNT3= 0; OCR3A= 2777; OCR3B= 22777; TCNT5= 0; OCR5A= 0; OCR5B= 0; }
:
Verschoben durch Admin
@ Tobi (Gast) > * W4_schaltung.aps (3,3 KB, 7 Downloads) >Vielen Dank schonmahl für Anregungen und Tipps. Lies mal was über Netiquette und Bildformate. Lange Quelltexte gehören in den Anhang! .aps kennt kaum jemand. MFG Falk
Vor allem, da .aps eine Projektdatei ist. Da ist kein Quellcode enthalten! Schaltplan wäre auch nett, nicht jedem sagt w4 Sparschaltung was.
Schau mal da explodiert nix: Beitrag "Hilfe Triacs explodieren" Zeig mal ein Bild vom explodierten Triac, Video wäre natürlich noch besser.
Floh schrieb: > nicht jedem sagt w4 Sparschaltung was. Google meint dazu: Sparschaltung an WC-Spülungen W4/W5 Und bei DAM: http://www.dam-germany.de/ Peter