Hallo, ich brauche Hilfe bei dem angehängtem C-Programm. Das Programm habe ich ursprünglich von einer anderen Seite übernommen und es soll nur die LED's an Port B zum blinken bringen (was auch funktioniert). Jetzt habe ich versucht mit einer Schleife die LED's nur 10x blinken zu lassen. Leider blinken sie immer noch in der Endlosschleife. Wie man sieht bin ich noch Anfänger und habe wohl einen kleinen Denkfehler in meinem Programm. Ich habe auch schon versucht die Schleife in die Prozedur "timer" zu integrieren. Dann blinken die LED's aber nur 4x und anschließend leuchtet Port B.3 halb ?!? Ich bin mir sicher, einer von Euch kann mir helfen und mir den richtigen Tipp geben! Danke Ralf
schleifen ;-) unsigned int i; for(i = 0; i<= 9; i++) { //mach was } i = 0; while( i <= 9) { //machwas i++; } i = 0; if(i!=9) { //machwas i++; }
ich verstehe nicht ganz was du mit den letzten 6 zeilen bewirken willst...: i = 0; if(i!=9) { //machwas i++; }
eine prüfung "i ist NICHT 9" wenn i=9 dann ist die schleife zu ende
@Ralf, Deine Schleife initialisiert nur 10-mal den Timer, d.h. sie hat nicht die geringsten Auswirkungen (einmal hätte völlig gereicht). Daß Deine LED aber nur 4* blinkt, ist mir ein Rätsel. Es sein denn Du machst den schlimmsten hier im Forum möglichen Fehler: Du postest einen völlig anderen Code, als den, über den Du sprichst !!! Peter
Also genau genommen, initialisierst Du nur 9x (für 10x: for(i=0; i<10; i++) oder for(i=1; i<=10; i++)). Aber das nur nebenbei. Warum es gerade 4x Blinken ist, kann ich Dir auch nicht beantworten. Folgendes ist jedenfalls falsch an Deinem Code: 1. Mehrfache Initialisierung des Counters mit timer() (Wenn der einmal läuft, wird Deine SIG_OVERFLOW1-Routine bis in alle Ewigkeit aufgerufen, d.h. bis Du den Timer deaktivierst) 2. In dieser Zeit hängt die Blinkrate von Deiner Taktfrequenz und dem gewählten Prescaler ab. 3. Nach Deiner x-fach Initialisierung setzt Du in main() alle LEDs auf aus, bevor Du in die Endlosschleife gehst. Warum? Zur Lösung: 1. Du Initialisierst den Timer 1x!!! und überläßt dann alles der Interrupt-Routine. Wenn die LEDs dann nur 10x Blinken sollen, musst Du dort noch einen Zähler einbauen. 2. Du verzichtest auf den Timer und packst den Blink-Code in Deine Endlosschleife. Im Moment machst Du beides irgendwie zur Hälfte ;-) (siehe Anhang) Grusz TW
@peter dannegger also die angehängte Datei ist korrekt (es ist die, über die ich spreche). Das mit dem initialisieren des Timers leuchtet mir auch ein. d.h. die Schleife müsste dann in der SIGNAL Routine zu finden sein, oder?
hi Ralf, in deiner SIGNAL Routine sollte nur ein counter hochgezählt werden und PORTB invertiert. Wenn du deine maximale Blinkanzahl erreicht hast kannst du ja den Interrupt da ja auch wieder abschalten. Je nachdem kannst du das ganze Zeug aus timer(); auch direkt in dein main schreiben, da du es ja sowieso nur einmal aufrufst.
// So muesste das klappen, aber evtl tappfuhler #include <avr/io.h> #include <avr/interrupt.h> #include <avr/signal.h> volatile char count; //Variable count definieren //Eigentlich ist valatile hier ueberfluessig da nur in der ISR darauf zugeriffen wird SIGNAL (SIG_OVERFLOW1) { if (count != 0) { if((count & 1) == 0) // Geradzahlig = LED an PORTB = 0x00; //Port B auf L setzen - LED an else // Ungerade = LED aus, also ach bei 1, am ende PORTB = 0xFF; //Port B auf H setzen - LED aus count--; //count auf L setzen } else { TCCR1B = 0; // Timer stoppen TIMSK &= ~(1<<TOIE1); //Timer Overflow Interrupt disable } return; } void timerInit (void) { //Prozedur timer TIMSK = (1<<TOIE1); //Timer Overflow Interrupt enable TCNT1 = 0; //Rücksetzen des Timers TCCR1B = (1<<CS11) | (1<<CS10); //Prescaler 64 sei (); //Interrup zulassen } int main (void) { //Hauptprozedur DDRB = 0xff; //Port B als Ausgang definieren PORTB = 0xFF; //Port B auf H setzen - LED aus count = 10*2; // 10 mal einschalten und 10 mal ausschalten = 10 mal blinken timerInit (); // timer starten for (;;){} //Endlosschleife }
Hi Ralf, Dein Programm besteht aus 2 Teilen: main() initialisiert einen Timer-Interrupt und hat NICHTS mit dem Blinken der LEDs an sich zu tun. SIGNAL (SIG_OVERFLOW1) ist der Timer-Interrupt. D.h. diese Funktion wird immer dann aufgerufen, wenn der Timer überläuft. Diese Funktion bewirkt bei Dir das Blinken der LEDs. Einmal initialisiert, läuft sie unabhängig vom Main-Programm. D.h., auch wenn Dein Main in der Endlos-Schleife for(;;); angekommen ist, blinken die LEDs munter weiter. Wenn Du das Blinken auf 10* begrenzen willst, musst Du in der IR-Funktion mitzählen, wie oft sie bereits durchlaufen wurde (2*10 Aufrufe), und danach den IR abschalten. Du hast also bereits Dein erstes C-Programm mit Interrupts geschrieben/kopiert, eine wichtige Technik im mc-Bereich. Trotzdem solltest Du noch etwas an den Basics arbeiten, bevor Du Interrupts angehst. Viele Grüße, Stefan
Vielen Dank an alle für die guten Tipps! Ich habe mein Programm jetzt etwas geändert und deshalb ganz auf die Interrupt Routinen verzichtet. Tja, ich muss einfach noch ein bischen besser mit C umgehen können :-)
Sehr schön ;-) Bitte behalte dieses erste Beispiel im Kopf und komm später darauf zurück, wenn Du etwas Erfahrung gesammelt hast. Denn Interrupts auf mc sind ein sehr wichtiges Werkzeug (wenn man weiss, was man tut :)) Viel Spass, Stefan
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.