Forum: Compiler & IDEs Brauche Hilfe bei C-Programm (Schleife)


von Ralf (Gast)


Angehängte Dateien:

Lesenswert?

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

von KoF (Gast)


Lesenswert?

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++;
}

von Tom (Gast)


Lesenswert?

ich verstehe nicht ganz was du mit den letzten 6 zeilen bewirken
willst...:


i = 0;
if(i!=9)
{
//machwas
i++;
}

von Sebastian (Gast)


Lesenswert?

eine prüfung "i ist NICHT 9"
wenn i=9 dann ist die schleife zu ende

von ---- (Gast)


Lesenswert?

Welche Schleife?

----, (QuadDash).

von peter dannegger (Gast)


Lesenswert?

@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

von Thilo Wawrzik (Gast)


Angehängte Dateien:

Lesenswert?

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

von Ralf (Gast)


Lesenswert?

@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?

von Jochen (Gast)


Lesenswert?

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.

von Werner B. (Gast)


Lesenswert?

// 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
}

von Stefan Kleinwort (Gast)


Lesenswert?

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

von Ralf (Gast)


Angehängte Dateien:

Lesenswert?

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 :-)

von Stefan Kleinwort (Gast)


Lesenswert?

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