mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ATMega8 als Zähler


Autor: Simon R. (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

ich habe mal wieder ein Problem mit meinem C-Programm. :-/

Für meine Schaltung verwende ich einen ATMega 8, programmiere mit dem 
AVR-Studio und programmiere in C.

Die Schaltung soll die Zustände einer anderen Mikrocontroller-Schaltung 
(ATtiny13) überwachen und je nach Zustand reagieren.

Sollte ein Fehler auftreten, so soll er den "Zaehler" um 1 erhöhen, es 
auf dem Display ausgeben, die Mikrocontroller-Schaltung (ATtiny13) 
zurücksetzen und das Ganze von vorne beginnen.

Das Problem:
Er zählt bis 1 hoch, aber dann passiert nichts mehr! Das Programm ist im 
Anhang. Kann mir jemand helfen?
Ich bin für alle Antworten und Hilfestellungen dankbar!!!

Viele Grüße

Simon

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Das Programm ist im
>Anhang.

Das denkst auch nur du. Ist es denn so schwer
eine C-Datei anzuhängen?

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

Bewertung
0 lesenswert
nicht lesenswert
Das APS File ist zunächst ziemlich uninteressant.
Das *.c File ist wichtig.
Alternativ kannst du auch ganz einfach den Code direkt aus dem Source 
Code Fenster hierher kopieren (wenn er nicht allzulang ist, was ich aber 
bei der Programmbeschreibung nicht annehme)

Autor: Simon R. (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ich bitte vielmals um Verzeihung... :-)

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

Bewertung
0 lesenswert
nicht lesenswert
Wieviele Pins willst du am Port B eigentlich überwachen? Und woran 
erkennt man, dass 'ein Fehler aufgetreten' ist?

Formatier das doch bitte mal ein wenig vernünftig. Ich denke nicht, dass 
da jetzt irgendwer Lust darauf hat, diese Monster-Bedingung mit all 
seinen vielen Klammern im if bzw. while zu analysieren um rauszufinden 
unter welchen Umständen der jeweilige Pfad genommen wird und wann nicht. 
Alles in allem kommt mir das reichlich kompliziert vor für die 
eigentlich primitiv anmutende AUfgabenstellung aus dem Anfangsposting.


PS: Was macht eigentlich der goto da am Anfang und am Ende der Funktion. 
Dir ist schon klar, dass die Funktion schleife_normal sowieso wieder und 
wieder ausgeführt werden würde und es daher nicht so schlau ist, da in 
der Funktion windige Schleifenkonstrukte mit goto aufzubauen?

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> Alternativ kannst du auch ganz einfach den Code direkt aus dem Source
> Code Fenster hierher kopieren (wenn er nicht allzulang ist,

Ne, ne, fang den Unsinn garnicht erst an!
Das wird dann nur wieder ein DOC, BMP oder ähnlich schlimmes.

*.c und *.h ist schon vollkommen richtig.


Peter

Autor: Simon R. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Als Zustandüberwachung habe ich 4 LEDs gewählt...2 LEDs geben den 
Grundzustand wieder (beide leuchten)...wenn beide Leuchten, soll das 
Programm aktiviert werden. Die anderen beiden LEDs blinken dann 
abwechselnd.
Solange sie blinken, soll er nichts tun (while-Schleife im 
main-Programm)..weicht der Zustand vom Blinkzustand ab (Durch äußere 
elektromagnetische Felder, dann soll das Programm den Zähler um 1 
erhöhen, auf dem Display ausgeben und die Schaltung in den Grundzustand 
setzen (LEDs, wie oben leuchten beide). Dach wieder das Blinkprogramm 
aktivieren usw.

Die goto's lass ich außen vor...es geht nur darum, dass nicht hochgezält 
wird.

Bevor ich die Sache mit dem itoa eingefügt habe, ging alles wie 
geschmiert.

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

Bewertung
0 lesenswert
nicht lesenswert
Simon R. schrieb:
> Als Zustandüberwachung habe ich 4 LEDs gewählt...2 LEDs geben den
> Grundzustand wieder (beide leuchten)...wenn beide Leuchten, soll das
> Programm aktiviert werden.

Welche sind das?

> Die anderen beiden LEDs blinken dann
> abwechselnd.
> Solange sie blinken,

Mit welcher Frequenz blinken sie? (ungefähr. Damit man abschätzen kann, 
in welchen Zeiträumen sich ein Pinzustand ändern muss um als Fehler 
erkannt zu werden)

Welche sind das?

> soll er nichts tun (while-Schleife im
> main-Programm)

Äh nein. Das ist nicht deine Programmlogik.


> Die goto's lass ich außen vor...es geht nur darum, dass nicht hochgezält
> wird.

Ich denke mal dass genau diese gotos dich soweit verwirrt haben, dass 
deine Programmlogik einfach nicht stimmt. Ohne die goto könnte man das 
Programm halb so kurz formulieren, die Struktur würde besser rauskommen 
und die Chance Fehler zu machen siinkt ebenfalls


Im übrigen halte ich die ganze Idee mit einem zweiten Prozessor, der 
einen ersten Prozessor überwachen soll, für ziemlich kontraproduktiv. 
Getreu dem Motto: Wer überwacht eigentlich den Überwacher? Was, wenn 
dieser Prozessor ebenfalls ausfällt?

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Simon R. schrieb:

> ...es geht nur darum, dass nicht hochgezält wird.

Auf dem LCD ausgegeben wird in der Funktion 2x "ausfaelle" und 1x 
"pulse". Die einzige Variable, die sich aber ändern könnte, ist 
"zaehler". Logisch, dass sich auf dem LCD nichts ändert.

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

Bewertung
0 lesenswert
nicht lesenswert
Nur so als Beispiel.
Man könnte das zb so formulieren
.....

   zaehler = 0;

   while( 1 ) {    // Hauptschliefe in main()

     // warte auf die beiden LED an PB3 und PB4.
     // wenn sie angehen, ist der Prozessor hoch

     while( ! ( PINB & ( 1 << PB3 ) &&
                PINB & ( 1 << PB4 ) )
       ;

     // ok, LED sind an, der andere Prozessor ist hoch.
     // in regelmässigen Zeitabständen muss sich jetzt der Zustand
     // an PB1 und PB2 ändern
     old = PINB & ( 1 << PB1 || 1 << PB2 );
     now = old;
     while( old != now ) {
       old = now;
       _delay_ms( setzte einen Zahlenwert ein, von dem sichergestellt
                  ist, dass sich die Blink-LED in dieser Zeit ändern
                  müssten );
       now = PINB & ( 1 << PB1 || 1 << PB2 );
     }

     // es hat in der Wartezeit keine Änderung des Pinzustands gegeben
     // -> Schluss: Prozessor ist abgeschmiert

     zaehler++;

     // resetten und am LCD ausgeben
     lcd_puti( zaehler );
     ....

   }
}

Autor: Simon R. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Stefan Ernst: Die variable ausfaelle ist doch durch die variable 
zaehler definiert...allerdings hatte ich es auch einfach mit zaehler-48 
versucht, funktioniert trotzdem nicht.

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

Bewertung
0 lesenswert
nicht lesenswert
Simon R. schrieb:
> @ Stefan Ernst: Die variable ausfaelle ist doch durch die variable
> zaehler definiert

Äh, nein.
C ist nicht Excel. Der Compiler führt nicht Buch darüber, welche 
Beziehungen du glaubst hergestellt zu haben.

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Simon R. schrieb:
> @ Stefan Ernst: Die variable ausfaelle ist doch durch die variable
> zaehler definiert...

Das ist eine einmalige Zuweisung, keine dauerhafte feste Relation 
zwischen den Variablen.

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

Bewertung
0 lesenswert
nicht lesenswert
> allerdings hatte ich es auch einfach mit zaehler-48 versucht

Wozu -48?

Steck zaehler in itoa hinein und du bekommst einen String, der ASCII 
mässig der Zahl in zaehler entspricht. Fertig.

Am besten machst du dir für diese Operation, einen int ausgeben, eine 
Funktion
void lcd_puti( int zahl )
{
  char buffer[10];

  itoa( zahl, buffer, 10 );
  lcd_puts( buffer );
}

und benutzt die ganz einfach, wann immer du einen int auszugeben hast.
   ....

                _delay_ms(30);                
                 zaehler++;
                _delay_ms(3000);
                
                lcd_home();
                lcd_string("Ausfaelle:");
                lcd_puti( zaehler );
                          
                set_cursor(0,2);
                lcd_string("BFR:");
                lcd_puti( ausfaelle );
                lcd_string("/");
                lcd_puti( pulse );
   ....

Autor: Simon R. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was die Zustände angeht...es muss durch umgekehrte Logik erfolgen.

Auch die LEDs dürfen nur abwechselnd aktiviert werden (XOR).

Ich weiß, dass das kompliziert aussieht...aber ich hatte vorher eine 
Logiktabelle über alle Zustände (insgesamt 2^4=16) aufgestellt und alle 
einzeln in die Bedingung eingebracht, die NICHT auftreten dürfen.

Autor: Simon R. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die -48 habe ich eingebunden, weil sonst, wenn er um eins erhöht, eine 
49 auf dem LC-Display (EA DIP 204-4 von Assembly Electronic) ausgibt.

Autor: Simon R. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Karl Heinz Buchegger

Und wie ist lcd_puts definiert?

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

Bewertung
0 lesenswert
nicht lesenswert
Simon R. schrieb:
> Die -48 habe ich eingebunden, weil sonst, wenn er um eins erhöht, eine
> 49 auf dem LC-Display (EA DIP 204-4 von Assembly Electronic) ausgibt.

Ja.
Wenn du zaehler als ASCII Code an das Display schickst.
Aber du hast ja itoa. Das weiß schon, wie man einen int zu einem String 
wandelt, so dass der String die Textrepräsentierung der Zahl darstellt.

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

Bewertung
0 lesenswert
nicht lesenswert
Simon R. schrieb:
> @ Karl Heinz Buchegger
>
> Und wie ist lcd_puts definiert?

Tschuldigung. Die Funktion heißt bei dir lcd_string.

Autor: Simon R. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok vielen Dank erstmal...ich werde es ausprobieren. :-)

Dieses Forum ist wirkliche eine große Hilfe...vielen Dank euch allen! 
;-)

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und zaehler nicht mit 0x30 zu initialisieren könnte auch helfen. ;-)

Autor: Stephan V. (orca)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich will mich jetzt ehrlich gesagt nicht durch den ganzen Code (noch 
dazu mit schleifen und goto Kombination quälen), aber ein paar Dinge 
sind mir beim kurzen überfliegen aufgefallen:

1. Dein Zähler wird JEDESMAL am Anfang von schleife_normal() auf 0x30 
zurück gesetzt gesetzt. Ist das wirklich Absicht??
Wenn ich das Programm richtig durchschaut habe wird im Fehlerfall der 
zähler um 1 erhöht, aufs LCD geschrieben und schleife_normal() beendet. 
Die main loop startet schleife_normal() wieder und setzt den zähler 
zurück. (Warum eigentlich ausgerechnet auf 0x30?)

2. ausfaelle wird NUR am Anfang von schleife_normal() zugewiesen. Im 
Fehlerfall erhöhst du zwar zähler, zeigst aber ausfaelle an???
Und das sowohl für Ausfaelle als auch BFR.

by(e)
Stephan

Autor: Simon R. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ausfaelle ist ja quasi durch zaehler definiert...
...aber das habe ich mittlerweile geändert...denn selbstsamerweise hat 
er mir statt einer 1 immer 49 ausgegeben (also 1+48)..
aber durch die richtige Initilisierung hat sich das geändert. :-)

Was deine Vermutung (zaehler immer zurückgesetzt) angeht, kannst du 
recht haben...

Man hat immer das Problem, dass man vor lauter Bäumen den Wald nicht 
mehr sieht...vor allem dann, wenn man schon zig mal dieses Programm 
umgeschrieben hat...

Autor: Simon R. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und du hattes recht Stephan Veigl...ich habe immer zaehler wieder 
zurückgesetzt...aber seltsam ist schon, dass es davor, bevor ich itoa() 
usw. eingefügt habe, immer funktioniert hat...naja...auch 
egal...hauptsache es läuft!!!;-)

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.