mikrocontroller.net

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


Autor: Ralf (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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

Autor: KoF (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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++;
}

Autor: Tom (Gast)
Datum:

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


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

Autor: Sebastian (Gast)
Datum:

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

Autor: ---- (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Welche Schleife?

----, (QuadDash).

Autor: peter dannegger (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Thilo Wawrzik (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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

Autor: Ralf (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Jochen (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Werner B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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
}

Autor: Stefan Kleinwort (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Ralf (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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 :-)

Autor: Stefan Kleinwort (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.