mikrocontroller.net

Forum: Compiler & IDEs Probleme beim Umstieg von Delay auf Timer


Autor: Martin Löffler (golfomania)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen

ich versuche einen Ausgang in bestimmten Zeitabständen zu schalten (soll 
mal eine Steuerung für eine Heizung werden). Da ich absoluter Anfänger 
bin, habe ich ich zuerst mit einer einfachen Funktion mit entprechenden 
Delays angefangen. Das funktioniert auch.
Jetzt bin ich dabei das ganze mit einem Timer+Interrupt zu realisieren.

Sprache: C
Controller: ATmega8
Entwicklungsumgebung: AVR Studio 4 + STK 500
Compilermeldungen: keine

Da der Controller neben der Heizung später noch wesentlich mehr machen 
soll (PWM, Entpellung, LCD) möchte ich ein Sekundenflag erzeugen, auf 
welches dann verschiedene Funktionen in der Hauptschleife ihre 
Laufzeiten aufbauen können.

Mein Programm ist im Anhang. Ich kriege es einfach nicht zu laufen 
(vielleicht ist es auch einfach zu spät :-).
Über einen konstruktiven Hinweis wäre ich wirklich dankbar.

Martin

Autor: Ohforf Sake (ohforf)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wozu ist das "return 0;" ?
Wird damit die main() funktion verlassen ?
Ich kanns nicht so gut lesen, weil die einrückungen nicht da sind, wie 
ichs gewohnt bin.

Autor: Ohforf Sake (ohforf)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habs mal zum Spass im Simulator laufen lassen.
PB6 blinkt hübsch langsam vor sich hin...
Sind die Fuses richtig gesetzt ?

Autor: Martin Löffler (golfomania)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wow bis 3 hab ich nicht durchgehalten :-)

Wie gesagt ich bin ein absoluter Anfänger. Ich hab mir einen 
Leitz-Ordner voll Tutorials und das Datenblatt vom ATmega8 ausgedrucket 
und versuche mir das ganze jetzt selbst beizubringen.

Das mit dem Return 0 hab ich irgendwo hier gelesen. Wenn ich es richtig 
verstanden habe, hat es damit zu tun, dass Int Main (void) einen 
Rückgabewert verlangt, auch wenn das durch die while-Schleife nie 
erreicht wird.

Muss ich an den Fuses was einstellen?? Die erste Version mit Delays hat 
ja mal funktioniert ?!

Wenn ich das Programm jetzt auf den Controller brenne leuchtet die LED 
dauerhaft...

Kann man mit dem Studio 4 C-Programme simulieren?

Das es bei dir im Simulator läuft heißt ja, dass ich gar nicht so weit 
weg vom Ziel bin.

Martin

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mach' doch mal direkt in den Interrupt ein
PORTB ^= 1<<PB6;
rein und schau, ob es dann (schnell) blinkt bzw. flackert.  Wenn nicht, 
hast Du möglicherweise irgendwo den falschen Microcontroller-Typ 
eingestellt, weil er gar nicht an der ISR vorbeikommt.

EDIT:  Die Zugriffe auf die LED in der Hauptschleife musst Du für diesen 
Test rausnehmen oder eine andere LED verwenden (sofern vorhanden).

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Martin Löffler schrieb:

> Das mit dem Return 0 hab ich irgendwo hier gelesen. Wenn ich es richtig
> verstanden habe, hat es damit zu tun, dass Int Main (void) einen
> Rückgabewert verlangt, auch wenn das durch die while-Schleife nie
> erreicht wird.

Das ist an dieser Stelle gar nicht der springende Punkt.
Worauf Ohforf hinaus will:

Rücke deinen Code ein!
Dein Code hat eine logische Struktur. Diese Struktur lässt sich durch 
Einrückungen sichtbar machen! Damit erkennt man, welche Anweisungen 
innerhalb von Schleifen sind, welche Anweisungen von einem if abhängen 
usw.

Die Optik eines Codes ist nicht Selbstzwecke, sondern ein wichtiger 
Bestandteil der Verstehbarkeit.

vergleich mal damit
int main (void)
{
  //PORTS
  DDRB = 0b00100000;          //PortB = PB6->out

  //VARIABLEN
  uint8_t a=0;                //Zählvariablen
  uint8_t betrieb=5;          //Variable Betrieb = Betriebszeit in Sekunden
  uint8_t pause=3;            //Variable Pause = Pausenzeit in Sekunden

  //Timer2 konfigurieren---------------------------------------------
  TCCR2 |= (1<<WGM21);        //Timer Mode "Compare Match"
  TCCR2 &= ~(1<<WGM20);
  OCR2 = 194;                 //Compare Register mit 194 laden -> 5,008/s
  TCCR2 |= (1<<CS20);         //Timer startet mit Prescaler von 1024 = 976,56/s
  TCCR2 |= (1<<CS21);
  TCCR2 |= (1<<CS22);
  TIMSK |= (1<<OCIE2);        //CTC Interrupt freigegeben

  sei();                      //Interrupts freigeben

  //Hauptschleife-----------------------------------------------------
  while (1)              
  {
    //Heizung
    if (secflag == 1)           
    {
      a++;
      secflag = 0;
    }

    if (a <= betrieb)
    {
      PORTB |= (1<<PB6);
    }

    if ((a > betrieb) && (a <= betrieb + pause))
    {
      PORTB &= ~(1<<PB6);
    }

    if (a > betrieb + pause)
    {
      a = 0;
    }
  }

  return 0;
}

Anhand der Einrückungstiefe kann man ganz leicht erkennen, welche Teile 
zusammen gehören und zb im Falle eines if, von welcher Bedinung die 
Ausführung der Anweisungen abhängt. Jetzt sieht man auch auf den ersten 
Blick, dass das return nicht innerhalb der while Schleife steht, denn 
alles innerhalb der Schleife wäre eingerückt und das return ist das nun 
mal nicht. Will ich wissen, welche Teile innerhalb der Schleife sind, 
dann brauch ich nur von der { in derselben Spalte mit den Augen nach 
unten gehen, bis ich eine } in derselben Spalte finde. Alles dazwischen 
ist innerhalb der Schleife.

Autor: Martin Löffler (golfomania)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Herr Buchecker,

danke für den Hinweis. So sieht es viel übersichtlicher aus.
Gibt es eine Einstellung, damit der Editor das automatisch macht?

Martin

Autor: Martin Löffler (golfomania)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ich hab es zum laufen gebracht !
Mit dem Tip von Herr Zimmerer hab ich in der ISR eine zusätzliche LED 
invertieren lassen dafür hab ich PB2 genommen. Diese hat nach dem 
Brennen dann auch wunderschön geblinkt auf dem STK500.

Dann habe ich versuchsweise mal in meinem ursprünglichen Programm PB6 
gegen PB2 getauscht und .... es funktioniert !

Also entweder es stimmt was mit der PB6 LED auf dem STK nicht, oder es 
hat was mit dem Controller zu tun. Auf dem Datenblatt ist der PB6 
eigentlich schon rausgefüht auf einen PIN ?!

Auf jeden Fall hab ich mich 2 Tage und eine Nacht mit einem Problem 
rumgeschlagen, was eigentlich gar keins war...

Danke für eure Hilfe.

Martin
PS. Im Anhang nochmal der jetzige Code (noch ohne Einrückungen). Ich hab 
die Timerinitalisierung noch etwas gestrafft.

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.