Guten Tag, ich habe einmal eine Frage bezüglich des wechseln von Kanälen unterschiedlicher ADCs. Aufgabe: Ich möchte mit einem Poti am Eingang eines ADCs eine Pulsweite für ein PWM einstellen, dies funktioniert auch soweit. Ich habe eine feste Periodendauer und mit dem Poti kann ich die Zeit Tein einstellen. Mit dem PWM Signal schalte ich dann über einen Treiber ein MOSFET. Hier möchte ich dann am Ausgang den Strom messen und über einen zweiten ADC des µC auswerten. Zu testzwecken habe ich hier auch erst einmal ein Poti angeschlossen, mit dem ich den Spanungswert einstelle. Einzeln funktionieren beide ADCs, ich kann mit dem einen Poti die PWM einstellen und mit dem anderen Poti eine Spannung einstellen und mit einem Grenzwert vergleichen und dann feste Zeiten Tein setzen und ausgeben. Nun soll aber beiden nacheinander dynamisch laufen. Zunächst soll der Stromwert kontrolliert werden, ist dieser in Ordnung, soll das Poti für die PWM ausgelesen und verarbeitet werden. Danach soll wieder der Stromwert überprüft werden usw. Ist der Stromwert nicht in Ordnung, soll ein fester Wert für die Zeit Tein eingestellt werden. Der Wert des Potis soll dann erst wieder verwendet werden, wenn der ADC Wert für die PWM den Grenzwert unterschreitet. Nun scheint in meinem Programm jedoch der Wechsel zwischen den beiden Kanälen der unterschiedlichen ADCs nicht richtig zu funktionieren. Ich habe hierzu schon einige Möglichkeiten rausgesucht gehabt und ausprobiert, jedoch habe ich es immer noch nicht zum Laufen bekommen. Angehängt habe ich einmal mein Programm, vielleicht könnt ihr mir einmal sagen, was ich falsch. mache. – Vielen Dank schon einmal im Voraus.
Hi
> // Vorteiler: 16 ; ADC_Frequenz 1MHz
Atmel gibt für 10Bit-ADC eine maximale Frequenz von 200kHz an.
MfG Spess
So
1 | ADMUX |= (0 << MUX2) | (1 << MUX1) | (0 << MUX0); // Eingang unserer Messung ist "ADC2", also Poti an PA2 |
kriegst du aber die einmal auf 1 gesetzten Bits nicht wieder auf 0 zurück. Siehe Bitmanipulation Bits setzen: eine Oder Operation Bits löschen: eine Und Operation Warum verwendest du nicht die ADC Routinen aus dem Tutorial? Die machen das richtig, dass sie den gewählten Kanal ins MUX Register eintragen. https://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/Analoge_Ein-_und_Ausgabe#Der_interne_ADC_im_AVR WIe machen sie das? indem sie mit einer Und-Operation erst mal alle MUX Bits auf 0 zwingen und dann hinterher mit einer Oder Operation die gewünschten wieder auf 1 bringen.
1 | uint16_t ADC_Read( uint8_t channel ) |
2 | {
|
3 | // Kanal waehlen, ohne andere Bits zu beeinflußen
|
4 | ADMUX = (ADMUX & ~(0x1F)) | (channel & 0x1F); |
5 | ...
|
:
Bearbeitet durch User
Du musst die Bits MUX2, MUX1 und MUX0 in ADMUX zurücksetzen, bevor Du mit ihnen den nächsten ADC-Eingang auswählst:
1 | // lösche Bits MUX2 - MUX0:
|
2 | ADMUX &= ~((1 << MUX2) | (1 << MUX1) | (1 << MUX0)); |
3 | |
4 | // setze neue Bits MUX2 - MUX0 zur ADC-Eingangswahl:
|
5 | ADMUX |= (1 << MUX2) | (0 << MUX1) | (0 << MUX0); |
Gruß, STefan
Super, vielen Dank Stefan und Karl Heinz, für die schnelle Antwort. Jetzt funktioniert der Wechsel zwischen den ADCs! spess53: Die Frequenz zwischen 50kHz und 200kHz ist ja nur ein Richtwert, in dem der ADC optimal arbeitet. Es funktioniert aber auch mit der Frequenz von 1MHz.
Marc schrieb: > Die Frequenz zwischen 50kHz und 200kHz ist ja nur ein Richtwert, in dem > der ADC optimal arbeitet Nee, eigentlich sind das die Spezifikationen, an die man sich halten sollte damit alles glatt läuft... > Es funktioniert aber auch mit der Frequenz von > 1MHz. Dann schnell ne Email an Atmel das sie sich geirrt haben und dringlichst ihre Specs ändern sollten.
Marc schrieb: > Die Frequenz zwischen 50kHz und 200kHz ist ja nur ein Richtwert, in dem > der ADC optimal arbeitet. Es funktioniert aber auch mit der Frequenz von > 1MHz. Kommt drauf an, was du als "funktioniert" definierst. Das der ADC oder der AVR nicht in Rauch aufgehen wird, dürfte klar sein. Wenn dann auch noch der Zahlenwert aus dem ADC abhängig vom Eingangswiderstand stimmen soll, sollte man sich schon an die Spec halten. Aber seis drum. Die spannende Sache kommt ja sowieso noch: die Synchronisierung des ADC mit der PWM. Speziell bei kleinen Duty Zyklen.
:
Bearbeitet durch User
Karl Heinz schrieb: > Die spannende Sache kommt ja sowieso noch: die Synchronisierung des ADC > mit der PWM. Speziell bei kleinen Duty Zyklen. Ein Ding der Unmöglichkeit bei der PWM-Frequenz. Wandlungsdauer wäre 13,5µs, Periodendauer eines PWM-Zykluses ist aber nur 10µs ;) Unmöglich im Sinne von "Ich erfasse jeden PWM-Zyklus". Das S&H geht schneller, klar... Man muss hier ganz klar festhalten, dass der ADC vom Tiny/Mega veraltet ist und lange nicht mehr Stand der Technik. Das es besser geht zeigen die XMega.
:
Bearbeitet durch User
Ingo Less schrieb: >> Es funktioniert aber auch mit der Frequenz von >> 1MHz. > Dann schnell ne Email an Atmel das sie sich geirrt haben und dringlichst > ihre Specs ändern sollten. aus dem Datenblatt der ATmega164..1284: "Table 28-17. ADC characteristics, single ended channel" "Absolute accuracy (Single Ended Conversion VREF = 4V, VCC = 4V, ADC clock = 1MHz, Noise Reduction Mode): 3.25 LSB"
S. Landolt schrieb: > Ingo Less schrieb: >>> Es funktioniert aber auch mit der Frequenz von >>> 1MHz. >> Dann schnell ne Email an Atmel das sie sich geirrt haben und dringlichst >> ihre Specs ändern sollten. > > aus dem Datenblatt der ATmega164..1284: Schön. Nur ist für einen Mega32 das Datenblatt des Mega32 relevant
Hi
>Nur ist für einen Mega32 das Datenblatt des Mega32 relevant
Der ist sogar besser. Bei dem sind es nur 3 LSB und nicht 3,25 LSB. Und
trotzdem steht der Satz mit den 50KHz...200kHz im Datenblatt.
MfG Spess
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.