Guten Abend zusammen, trotz Lesens aller möglichen Seiten gelingt es mir nicht, das beiliegende Prg. so zu gestalten, wie ich's gern hätte. Hardware STK200, ATmega88, LCD an PortD. Die Hardware funktioniert mit Bascom wie gewünscht. LCD Library v. Peter Fleury (PORT geändert). Auch das zugehörige Testprogramm funktioniert einwandfrei. Problem: lcd_puts(buffer); gibt nicht die erwarteten 0....1023 aus sondern eine eher zufällige zweistellige Zahl. Wo kann der Fehler liegen, im ADC Wandlerteil oder bei der Umwandlung mit utoa? Danke für ev. Hinweise Toni #include <stdlib.h> #include <avr/io.h> #include <avr/pgmspace.h> #include <util/delay.h> #include <avr/io.h> #include <inttypes.h> #include "lcd.h" uint16_t readADC(uint8_t channel) { uint8_t i; uint8_t ADC_temp; uint8_t ADCH_temp; uint16_t result = 0; // Den ADC aktivieren und Teilungsfaktor auf 64 stellen ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1); // Kanal des Multiplexers waehlen // Avcc als Referenzspannung verwenden ADMUX = channel | (0<<REFS1) | (1<<REFS0); // Den ADC initialisieren und einen sog. Dummyreadout machen ADCSRA |= (1<<ADSC); while(ADCSRA & (1<<ADSC)); // Jetzt 3x die analoge Spannung am Kanal "channel" auslesen // und dann Durchschnittswert ausrechnen. for(i=0; i<3; i++) { // Eine Wandlung ADCSRA |= (1<<ADSC); // Auf Ergebnis warten... while(ADCSRA & (1<<ADSC)); //Ergebnisregister auslesen ADC_temp = ADCL; ADCH_temp = ADCH; ADC_temp += (ADCH_temp << 8); result += ADC_temp; } // ADC wieder deaktivieren ADCSRA &= ~(1<<ADEN); result /= 3; return result; } int main(void) { char buffer[7]; //Auslesen der analogen Spannung an ADC0, //In result steht das Ergebnis. uint16_t result = readADC(0); //initialize display, cursor blinkt lcd_init(LCD_DISP_ON_CURSOR_BLINK); //clear display and home cursor lcd_clrscr(); //integer in ASCII umwandeln utoa( result , buffer, 10); lcd_puts("Ergebnis:\n"); lcd_puts(buffer); return 0 }
Toni schrieb: > ADC_temp += (ADCH_temp << 8); ADC_temp ist 8 Bit deklariert und Du versuchst einen 16 Bit Wert zu addieren. btw - Du könntest auch die Formatierung einsetzen - dann ist Dein Code etwas lesbarer:
1 | C-Code |
Servus Dieter, kaum macht man es richtig, schon funktioniert es! Vielen Dank und liebe Grüße Toni
In C brauchst du diesen 'komplizierten' Teil
1 | ADC_temp = ADCL; ADCH_temp = ADCH; |
2 | ADC_temp += (ADCH_temp << 8); |
3 | result += ADC_temp; |
überhaupt nicht. Du verwendest einfach das Pseudo-Register 'ADC' und der Compiler dröselt das alles richtig auf und setzt die Werte für dich zusammen
1 | for(i=0; i<3; i++) { |
2 | // Eine Wandlung
|
3 | ADCSRA |= (1<<ADSC); |
4 | // Auf Ergebnis warten...
|
5 | while(ADCSRA & (1<<ADSC)); |
6 | //Ergebnisregister auslesen
|
7 | result += ADC; |
8 | }
|
Siehe auch den ADC Abschnitt im AVR-GCC-Tutorial
Das hatte ich auch versucht, aber irgendwie trotzdem die falsch deklarierte Variable im Spiel gehabt! Nochmals Danke für die Hilfe Toni
Toni schrieb: > Das hatte ich auch versucht, aber irgendwie trotzdem > die falsch deklarierte Variable im Spiel gehabt! :-) Wie kann eine Variable, die gar nicht gebraucht wird und daher im Code gar nicht mehr existiert, falsch deklariert sein? :-) (genau das ist der springende Punkt. Da geht es nicht nur darum, dass der Code kürzer wird. Es geht auch darum, dass durch die Vereinfachung auch Fehlerquellen wegfallen)
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.