Hallo guten Morgen an alle, ich hatte ja vor ein paar Tage im Beitrag "ADC-Mega8, Hilfe bitte ich komme nicht weiter", schon mal um Hilfe gebeten und konnte das Problem danach auch beheben. War eigentlich keine große Sache ich hatte es nur nicht gesehen. Jetzt gibt es wieder ein Problem (sicherlich ähnlich banal) und mir ist einfach nicht klar wo der Fehler liegt. Vielleicht erkennt Ihr den "Kasus Knacksus". :-) U.a. soll folgender Code ausgeführt werden: ISR (TIMER1_OVF_vect){ … result = Read_Channel(0); // ACD – Wert wird zugewiesen … lcd_out(result); return; } void lcd_out(uint16_t wert){ set_cursor(0,2); if(wert>963){ lcd_string("wird geladen"); }else if(wert>928 && wert<963){ lcd_string("Batterie voll"); }else if(wert>785){ lcd_string("Ladung gring!"); }else if(wert<=737 && wert>717){ lcd_string("Ladung kritisch!"); }else if(wert==917){ lcd_string("abgeschaltet!!"); }else if(wert==0){ lcd_string("Schalter aus!"); } } Es wird offenbar keine der If-Anweisungen ausgeführt, den ich erhalte auf dem Display keine Anzeige. Lieg es an der Notation der Vergleiche, ist es ein Typ-Konflikt … ??? Gruß Wilfried
Prinzipiell ist es schlecht, Code in einer ISR aufzurufen, der längere Zeit für die Abarbeitung braucht. Ohne deine Beschreibung, wie sich der Controller verhält, wird es schwierig genaues zu sagen. Als erstes würde ich aber den ADC-Wert direkt auf dem Display ausgeben, um zu sehen, dass die Ausgabe-Funktion überhaupt abgearbeitet wird.
Um aus der ISR die LCD-Ausgabe zu "triggern", verwendet man eigentlich z.B. folgenden Mechanismus (Pseudo-Code):
1 | #define IDLE 0
|
2 | #define LCD_OUT 1
|
3 | |
4 | volatile uint8_t command; |
5 | |
6 | ISR(TIMER1_OVF_vect) |
7 | {
|
8 | //...
|
9 | command = LCD_OUT; |
10 | }
|
11 | |
12 | int main() |
13 | {
|
14 | //...
|
15 | |
16 | for(;;) |
17 | {
|
18 | if(command == LCD_OUT) |
19 | {
|
20 | lcd_out(...); |
21 | command = IDLE; |
22 | }
|
23 | }
|
24 | return 0; |
25 | }
|
Wilfried H. schrieb: > Lieg es an der Notation der Vergleiche, ist es ein Typ-Konflikt … ??? Wie wäre es mit: Der Wert ist nicht der, den du erwartest? Du hast zb keine Ausgabe für Werte * die kleiner als 717 sind * die sich im Bereich 738 bis 785 bewegen. Welche Werte hast du denn?
Ich glaube ich habe meinen Fehler gefunden. Wenn ich dem ADC-Wert über die Funktion "itoa" wandele und direkt anzeigen lasse erhalte ich z.B. bei 2,5V Eingangsspannung die Anzeige "0000000511". Ich schließe daraus, das ich die führenden Nullen beim Vergleich berücksichtigen muß, richtig?
Diese Schreibweise
1 | if(wert>963){ |
2 | lcd_string("wird geladen"); |
3 | }else if(wert>928 && wert<963){ |
4 | lcd_string("Batterie voll"); |
5 | }else if(wert>785){ |
6 | lcd_string("Ladung gring!"); |
7 | }else if(wert<=737 && wert>717){ |
8 | lcd_string("Ladung kritisch!"); |
9 | }else if(wert==917){ |
10 | lcd_string("abgeschaltet!!"); |
11 | }else if(wert==0){ |
12 | lcd_string("Schalter aus!"); |
13 | }
|
ist sehr unübersichtlich. Ist dir zb aufgefallen, dass der Fall (wert==917) nie ausgeführt werden kann? Beobachtung: Wenn der Wert zb 980 ist, dann wird dieser if Teil
1 | if( wert > 963 ) |
genommen. Da alle andere Abfragen mittels else if an dieses if gekoppelt sind, werden sie gar nicht mehr ausgewertet. Du musst daher hier
1 | else if( wert > 928 && wert < 963 ) |
gar nicht mehr abfragen, ob der Wert kleiner als 963 ist. Er kann nicht mehr größer als 963 sein, ansonsten würde das Programm gar nicht bei dieser Abfrage sein! was soll eigentlich passieren, wenn der Wert exakt 963 ist. Das ist ein Tippfehler, da muss es <= heißen :-). Aber besser ist es, das ganze zu vereinfachen und immer nur auf die Untergrenze zu prüfen und die in absteigender Reihenfolge anzuordnen:
1 | //
|
2 | // zuerst die fixen Werte
|
3 | //
|
4 | if( wert == 917 ) |
5 | lcd_string( "abgeschaltet!!" ); |
6 | |
7 | else if( wert == 0 ) |
8 | lcd_string( "Schalter aus!" ); |
9 | |
10 | else { // dann Wertebereiche |
11 | if( wert > 963 ) |
12 | lcd_string( "wird geladen" ); |
13 | |
14 | else if( wert > 928 ) |
15 | lcd_string( "Batterie voll" ); |
16 | |
17 | else if( wert > 785 ) |
18 | lcd_string( "Ladung gring!" ); |
19 | |
20 | else if( wert > 717 ) |
21 | lcd_string( "Ladung kritisch!" ); |
22 | |
23 | else
|
24 | lcd_string( "massive Unterspannung !" ); |
25 | }
|
auf die Art kann es dir nie passieren, dass Bereichsgrenzen nicht aneinanderpassen und du unbeabsichtigt Lücken in deinen Bereichen hast. Auch solltest du dir angewöhnen einen 'default'-else Zweig einzufügen, der alles andere auffängt.
Wilfried H. schrieb: > Ich glaube ich habe meinen Fehler gefunden. Wenn ich dem ADC-Wert über > die Funktion "itoa" wandele und direkt anzeigen lasse erhalte ich z.B. > bei 2,5V Eingangsspannung die Anzeige "0000000511". Ich schließe daraus, > das ich die führenden Nullen beim Vergleich berücksichtigen muß, > richtig? Falsch. Dein Code arbeitet schon richtig. Für den Fall, dass der wert 511 beträgt, hast du ganz einfach keine Ausgabe vorgesehen. (Siehe auch meinen vorhergehenden Beitrag, wie du das besser machen kannst)
Wilfried H. schrieb: > Soory, die 917 im Code ist falsch muß heißen 717! Und wahrscheinlich hätte es im Original auch nicht == sondern < heissen sollen :-) -> was lernen wir daraus: optische Formatierung und Aufbereitung des Codes ist kein Selbstzweck sondern hilft auch mit Fehler zu sehen! Wer die Einzelteile einer Anweisung auf Knirsch ohne Leerzeichen aneinanderpappt, hat es nicht besser verdient. Seit du klein bist, hast du dein Gehirn darauf trainiert, dass zwischen Wörtern Leerraum steht. Warum man diese Konditionierung bei der C Programmierung über Bord werfen muss nur weil es erlaubt ist, entzieht sich meinem Verständnis. Wäre ja auch zu einfach, wenn man eine Anweisung lesen kann ohne erst 3 mal vorwärts/rückwärts mit den Augen durch die Anweisung laufen zu müssen um die Einzelteile optisch zu identifizieren.
Hallo Karl Heinz, danke Dir ein weiteres mal. Du hast natürlich völlig recht. Aber so ist das wenn man lange nicht programmiert hat, dann verlernt man doch vieles. Vor allen Dingen bei den eigentlich so logischen Basics, da denkt man garnicht mehr richtig nach, denn "das muß ja stimmen". Also danke noch mal Wilfried
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.