Forum: Mikrocontroller und Digitale Elektronik ATMega8 als Zähler


von Simon R. (Gast)


Angehängte Dateien:

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

von holger (Gast)


Lesenswert?

>Das Programm ist im
>Anhang.

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

von Karl H. (kbuchegg)


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)

von Simon R. (Gast)


Angehängte Dateien:

Lesenswert?

Ich bitte vielmals um Verzeihung... :-)

von Karl H. (kbuchegg)


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?

von Peter D. (peda)


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

von Simon R. (Gast)


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.

von Karl H. (kbuchegg)


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?

von Stefan E. (sternst)


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.

von Karl H. (kbuchegg)


Lesenswert?

Nur so als Beispiel.
Man könnte das zb so formulieren
1
.....
2
3
   zaehler = 0;
4
5
   while( 1 ) {    // Hauptschliefe in main()
6
7
     // warte auf die beiden LED an PB3 und PB4.
8
     // wenn sie angehen, ist der Prozessor hoch
9
10
     while( ! ( PINB & ( 1 << PB3 ) &&
11
                PINB & ( 1 << PB4 ) )
12
       ;
13
14
     // ok, LED sind an, der andere Prozessor ist hoch.
15
     // in regelmässigen Zeitabständen muss sich jetzt der Zustand
16
     // an PB1 und PB2 ändern
17
     old = PINB & ( 1 << PB1 || 1 << PB2 );
18
     now = old;
19
     while( old != now ) {
20
       old = now;
21
       _delay_ms( setzte einen Zahlenwert ein, von dem sichergestellt
22
                  ist, dass sich die Blink-LED in dieser Zeit ändern
23
                  müssten );
24
       now = PINB & ( 1 << PB1 || 1 << PB2 );
25
     }
26
27
     // es hat in der Wartezeit keine Änderung des Pinzustands gegeben
28
     // -> Schluss: Prozessor ist abgeschmiert
29
30
     zaehler++;
31
32
     // resetten und am LCD ausgeben
33
     lcd_puti( zaehler );
34
     ....
35
36
   }
37
}

von Simon R. (Gast)


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.

von Karl H. (kbuchegg)


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.

von Stefan E. (sternst)


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.

von Karl H. (kbuchegg)


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
1
void lcd_puti( int zahl )
2
{
3
  char buffer[10];
4
5
  itoa( zahl, buffer, 10 );
6
  lcd_puts( buffer );
7
}

und benutzt die ganz einfach, wann immer du einen int auszugeben hast.
1
   ....
2
3
                _delay_ms(30);                
4
                 zaehler++;
5
                _delay_ms(3000);
6
                
7
                lcd_home();
8
                lcd_string("Ausfaelle:");
9
                lcd_puti( zaehler );
10
                          
11
                set_cursor(0,2);
12
                lcd_string("BFR:");
13
                lcd_puti( ausfaelle );
14
                lcd_string("/");
15
                lcd_puti( pulse );
16
   ....

von Simon R. (Gast)


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.

von Simon R. (Gast)


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.

von Simon R. (Gast)


Lesenswert?

@ Karl Heinz Buchegger

Und wie ist lcd_puts definiert?

von Karl H. (kbuchegg)


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.

von Karl H. (kbuchegg)


Lesenswert?

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

Tschuldigung. Die Funktion heißt bei dir lcd_string.

von Simon R. (Gast)


Lesenswert?

Ok vielen Dank erstmal...ich werde es ausprobieren. :-)

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

von Stefan E. (sternst)


Lesenswert?

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

von Stephan V. (orca)


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

von Simon R. (Gast)


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...

von Simon R. (Gast)


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!!!;-)

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.