Hallo ihr lieben Profis,
ich bins mal wieder:
Folgendes Problem: Ich habe ein Display, auf dem ich Texte anzeigen kann
(Programmiert mit den Routinen aus dem Tutorial). An Pin PA0 liegt die
Datenleitung eines Sensors, deren Wert ausgegeben werden soll.
Das Auslesen des ADC habe ich mit Hilfe dieses Tutorials gelöst:
http://www.rn-wissen.de/index.php/ADC_(Avr)
Weiterhin habe ich mich für die Anzeige an den Festkommaarithmetik
Artikel gehalten.
Als Referenzspannung habe ich meine 5V Versorgungsspannung an AREF und
AVCC gelegt.
Ich habe das ganze mal mit einem Multimeter gemessen und mein Sensor
gibt an den uC eine Spannung zwischen 0 und 5V aus.
Ich arbeite mit einem ATMEGA32, der mit einem Takt von 1Mhz läuft.
Hier mein Code (In auszügen):
1
//Quelle für die folgende Methode: www.rn-wissen.de/index.php/ADC_(Avr)
2
3
long readADC(uint8_t channel){
4
uint8_t i;
5
uint16_t result=0;
6
//Den ADC aktivieren und den Teilungsfaktor auf 8 stellen
7
ADCSRA =(1<<ADEN)| (1<<ADPS0)|(1<<ADPS1);
8
9
//Kanal des Multiplexers wählen
10
//Interne Referenzspannung verwenden (also 2,56V)
11
ADMUX = channel|(1<<REFS1)|(1<<REFS0);
12
13
//Den ADC initialisieren und einen sog. Dummyreadout machen
14
ADCSRA |= (1<<ADSC);
15
while(ADCSRA &(1<<ADSC));
16
17
//Jetzt 3x die Spannung an Kanal channel auslesen und dann einen Durchschnittswert berechnen
18
for (i=0; i<3; i++){
19
//Eine Wandlung
20
ADCSRA |= (1<< ADSC);
21
//Auf Ergebnis waren...
22
while (ADCSRA & (1<<ADSC));
23
24
result += ADCW;
25
}
26
//ADC wiederdeaktivieren
27
ADCSRA &= ~(1<<ADEN);
28
result /= 3;
29
return result;
30
}
31
32
33
/*Funktion zur Anzeigeeiner 32Bit Zahl im Stringformat auf einem LCD
long spannung = result*(long)5000; //Ermitteln des digitalen Wertes der gemessenen Größe Referenzspannung: 5V
82
spannung = spannung/1024; //Umrechnen, wegen 10Bit auflösung
83
//Die nun errechnete Spannung soll auf 1000el genau (also 3 Nachkommastellen) ausgeben werden.
84
uint8_t i;
85
char string[11]; //String Terminator
86
string[11] ='\0';
87
if(spannung<0){ //ist die Zahl negativ?
88
string[0] ='-';
89
spannung = -spannung;
90
}
91
92
else string[0] = ' '; //Die Zahl ist positiv
93
for(i=10; i>=1; i--){
94
string[i] = (spannung%10) +'0'; //Modulo rechnen, dan den ASCII Code von '0'addieren
95
spannung/=10;
96
}
97
utoa(spannung, string, 10);
98
schreibe_Zahl(string, 2, 5, 3);
99
_delay_ms(3000);
100
}
Das Display zeigt nun aber keine Zahlen zwischen 0 und 4.8 an, wie
gewünscht, sondern Zahlen wie .004.
Wird der Sensor ausgelöst, verändern sich die Zahlen, zum Beispiel zu
.002 oder .001
Gebe ich für meinen string zur Ausgabe eine manuelle Zahl ein, dann wird
diese aber korrekt angezeigt.
Folglich muss ich also iwo vorher einen Fehler gemacht haben...
Ich hoffe ihr könnt mir helfen!
Liebe Grüße
Eure Starfire
Hallo,
abgesehen von dem Hinweis von MWS habe ich zusätzlich folgendes gesehen:
Hier setzt Du Deine Zahl in einen String um:
Starfire schrieb:> for(i=10; i>=1; i--){> string[i] = (spannung%10) +'0'; //Modulo rechnen, dan den ASCII Code von
'0'addieren
> spannung/=10;> }
Um den String gleich darauf wieder zu überschreiben:
> utoa(spannung, string, 10);
Da hier die Variable Spannung 10 mal durch 10 geteilt wurde, steht wohl
nur noch die erste Ziffer drin. Du mußt Dich entscheiden, entweder die
eine oder die andere Variante.
Und vergiss die "schreibe_Zahl" Funktion.
Die ist schwer beschädigt. Wenn du der nicht einen String so
reinschiebst, wie sie ihn haben will, dann kracht sie ganz gewaltig.
>string[i]=(spannung%10)+'0';//Modulo rechnen, dan den ASCII Code von '0'addieren
3
>spannung/=10;
4
>}
5
>utoa(spannung,string,10);
6
>
entweder DU wandelst die Zahl selber in eine Textdarstellung oder du
lässt das utoa machen, aber nicht beides (und wenn du es selber machst,
dann musst du das auch richtig machen). Vor allen Dingen dann nicht,
wenn deine eigene Wandlung die Zahl bis auf die Einerstelle reduziert
(durch die fortgesetzte Division durch 10).
Lieber Karl Heinz,
warum einfach, wenn es auch kompliziert geht :D
Ich habe mal den Müll, den ich gemacht habe raus genommen und nur deinen
Code einprogrammiert...
Danke dafür, es Funktioniert! Mir hat wahrscheinlich lediglich die
Kenntniss von sprintf gefehlt... wieder was gelernt :)
Vielen Dank!
Starfire
Starfire schrieb:> Mir hat wahrscheinlich lediglich die Kenntniss von sprintf gefehlt...
sprintf() ist sehr mächtig, benötigt aber auch etlichen Speicherplatz.
Wenn man verschiedene Darstellungsvarianten benötigt oder genug Platz
hat, OK. Ansonsten sind die itoa-Funktionen nicht zu verachten.