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


von Martin L. (golfomania)


Angehängte Dateien:

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

von Ohforf S. (ohforf)


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.

von Ohforf S. (ohforf)


Lesenswert?

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

von Martin L. (golfomania)


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

von Hc Z. (mizch)


Lesenswert?

Mach' doch mal direkt in den Interrupt ein
1
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).

von Karl H. (kbuchegg)


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
1
int main (void)
2
{
3
  //PORTS
4
  DDRB = 0b00100000;          //PortB = PB6->out
5
6
  //VARIABLEN
7
  uint8_t a=0;                //Zählvariablen
8
  uint8_t betrieb=5;          //Variable Betrieb = Betriebszeit in Sekunden
9
  uint8_t pause=3;            //Variable Pause = Pausenzeit in Sekunden
10
11
  //Timer2 konfigurieren---------------------------------------------
12
  TCCR2 |= (1<<WGM21);        //Timer Mode "Compare Match"
13
  TCCR2 &= ~(1<<WGM20);
14
  OCR2 = 194;                 //Compare Register mit 194 laden -> 5,008/s
15
  TCCR2 |= (1<<CS20);         //Timer startet mit Prescaler von 1024 = 976,56/s
16
  TCCR2 |= (1<<CS21);
17
  TCCR2 |= (1<<CS22);
18
  TIMSK |= (1<<OCIE2);        //CTC Interrupt freigegeben
19
20
  sei();                      //Interrupts freigeben
21
22
  //Hauptschleife-----------------------------------------------------
23
  while (1)              
24
  {
25
    //Heizung
26
    if (secflag == 1)           
27
    {
28
      a++;
29
      secflag = 0;
30
    }
31
32
    if (a <= betrieb)
33
    {
34
      PORTB |= (1<<PB6);
35
    }
36
37
    if ((a > betrieb) && (a <= betrieb + pause))
38
    {
39
      PORTB &= ~(1<<PB6);
40
    }
41
42
    if (a > betrieb + pause)
43
    {
44
      a = 0;
45
    }
46
  }
47
48
  return 0;
49
}

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.

von Martin L. (golfomania)


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

von Martin L. (golfomania)


Angehängte Dateien:

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.

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.