www.mikrocontroller.net

Forum: Compiler & IDEs Programm funktioniert nur kurze Zeit lang, AVR Atmega 8


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

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich habe ein C-Programm für Atmega 8 geschrieben, womit ich eine Art Uhr 
am LCD-Display Zeile 1 darstellen kann und Zeile 2 wechselweise den 
Zählerstatus eines Taster oder den Wert eines ADC anzeige.
(Programm siehe Anhang, includiertes ADC.C als Kommentar im Programm 
unten angehängt)
Leider habe ich mit diesem Programm ein Problem:
es läuft nur kurz (mal 10sec, mal 1min und ein paar sec), aber nie 
länger.
Weiß nicht warum und würde dazu eure Hilfe benötigen.
Die Case sind drin, weil ich hier das Programm noch um verschiedene 
Funktionen erweitern will.
Über eure Hilfe wäre ich wirklich sehr dankbar.

Grüße
Markus
PS:
Das AVR-GCC-Tutorial ist super

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Argh, immer diese "ausführlichen" Fehlerbeschreibungen.
Wie äußert sich denn das "läuft nur kurz"? Was passiert dann?

Autor: MarkusG (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
es bleibt einfach stehen, es passiert nix mehr. Dehr Inhalt des 
LCD-Displays ändert sich nicht mehr.
Im Programm ist auch ein Blinklicht drinn. Auch diese hört dann auf zu 
blinken.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ MarkusG (Gast)

>es bleibt einfach stehen, es passiert nix mehr. Dehr Inhalt des
>LCD-Displays ändert sich nicht mehr.

>Im Programm ist auch ein Blinklicht drinn. Auch diese hört dann auf zu
>blinken.

Tjaaa, da sind einige Schnitzer drin.

>  while(1)
>  {
>    if (TIFR == (1<<TOV0))

Ganz gefährlich. Denn sobald EIN EINZIGES Bit in dem Register zusätlich 
gesetzt ist, wird die Bedingung nie wieder erfüllt. Du willst eher sowas 
machen

    if (TIFR & (1<<TOV0))

Siehe auch Bitmanipulation

In alle Zweige teiler++ reinzuschreiben ist sinnfrei, zumal es damit 
teilweise doppelt ausgeführt wird. Das ist vermutlich auch der Grund, 
warum dein Programm komisch reagiert. Der Switch wird unsinigerweise 
rasend schnell und oft abgearbeitet. Der muss mit in die if() Abfrage 
des Timers!

MFG
Falk

Autor: MarkusG (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Falk Brunner,

viele Dank für deinen Hinweis mit der Bitmanupulation. Nachdem ich dies 
geändert habe, funktioniert das Programm tatsächlich wie gewünscht.
Das ich in jedem case
teiler ++;
break;
habe ist absicht, damit dieser nur jeweils einmal pro sec. ausgeführt 
wird.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ MarkusG (Gast)

>habe ist absicht, damit dieser nur jeweils einmal pro sec. ausgeführt
>wird.

Wird er auch so, wenn mans richtig macht. Und dein Programm ist noch 
falsch. Eher so.
  while(1)
  {
    if (TIFR & (1<<TOV0))
    {
      // diese Routine wird alle 16384us aufgerufen
      // dies ergibt sich aus: 16Mhz=0.0625us
      // 8Bit-Timer: 0.0625us*8=16us
      // 1024 Prescaler: 16us*1024=16384us

      TIFR |= (1<<TOV0);
      teiler ++;
      
      // zaehlen Impulse PC1
      if (PINC & ( 1 << PC1))
      {
        if (!bin.hold)
        {
          bin.hold = 1;
          zaehler_1 ++;
        }
      }
      else
      {
        bin.hold = 0;
      }
      switch (teiler)
      {
        case 11:      // Aufruf 1* pro sec
          // wechseln des Zusandes PORTD.6
          PORTD ^= (1<<6);
          break;
        
        case 22: // Aufruf 1* pro sec
          // lesen Analog Channel 0 (10Bit)
          adcval = ReadChannel(0); /* MUX-Bits auf 0b0000 -> Channel 0  -> PC0*/
          break;
    
        case 33: // Aufruf 1* pro sec
          if ( sec % 2 ) // sek�nliche Abwechslung der Ausgabe
          {
            //   Ausgabe des ADC-Messwertes auf dem Display
            utoa( 4.8876 * adcval, buf, 10); // Messbereichsendwert: 5000mVolt, Aufl�sung 10Bit=1023
            set_cursor(0,2);
            lcd_string("=>_____mVolt");
            set_cursor(0,2);     // Spalte 2, Zeile 2
            lcd_string(buf);     // write ADC-mV to display
          }
          else
          {
            // Ausgabe des Zaehler PinC.1 auf dem Display
            utoa( zaehler_1, buf, 10);
            set_cursor(0,2);
            lcd_string("=>_____Zaehler1");
            set_cursor(0,2);     // Spalte 2, Zeile 2
            lcd_string(buf);     // write ADC-mV to display
          }
          break;     
    
        case 44: // Aufruf 1* pro sec
          // Ausgabe des Timer 0 auf dem Display
          set_cursor(0,1);
          lcd_string("________________");
        
          utoa( sec, buf, 10); // convert uint to char
          set_cursor(10,1);     // Spalte 8, Zeile 1
          lcd_string(buf);     // write ADC-value to display
      
          utoa( min, buf, 10); // convert uint to char
          set_cursor(5,1);     // Spalte 8, Zeile 1
          lcd_string(buf);     // write ADC-value to display
      
          utoa( std, buf, 10); // convert uint to char
          set_cursor(0,1);     // Spalte 8, Zeile 1
          lcd_string(buf);     // write ADC-value to display
      
          break;
    
        case 55: // Aufruf 1* pro sec
          // wechseln des Zusandes PORTD.6
          PORTD ^= (1<<6);
          break;
    
        case 66: // Aufruf 1* pro sec
          // nun ist eine Sekunde vergangen
          // erh�he den Sekundenz�hler
          teiler = 0;
          sec ++;
      
          if (sec==60) {
            min ++;
            sec = 0;
            if (min==60)
            {
              std ++;
              min = 0;
            }
         }
      }
    }
  return 0;
}

MFG
Falk

Autor: MarkusG (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
OK, bin überzeugt.
Vielen Dank für Eure Hilfen.

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.