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
@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
Eine eigene Frage?
Dieser Thread ist über 21 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.