Hallo zusammen,
nachdem ihr mir bisher immer so gut helfen konntet, hier mal wieder ein
Verständnisproblem :-)
Ich benutze einen Atmega8
Der ADC hat 10Bit, das Ergebnis einer Wandlung wird in 2 Byte (16Bit)
gespeichert.
In meinem Buch steht, dass ich das Ergebnis nach der Wandlung also um 6
Stellen nach rechts verschieben muss, um einen korrekten Wert zu
erhalten (klingt logisch).
Ich glaube in meinem Fall stimmt das aber nicht.
#include <avr/io.h>
#include <util/sbit.h>
int Dimmstufe =0;
int main(void)
{
DDRB |= (1<<PB1);
DDRD &= ~(1<<PD0);
ICR1 = 1024;
OCR1A = 0;
TCCR1A = (1<<WGM11)+(1<<COM1A1);
TCCR1B = (1<<WGM12)+(1<<WGM13)+(1<<CS10);
ADMUX |= (1<<REFS0);
ADCSRA |= (1<<ADEN)+(1<<ADPS0)+(1<<ADPS1)+(1<<ADPS2);
while (1)
{
ADCSRA |= (1<<ADSC);
while(ADCSRA &(1<<ADSC));
{
Dimmstufe = ADC;
//Dimmstufe = Dimmstufe >> 6;
OCR1A = Dimmstufe;
}
}
}
Zum Test wird eine PWM mit TOP(ICR1)=1024 verwendet.
Da der ADC mit 10bit (ebenfalls 1024) wandelt, ergibt sich dadurch eine
Dimmung zwischen 0-100%.
Der Ausgang wird aber nur zwischen 0-100% (1024) gedimmt, wenn ich die
Zeile mit dem Rechtsverschub nicht einbinde.
Wobei ich auch nicht ganz auf 0 herunterkomme, etwas leuchtet die Lamape
auch bei 0V auf dem ADC-Eingang..
Hallo Philipp L., das verschieben um 6 Bits scheint nur notwendig zu sein, wenn das Bit ADLAR gesetzt ist (vgl. [1], Seite 201). Da diese Bit mit 0 initialisiert wird, wird das Verschieben nicht benötigt. [1]: https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-2486-8-bit-AVR-microcontroller-ATmega8_L_datasheet.pdf
Ja, das ADLAR hatte ich auch schon gelesen. Wenn ich ADLAR aber einschalte und am Ende alles um 6 Bit verschiebe, bekomme ich nicht die gleiche Charakteristik wie ohne ADLAR und ohne verschieben. Mit ADLAR gibt ab einer Dimmstufe (evtl. so 50%??) einen Sprung in der Kennlinie zu 100%. Die untere Häfte sieht damit auch "komisch" aus. Sorry, kann den Verlauf schlecht erklären.
Das ADLAR Register (AD Left Adjust) steuert wie dein ADC-Messwert (10bit breit) im Ergebnisregister (16bit breit) abgelegt wird. ADLAR = 0 xxxx xx11 1111 1111 ADLAR = 1 1111 1111 11xx xxxx Das entspricht einem Shift von 6 bit. Du hast ADLAR nicht gesetzt und Timer 1 nutzt ebenfalls ein 16bit Register, also schreibst du Werte bis maximal 1024. Alles Shiny. bei gesetztem Bit müsstest du hingegen 6 Bits nach rechts shiften. Praktisch ist das Register, wenn du nach der Messung eh nur 8 bit weiter verarbeitest, denn dann kannst du deinen Messwert direkt aus dem höherwertigen Byte auslesen. Würdest du Timer0 benutzen, wäre das der Fall. Dass deine Lampe immer schwach leuchtet, liegt an der Konfiguration des Timers. Der Timer läuft über, setzt den Ausgang, resettet das Zählregister und wartet dann auf den Compare Match um wieder abzuschalten. Bei OCR1A = 0 passiert das beim nächsten Timertakt, aber der Ausgang wird immer zuerst mal eingeschaltet. Und das siehst du halt. Schau dir die Timer-Modi im Datenblatt nochmal genau an. Genau wegen solcher Probleme gibt es so viele unterschiedliche Ansteuerungsmöglichkeiten. Nachtrag: Dein Helligkeitssprung bei aktiviertem ADLAR wird daran liegen dass "int" als Datentyp erstmal 16bit signed ist. Da das Vorzeichen im MSB abgelegt wird, tritt der Fehler nur auf wenn du einen Wert von mehr als 50% am ADC-Eingang hast und das Ergebnis linksbündig ausgerichtet ist. Dann ist das MSB plötzlich 1 was eben nicht einen höheren Wert sondern ein invertiertes Vorzeichen zur Folge hat. Benutze die dafür vorgesehenen Datentypen, hier z.b. einen uint16_t. Damit sollte das Problem verschwinden.
Danke, das war eine sehr gute Erklärung ! Habe auf deine Empfehlung nochmals gelesen und auf einen anderen Modus (Phasenkorrekte-PWM) umgestellt, kann nun auch bis 0 runterdimmen. Ich habe zwar die Grundfunktion mit Hoch/Runterzählen verstanden. aber hier gibt es doch den Zeitpunkt, in dem der Zähler bei 0 ist und wieder anfängt hochzuzählen. Warum schaltet er in diesem Moment nicht den Ausgang auf 1, da Zähler und OCR1A identisch sind. Ist es also richtig, dass ich mit Fast-PWM in keiner Einstellung bis 0 runterdimmen kann?
Philipp L. schrieb: > Ist es also richtig, dass ich mit Fast-PWM in keiner Einstellung bis 0 > runterdimmen kann? Ja. Steht im Datenblatt: "The extreme values for the OCR1x Register represents special cases when generating a PWM waveform output in the fast PWM mode. If the OCR1x is set equal to BOTTOM (0x0000) the out- put will be a narrow spike for each TOP+1 timer clock cycle."
Danke. Ich habe für das Anschlussproblem (Flackern) einen neuen Thread aufgemacht.
Philipp L. schrieb: > Wenn ich ADLAR aber einschalte und am Ende alles um 6 Bit verschiebe, > bekomme ich nicht die gleiche Charakteristik wie ohne ADLAR und ohne > verschieben. Das liegt daran, daß du für die Variable "Dimmstufe" den Typ int genommen hast. Es sollte aber ein unsigned int sein. Diese Typen verhalten sich unterschiedlich beim Rechsschieben. Stichwort: Vorzeichen.
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.