Hallo zusammen, ich möchte gerne zwei analoge Signale mit dem ATMEGA8 einlesen. Bei den einzelnen Kanälen klappt dies auch, aber eben leider nicht bei beiden gleichzeitig. Was gibt es da alles besonderes zu beachten. Anbei noch mein C-Code. Achja, die beiden Funktionen werden im Hauptprogramm nacheinander aufgerufen. Vielen Dank. Gruß Thomas unsigned char U_poti_Eingang() { DDRC &= 0b11111110; unsigned char U_poti=0; ADMUX |= 0b01100000; // Einlesen des Kanals 0 usw. ADCSRA|= 0b11000000; while (ADCSRA &0b01100000) // Überprüfung: Abschluss der Wandlung {} U_poti=ADCH; return U_poti; // Wertebereich: 0-255 } unsigned char U_LED_Eingang() { DDRC &= 0b11111101; unsigned char U_LED=0; ADMUX |= 0b01100001; // Einlesen des Kanals 1 usw. ADCSRA|= 0b11000000; while (ADCSRA &0b01100000) // Überprüfung: Abschluss der Wandlung {} U_LED=ADCH; return U_LED; // Wertebereich: 0-255 }
:
Verschoben durch Admin
> ADMUX |= 0b01100000; // Einlesen des Kanals 0 usw.
Hier habe ich beim Lesen kapituliert.
Krapao schrieb: >> ADMUX |= 0b01100000; // Einlesen des Kanals 0 usw. > > Hier habe ich beim Lesen kapituliert. Ja, sorry für die schlechte Beschreibung. Ja die letzten vier Bits beziehen sich auf den Anschluss zum Poti. Also MUX0-MUX3. Und da alle vier Bits Null sind ist es ja der Anschluß ADC0 des µC. War für mich ne Bezeichnung wo ich das Kabel anzuschließen habe.
Durch die absoluten Bitmasken ist es sau schwer direkt zu sehen, ob dein Code richtig ist. Mit den symbolischen Bitnamen aus den Includefiles ist es wesentlich einfacher zu sehen, ob der Code dem bekannten Code z.B. im AVR-GCC-Tutorial entspricht. Deinen Code kann man nur mit intensivem Lesen des Atmega8 Datenblatts überprüfen. Bei der Stelle > while (ADCSRA &0b01100000) // Überprüfung: Abschluss der Wandlung > {} ist was faul. Ich erwarte da eine Bitmaske mit einem gesetzten Bit, nicht zwei wie in deinem Code. Ich würde auch die bewährte Auftrennung in die einmalige ADC-Initialisierung und ggf. regelmäßige ADC-Kanalumschaltung/Auslesen beibehalten, so wie sie im Tutorial verwendet wird.
Wenn du ADMUX|=(1<<REFS0)|(1<<ADLAR); schreibst dann muss sich der Leser nicht das Datenblatt heraussuchen um zu verstehen was du meinst. Warum aktivierst du das immer wieder, es genügt doch einmal im main.
Deine SChreibweise wurde ja schon zur Genüge angesprochen. Zu noch einem Fehler (neben der Abfrage ob er fertig ist)
1 | ADMUX |= 0b01100001; // Einlesen des Kanals 1 usw. |
und wie erwartest du, dass das ganz rechte 1 Bit (für Kanal 1) jemals wieder gelöscht wird?
1 | ADMUX |= 0b01100000; // Einlesen des Kanals 0 usw. |
kann das nicht leisten. Mit einem Oder (|) kann man BIts nur auf 1 zwingen, nicht jedoch auf 0 zurücksetzen. Schau dir die ADC Routinen im AVR-GCC-Tutorial an, die berücksichtigen das. Und wenn du schon dabei bist könntest du auch ganz einfach die Routinen von dort verwenden. Die sind sauber geschrieben und berücksichtigen deine Kanalumschaltung. Im Prinzip weißt du ja wie's geht, daher spricht nichts dagegen, wenn du fix&fertige Funktionen dafür einsetzt, die dann auch noch die letzten Feinheiten berücksichtigt haben. Kein Grund das Rad neu zu erfinden und in 3 Anweisungen 4 vermeidbare Fehler zu machen.
Hi, das wird nicht funktionieren:
> while (ADCSRA &0b01100000)
Du meinst sicherlich:
1 | while (ADCSRA &(1<<ADSC)); |
Grüße, Ingo
Hubert G. schrieb: > Wenn du ADMUX|=(1<<REFS0)|(1<<ADLAR); schreibst dann muss sich der Leser > nicht das Datenblatt heraussuchen um zu verstehen was du meinst. > Warum aktivierst du das immer wieder, es genügt doch einmal im main. Ah okay, wird diese Art der Schreibweise "(1<<REFS0)|(1<<ADLAR)" als "symbolische Bitnamen" benannt? Hab davor gedacht die absolute Schreibweise ist eindeutiger. Ich wollte damit nur ausschließen, dass mir durch das Kompilieren oder durch andere Programme die Register verändert werden. Danke für die vielen Hinweise. Werde mich dann jetzt erst nochmals mit der Kanalumschaltung ausführlich befassen.
@ Thomas (Gast) >Ah okay, wird diese Art der Schreibweise "(1<<REFS0)|(1<<ADLAR)" als >"symbolische Bitnamen" benannt? Ja. > Hab davor gedacht die absolute >Schreibweise ist eindeutiger. Nein.
Hallo Freunde, ich möchte gerne mit einem Atmega16 zwei verschiedene Analogsignale an den Pins PA0 und PA1 abtasten. Leider bin ich noch Anfänger und muss noch viel herum probieren und lesen dazu. Aber jetzt komme ich wirklich nicht mehr weiter. Vielleicht kann mir ja mal einer einen Tip geben und sagen, was an dem unten aufgeführten Code nicht richtig ist. Wenn ich nur über den ADC PA0 einlese funktioniert es, was ich dann über das PWM TImer1 auch sauber angezeigt bekomme. Möchte ich jedoch beide Pins abtasten, reagiert er wieder nur auf PA0 und lässt PA1 scheinbar außer acht. Danke im Voraus. Jens #include <avr/io.h> #ifndef F_CPU #define F_CPU 4000000UL #define ADATE 5 #endif #include <util/delay.h> int main(void) { uint16_t wert1; uint16_t wert2; DDRB |= (1 << DDB3); // Setup PB0 as output while(1) { //erstes Abtasten ADMUX |= (1<<REFS0); ADCSRA |= (1<<ADEN)|(1<<ADATE)|(1<<ADPS2)|(1<<ADSC); while(!(ADCSRA&(1<<ADSC))); // Wait until a conversion is finished wert1 = ADC; //zweites Abtasten ADMUX |= (1<<REFS1); ADCSRA |= (1<<ADEN)|(1<<ADATE)|(1<<ADPS2)|(1<<ADSC); while(!(ADCSRA&(1<<ADSC))); // Wait until a conversion is finished wert2 = ADC; //über PWM Timer1 ausgeben DDRD |= (1 << DDB4); DDRD |= (1 << DDB5); TCCR1A = (1<<WGM10)|(1<<WGM11)|(1<<COM1A1)|(1<<COM1B1); TCCR1B = (1<<WGM12)|(1<<CS11)|(1<<CS10); OCR1A = wert1; OCR1B = wert2; } return 0; }
Was war an diesem Hienweis nicht verständlich? >>> Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. >>> Bitte hier nur auf die ursprüngliche Frage antworten, >>> für neue Fragen einen neuen Beitrag erstellen.
Hi >//erstes Abtasten > ADMUX |= (1<<REFS0); >//erstes Abtasten > ADMUX |= (1<<REFS0); Damit schaltest du die Referenzspannungsquelle aber nicht die Kanäle um. Außerdem konfiguriert man den ADC nicht ständig in der while-Schleife. das macht man einmal davor. In der Schleife brauchst du nur die ADMUX-Bits und ADSC anfassen. MfG spess
1 | ADMUX |= 0b01100000; |
2 | ... |
3 | ADMUX |= 0b01100001; |
Das mit dem "|=" ist keine gute Idee! Damit wird irgendwann mal der Kanal auf 1 gestellt und "|= 0" macht das nicht rückgängig! Du mußt entweder Deinen Code auf "=" umstellen oder vor dem "|=" mit "&= ..." die Kanalbits löschen.
Max fragte:
>Was war an diesem Hienweis nicht verständlich?
Wo ist Deine Hilfe? Ich sehe sie nicht.
Bist Du einer der Typen, die den TO, wenn er wirklich einen neuen
Beitrag
verfasst hätte, auch nur auf die Suchfunktion hinweisen und nicht helfen
wollen oder können?
Ist es Deiner Meinung nach sinnvoll, 10 gleichartige Threads mit nicht
Einer Lösung des Problemes zu haben?
Das mußte mal raus....
Sorry, ich hatte das verteilt. Ja ich werd dazu was komplett neues erstellen.
Return of Schnulli schrieb: > Wo ist Deine Hilfe? Ich sehe sie nicht. Deine ist auch nicht vorhanden. Return of Schnulli schrieb: > Bist Du einer der Typen, die den TO, wenn er wirklich einen neuen > Beitrag verfasst hätte, auch nur auf die Suchfunktion hinweisen Wenn ich nicht richtig erinnere, habe ich das noch nie gemacht oder mindestens nicht in nennenswerter Menge.
@ Max H. (hartl192) was lässt du dich als registrierter User hier von so einem Blockwart denunzieren? setz den auf die Ignoliste und gut ist, oder suche seine Beiträge hier, der kann nur Rummosern - fachl. Tiefflieger
Jens schrieb: > Sorry, ich hatte das verteilt. Ja ich werd dazu was komplett neues > erstellen. Dann schreib doch gleich den Link - wer soll sich da sonst noch zurecht finden. Oder ein Mod erbarmt sich und löscht hier den ganzen, an den alten Thread rangeklatschten Mist.
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.