Wo setzt du "flanke" auf 1, wenn "flanke" auf 0 ist warum setzt du sie anschließend wieder auf 0? Ausserdem ist das sicher nicht der ganze Code denn der macht ja wenig Sinn.
Hallo,
ich habe hier im Forum in verschiedenen Beiträgen Ansätze zum Auswerten eines Servosignals vom Empfänger gelesen. Nun habe ich versucht mir daraus mal einen eigenen Versuch zu programmieren um ein solches Signal auszulesen.
Mein Versuch sieht wie folgt aus:
Ich habe mein Signal auf den Eingang INT0 gelegt. Den Timer 1 habe ich mit dem Teiler CPU/8 gestartet (CPU-Takt 8MHz).
Nun wird bei der steigenden Flanke an INT0 ein Interrupt ausgelöst, da setze ich eine Variable, versuche den Counter TCNT1 in eine andere Variable abzulegen und setze den Interrupt auf fallende Flanke.
Bei der fallenden Flanke passiert das selbe in ähnlicher Weise.
Mein µC (zur Zeit Mega16 später auch im MegaCode:void init_timer(void) { // Timer0 (8Bit) TCCR0 |= (1<<CS00) | (1<<CS01); //Vorteiler auf CPU Takt/64 TIMSK |= (1<<TOIE0); //Interupt für Timer0 Overflow einschalten //Timer 1 (16Bit) TCCR1B |= (1<<CS11); //Vorteiler auf CPU Takt/8 } void init_interrupt(void) { MCUCR |= (1<<ISC00) | (1<<ISC01); //INT0 auf Steigende Flanke GICR |= (1<<INT0); //Interrupt von INT0 auf Enable } ISR(INT0_vect) { if (flanke == 1) { start = TCNT1; MCUCR |= (1<<ISC01); } if (flanke == 0) { stop = TCNT1; MCUCR |= (1<<ISC00) | (1<<ISC01); //INT0 auf Steigende Flanke flanke = 0; } }scheint auch auf die Impulse vom Empfänger zu reagieren, also ein Interrupt wird ausgelöst.
Mit dem Timer0 lasse ich einen Zähler hochzählen der mir dann durch If anweisungen Ausgänge setzt oder rücksetzt.
Mein Problem:
Sobald ich den Empfängerimpuls anschließe wird nur noch der Interrupt ausgeführt, das restliche Programm läuft nicht mehr ab.
Da ich hier schon öfter davon gelesen habe, meine ich das auch mehrere Impulse ausgewertet werden können und trotzdem noch komplexe Programme ausgeführt werden.
Was mache ich falsch?
Ist der Code im Interrupt zu Zeitaufwendig? (Frequenz ist 50Hz Impulslänge von 1ms bis 2ms)
Ist mein auslesen des Counterregisters richtig? (beim 8Bit Timer ging es so)
Ich hoffe ich habe mein Problem ausführlich genug beschrieben, sonst bitte einfach nachfragen. Bin noch am Anfang mit der C-Programmiererei.
Danke schon einmal im voraus für die Hilfe
mfG Henry
Wo setzt du "flanke" auf 1, wenn "flanke" auf 0 ist warum setzt du sie anschließend wieder auf 0? Ausserdem ist das sicher nicht der ganze Code denn der macht ja wenig Sinn.
Hallo,
nein das ist nicht der ganze Code. Ich dachte die entscheidenen Teile wären die oben genannten.
Das ist jetzt der ganze. Ist ja auch nur ein Testprogrämmchen.Code://Einbinden der Funktionen aus den anderen Dateien extern void init_digital (void); extern void init_timer(void); extern void init_interrupt(void); extern void lcd_writetext(char *text); extern void lcd_ini(void); extern void lcd_gotopos (uint8_t zeile, uint8_t spalte); //Globale Variable volatile int Zaehler; volatile int Zaehler2; volatile int start; volatile int stop; volatile int impuls; volatile int flanke; volatile char impuls1; int main(void) //Hauptprogremm { //Variablen der Steuerwelle 0 bis Reset int LED1 = 0; int LED2 = 250; //int LED3 = 50; //int LED4 = 100; //int LED5 = 0; //int LED6 = 0; //int LED7 = 0; //int LED8 = 0; //int LED9 = 0; //int LED10 = 0; //int LED11 = 0; int test = 300; int Reset = 500; // Ende LED Steuerwellenvorgabe init_digital(); // Ports initialisieren (eigene Funktion) init_timer(); // Timer initialisieren (eigene Funktion) init_interrupt(); lcd_ini(); flanke = 1; //Flankenmerker sei(); //Interupts aktivieren while(1) { if (Zaehler2 == test) { impuls = stop - start; itoa(impuls, impuls1,10); lcd_gotopos(2,1); lcd_writetext("Impd: " + impuls1); } if (PIND & (1<<PIND5)) { PORTC |= (1<<PC5); //Bit1 auf High setzen } // Blaulicht (Blitzer) Transistor T1 if (Zaehler == LED1) { PORTB |= (1<<PB1); //Bit1 auf High setzen } if (Zaehler == LED1 + 50) { PORTB &= ~(1<<PB1); //Bit1 auf Low setzen } if (Zaehler == LED1 + 120) { PORTB |= (1<<PB1); //Bit1 auf High setzen } if (Zaehler == LED1 + 170) { PORTB &= ~(1<<PB1); //Bit1 auf Low setzen } //ENDE Blaulicht (Blitzer) Transistor T1 //**************************************************************************** // Blaulicht (Blitzer) Transistor T2 if (Zaehler == LED2) { PORTB |= (1<<PB2); //Bit2 auf High setzen } if (Zaehler == LED2 + 50) { PORTB &= ~(1<<PB2); //Bit2 auf Low setzen } if (Zaehler == LED2 + 120) { PORTB |= (1<<PB2); //Bit2 auf High setzen } if (Zaehler == LED2 + 170) { PORTB &= ~(1<<PB2); //Bit2 auf Low setzen } //ENDE Blaulicht (Blitzer) Transistor T2 //Zähler Reset if (Zaehler >= Reset) { Zaehler = 0; } //Zähler2 Reset if (Zaehler2 >= Reset) { Zaehler2 = 0; } //**************************************************************************** if (!(PIND & (1<<PIND5))) { PORTC &= ~(1<<PC5); } } //while } //ENDE main ISR(TIMER0_OVF_vect) //Interrupt bei Timer0 Overflow { Zaehler++; Zaehler2++; } ISR(INT0_vect) { if (flanke == 1) { start = TCNT1; MCUCR |= (1<<ISC01); } if (flanke == 0) { stop = TCNT1; MCUCR |= (1<<ISC00) | (1<<ISC01); //INT0 auf Steigende Flanke stellen (Löst Interrupt bei steigendet Flanke an INT0 aus flanke = 0; } }
Flanke wird beim ersten Start des Controllers auf 1 gesetzt und dient nur dazu im Interrupt in die richtige Schleife zu sprinngen.
mfG Henry
Wenn du das Signal direkt vom Empfänger auswerten willst weiss ich nicht was du mit Flankenumschalten willst. Die Zeit für das Servo liegt doch im Abstand der Impulse die der Empfänger ausgibt also nur auf steigende oder fallende Flanke setzen.
Von dem Abgesehen sehe ich nicht wo du auf "flanke =0" stellst.
Ich möchte ja die Impulszeit haben, sonst habe ich ja immer unverändert die 50 Hz.
Wichtig ist Zeit zwischen der steigenden und fallenden Flanke des Impulses
mfG Henry
Dann willst du die bereits dekodierten Impulse für das Servo auswerten. Das ist was anderes.
Ich sehe nicht wo du deinen INT0 initialisierst, nehme an er steht auf steigende Flanke, die steigende Flanke löst den ISR aus, startet den Timer, stellt den INT0 auf fallende Flanke, setzt "flanke" auf 0. Die nächste fallende Flanke löst ISR aus, stoppt den Timer, Timer auslesen,INT0 auf steigende Flanke, "flanke" auf 1. usw.
Ich weiss nicht ganz wo da das Problem liegt.
Hubert
Ja, die steigende Flanke lege ich beim Initialisieren des Interrups fest.
Mein Proglem liegt darin, das die anderen Befehle (If) die mir ein paar LED's zum blinken bringen sollen nicht mehr ausgeführt werden. Die LED's hören auf zu blinken.
Also mein Code sollte demnach funktionieren, oder verstehe ich dich da falsch?
mfG Henry
Dein ISR(INT0_vect) kann nicht funktionieren, ausser du sagst mir wo du auf "flanke =0" umschaltest.
Hallo,
Du hast Recht, ich habe vergessen auf Flanke 0 zu schalten. Ich probiere es mal aus ob es dann klappt.
Melde mich dann noch einmal hier
mfG Henry
Hmm,
das hatte ich wohl versehendlich gelöscht beim testen. Das Programm wird immer noch nicht weiter abgearbeitet wenn ein Impuls anliegt.
Code sieht jetzt so aus:
Code://Einbinden der Funktionen aus den anderen Dateien extern void init_digital (void); extern void init_timer(void); extern void init_interrupt(void); extern void lcd_writetext(char *text); extern void lcd_ini(void); extern void lcd_gotopos (uint8_t zeile, uint8_t spalte); //Globale Variable volatile int Zaehler; volatile int Zaehler2; volatile int start; volatile int stop; volatile int impuls; volatile int flanke; volatile int z1; volatile char impuls1; volatile char z11; int main(void) //Hauptprogremm { //Variablen der Steuerwelle 0 bis Reset int LED1 = 0; int LED2 = 250; //int LED3 = 50; //int LED4 = 100; //int LED5 = 0; //int LED6 = 0; //int LED7 = 0; //int LED8 = 0; //int LED9 = 0; //int LED10 = 0; //int LED11 = 0; int test = 300; int Reset = 500; // Ende LED Steuerwellenvorgabe init_digital(); // Ports initialisieren (eigene Funktion) init_timer(); // Timer initialisieren (eigene Funktion) init_interrupt(); lcd_ini(); flanke = 1; //Flankenmerker z1 = 0; sei(); //Interupts aktivieren while(1) { if (Zaehler2 == test) { impuls = stop - start; itoa(impuls, impuls1,10); itoa(z1, z11,10); lcd_gotopos(2,1); lcd_writetext("Impd: " +impuls1); lcd_gotopos(3,1); lcd_writetext(z11); } if (PIND & (1<<PIND5)) { PORTC |= (1<<PC5); //Bit1 auf High setzen } // Blaulicht (Blitzer) Transistor T1 if (Zaehler == LED1) { PORTB |= (1<<PB1); //Bit1 auf High setzen } if (Zaehler == LED1 + 50) { PORTB &= ~(1<<PB1); //Bit1 auf Low setzen } if (Zaehler == LED1 + 120) { PORTB |= (1<<PB1); //Bit1 auf High setzen } if (Zaehler == LED1 + 170) { PORTB &= ~(1<<PB1); //Bit1 auf Low setzen } //ENDE Blaulicht (Blitzer) Transistor T1 //**************************************************************************** // Blaulicht (Blitzer) Transistor T2 if (Zaehler == LED2) { PORTB |= (1<<PB2); //Bit2 auf High setzen } if (Zaehler == LED2 + 50) { PORTB &= ~(1<<PB2); //Bit2 auf Low setzen } if (Zaehler == LED2 + 120) { PORTB |= (1<<PB2); //Bit2 auf High setzen } if (Zaehler == LED2 + 170) { PORTB &= ~(1<<PB2); //Bit2 auf Low setzen } //ENDE Blaulicht (Blitzer) Transistor T2 //Zähler Reset if (Zaehler >= Reset) { Zaehler = 0; } //Zähler2 Reset if (Zaehler2 >= Reset) { Zaehler2 = 0; } //**************************************************************************** if (!(PIND & (1<<PIND5))) { PORTC &= ~(1<<PC5); } } //while } //ENDE main ISR(TIMER0_OVF_vect) //Interrupt bei Timer0 Overflow { Zaehler++; Zaehler2++; } ISR(INT0_vect) { if (flanke == 1) { start = TCNT1; MCUCR |= (1<<ISC01); //INT0 auf fallende Flanke stellen flanke = 0; } if (flanke == 0) { stop = TCNT1; MCUCR |= (1<<ISC00) | (1<<ISC01); //INT0 auf Steigende Flanke stellen (Löst Interrupt bei steigendet Flanke an INT0 aus flanke = 1; z1++; } }
mfG Henry
Lesezeichen