an dieser Stelle -
lcd_int4(adc_read()); // <== hier mehrere ADC-Auslesungen angezeigt
werden mehrere Messungen angezeigt und überschrieben. D.h. die Funktion 'lcd_int4' wird nur einmal ausgeführt da sonst hintereinander geschrieben würde - aber der Wert wird mehrfach angezeigt.
Wie kann das sein? Was mache ich falsch?
1
voidmain(void)
2
//
3
{
4
5
clock_prescale_set(clock_div_2);//8mhz
6
7
init_timer_smh();
8
led1_init;
9
10
//usart_init;
11
//USART0_init(9600);
12
//relais_init;
13
i2c_init();
14
lcd_init();
15
adc_init();
16
17
lcd_clear(RED);
18
lcd_int4(adc_read());// <== hier eine ADC-Auslesung
if(sec==3&&min%6==0){//alle sechs Minuten auslesen
54
55
if(min==0)//jede Stunde -------
56
{
57
// nichts?
58
}
59
60
//wr_read_reg();
61
//sub_regelung();
62
}
63
64
if(sec%5==1){
65
66
u8i=0;
67
lcd_goto(10+i++,1);
68
69
lcd_int4(i);// <== hier 1mal angezeigt
70
lcd_int4(adc_read());// <== hier mehrere ADC-Auslesungen angezeigt
71
}
72
73
}//while
74
75
}//main
Und auf den problematischen Teil reduziert:
1
voidmain(void){
2
3
while(1){
4
5
if(timer_smh>99){
6
sec=sec++;
7
timer_smh=0;
8
}
9
10
if(sec%5==1){
11
12
u8i=0;
13
lcd_goto(10+i++,1);
14
15
lcd_int4(i);// <== hier 1mal angezeigt
16
lcd_int4(adc_read());// <== hier mehrere ADC-Auslesungen angezeigt
17
}
18
19
}//while
20
21
}//main
Hier fallen mir folgende Dinge auf:
Ist timer_smh als "volatile" und 8 Bit Integer deklariert? Wenn nicht, können Lesezugriffe im Hauptprogramm durch Schreibzugriffe in der Timer-ISR gestört werden und zu unerwartetem Verhalten führen. Allerdings nicht zu dem konkreten Verhalten, dass wir hier sehen. Dafür muss es noch einen anderen Grund geben.
lcd_goto(10 + i++
ergibt immer 10, weil i immer 0 ist.
lcd_int4(i);
gibt immer 1 aus, weil i immer 1 ist.
lcd_int4(adc_read());
Gibt mit Sicherheit nur eine ADC Messung aus. Denn etwas anderes kann diese Funtkion nicht tun.
Offenbar kommt die Ausgabe " 1 813" von diesen beiden Aufrufen.
Die unerwarte Ausgabe in der dritten Display-Zeile stimmt nicht mit dem Quellcode überein. Denn er enthält kein "lcd_goto(3,1)". Sie kann auch nicht von "lcd_int4()" kommen, weil diese Funktion immer 4 Ziffern rehtsbündig ausgibt.
Vermutlich ist der Fehler ganz woanders, in einem Stück Code, den du nicht gezeigt hast. Ich würde mal alle andere Display-Ausgaben auskommentieren um auszuschließen, dass sie stören.
Negative Zahlen mit mehr als 3 Stellen führen zu einer fehlerhaften
Ausgabe:
Das ist bewusst in kauf genommen. Die Funktion dient zur Positionierung auf dem Display. Wenn größere negative Werte zu erwarten sind muss man das anders machen.
stimmt - "lcd_goto(3,1)" hab ich nachträglich eingefügt
stimmt auch, habe die Deklaration nach oben gezogen
Wenn du hilfreiche Hilfe bekommen willst, solltest du deine Probleme ordentlich beschreiben. Wenn man sich Mühe gibt, erkennt man die Ursache beim verfassen der Problembeschreibung sogar oft selbst.
Ergebnis bleibt. Stelle wird nur einmal aufgerufen.
Damit kann ich nichts anfangen. Ist das jetzt eine gute oder eine schlechte Nachricht?
Nochmal von vorne: Zeige den kompletten Quelltext (ordentlich formatiert!), die dazugehörige Ausgabe, und was du stattdessen erwartest.
Wenn man es schon nicht schafft vernünftige, aussagekräftige
Namen für Funktionen und Variablen zu finden dann kann's auch
mit deren Inhalten schwierig werden, um es mal vorsichtig
auszudrücken .... ja, und die Formatierung, ein Graus ....
Wenn du mal im Detail beschreibst was deine Funktion am LCD
machen soll (ich kann es nicht, will es auch nicht verstehen)
dann könnte man (jemand hier im Forum) dir mit ein paar
"Pinselstrichen" eine vernünftige Funktion mit der Anwendung
von sprintf(...) schreiben.
Ich nehme an dass du das nicht alleine schaffst, denn schon
der Titel deines Threads hat nichts mit dem zu tun was du
wirklich an Problemen hast. Jedenfalls hat das alles (zuerst
mal) nichts mit dem ADC zu tun.
#include <stdio.h>
#include <stdint.h>
void lcd_int4(int16_t val)
{
char s[] = "Err ";
if ( val >= -999 && val <= 9999 )
sprintf(s, "%4d", val);
lcd_write(s);
}
Schlechter Stil. Bei sowas kann man sich bei C immer wieder leicht in den Fuß schießen. Entweder die Einzelanweisung hinter if() in der gleichen Zeile oder IMMER mit Klammern!
Und wozu soll ein Komma bei Integerzahlen
gut sein?
Sorry ich hab noch nie mit Fließkomma gearbeitet und habe das auch im Prinzip nie gebraucht. Der ADC liefert bei 10bit 0-1023. Spannungsmessung Genauigkeit ist 0,1 Volt.
Die Darstellung auf dem lcd muss formatiert sein - sonst sieht es blöd aus. Also immer 4Stellen für eine Zahl.
Die Funktion lcd_int_10() kann auf 4Stellen also Werte von
+9999 bis -999 darstellen davon den Zahlenbereich 99,9 bis -9,9 als Dezimalwert mit Komma. Im Prinzip ist das der Sinn meiner Funktion wobei ihr ganz richtig bemerkt habt, dass die Funktion noch nicht ganz fertig ist weil die Anzeige von negativen Zahlen nicht funktioniert und die Ausgaben von Zahlen >99,9 auch noch nicht implementiert ist. (ich muss nur Spannungen von 0 - 60V auswerten - brauch ich also noch nicht)
Ich fand die Idee gut für Dezimalzahlen aus der ADC-Spannungsmessung eine eigene Funktion zu schreiben statt bisher
lcd_int2(x/10);
lcd_write(",");
lcd_int(x%10);
Sorry ich hab noch nie mit Fließkomma gearbeitet und habe das auch im
Prinzip nie gebraucht. Der ADC liefert bei 10bit 0-1023.
Spannungsmessung Genauigkeit ist 0,1 Volt.
Aha, also Festkommaarithmetik. Die ist aus deiner Funktion aber nicht so recht ablesbar.
Aber irgendwie versteht mich mal wieder keiner.
Das könnte an deinen Informationen liegen, welche du nicht lieferst.