Forum: Mikrocontroller und Digitale Elektronik Phasenanschnittsteuerung Quellcode


von Tobias (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.