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
>Das Programm ist im >Anhang. Das denkst auch nur du. Ist es denn so schwer eine C-Datei anzuhängen?
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)
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?
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
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.
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?
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.
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 | }
|
@ 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.
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.
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.
> 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 | ....
|
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.
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.
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.
Simon R. schrieb: > @ Karl Heinz Buchegger > > Und wie ist lcd_puts definiert? Tschuldigung. Die Funktion heißt bei dir lcd_string.
Ok vielen Dank erstmal...ich werde es ausprobieren. :-) Dieses Forum ist wirkliche eine große Hilfe...vielen Dank euch allen! ;-)
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
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...
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.