Hallo zusammen, Ich habe mich eben an einer AD wandlung versucht. Wenn ich das Ergebnis auf dem LCD ausgeben möchte erhalte ich nur Werte von 0-258. Es sollte ja von 0-1024 bei 10 Bit sein. Ich denke mein Fehler liegt in der Umformung. Hier mal mein Code: unsigned int adcval; char adcbuffer[33]; if (channel == 2){ ADMUX = 0x42; // MUX ADC2 } ADCSRA |= (1<<ADSC); while ( ADCSRA & (1<<ADSC) ) { } adcval = ADCL; adcval += ADCH; itoa(adcval, adcbuffer,10); lcd_write_txt(adcbuffer);
> adcval = ADCL; > adcval += ADCH; Du hast einfach nur Low- und High-Byte addiert. Besser:
1 | adcval = ADCL; |
2 | adcval += ADCH << 8; |
Noch besser:
1 | adcval = ADC; |
Jetzt wo die Ausgabe sauber funktioniert (werte von 0-1023), würde ich diese auch gerne einer Spannung zuordnen. Das was ich hinbekomme ist, dass ich Ganzzahlen von 0-4 (Volt) ausgeben kann. Nur meine Nachkommastellen verschwinden. Wär super wenn ihr mir da auch noch mal weiterhelfen könnt. Hier wieder ein Auszug:
1 | unsigned int adcval; |
2 | unsigned int adcbuffer; |
3 | float result; |
4 | |
5 | |
6 | void lcd_write_txt(char *txt) { |
7 | while(*txt) { |
8 | lcd_write(*txt); |
9 | txt++; |
10 | }
|
11 | }
|
12 | |
13 | int adc_getval(int channel){ |
14 | |
15 | if (channel == 0){ |
16 | ADMUX = 0x40; // MUX ADC0 Uref = 5V |
17 | }
|
18 | |
19 | if (channel == 1){ |
20 | ADMUX = 0x41; // MUX ADC1 Uref = 5V |
21 | }
|
22 | |
23 | if (channel == 2){ |
24 | ADMUX = 0x42; // MUX ADC2 Uref = 5V |
25 | }
|
26 | |
27 | ADCSRA |= (1<<ADSC); |
28 | |
29 | while ( ADCSRA & (1<<ADSC) ) { |
30 | }
|
31 | |
32 | |
33 | adcval = ADCL; |
34 | adcval += ADCH <<8; |
35 | |
36 | result = adcval*(5.0/1024.0); |
37 | |
38 | itoa(result, adcbuffer,10); |
39 | |
40 | return adcbuffer; |
41 | }
|
42 | |
43 | int main (void){ |
44 | lcd_write_txt(adc_getval(0)); |
45 | }
|
Ich tippe irgendwie auf die nutzung von itoa(); und meine funktion müsste ja eigentlich auch einen char zurückgeben. Wenn ich diese als char deklariere kommt die Warnung vom Compiler: passing argument 2 of 'itoa' makes pointer from integer without a cast.
Festkommaarithmetik! Gleitkomma-Berechnungen sind auf einem µC nicht nur Ressourcenfresser, sondern in diesem Fall auch völlig unsinnig. Und die Funktion heißt nicht umsonst itoa (integer to ascii), weil sie integer-Werte (ganzzahlige Werte) in einen ASCII-String konvertiert, und mit float nix anfangen kann. Und in integer gibt es nunmal keine Nachkommastellen. Für Gleitkommawerte gibt es zwar dtostrf bzw. dtostre , aber wie schon gesagt, lass es lieber sein.
Ach übrigens: Du solltest Dir dringendst mal die Dokumentation der Funktion itoa in der libc-Doku anschauen! Das mit Deinem adcbuffer kann so nicht funktionieren. Ein String wird in C als Array of char abgelegt und ist außerdem noch nullterminiert, braucht also ein Zeichen mehr als der eigentliche String hat. Wenn Du etwas Sinnvolles rausbekommen willst, dann so
1 | char adcbuffer[5]; |
Das reicht dann für eine Vorkommastelle, den Dezimalpunkt und zwei Nachkommastellen (wie man die in integer berechnet, müsstest Du eben anhand des Artikels Festkommaarithmetik herausfinden). Und das itoa machste entweder in main oder Du gibst einen Zeiger auf den Buffer zurück.
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.