Hallo zusammen,
Ich probiere schon seit einiger Zeit meinen AD-Wandler zum laufen zu
bekommen. habe auch schon echt viel mit IR-Bit enable/disable
rumprobiert, aber irgendwie läuft der net richtig. Nach Angaben im
Datenblatt habe ich eigentlich alles richtig konfiguriert, aber der
läuft leider immer noch nicht.
Habe hier mal ein Auszug meines programmes.
Martin28 schrieb:> Hallo zusammen,>> Ich probiere schon seit einiger Zeit meinen AD-Wandler zum laufen zu> bekommen. habe auch schon echt viel mit IR-Bit enable/disable> rumprobiert, aber irgendwie läuft der net richtig.
Wie wärs, wenn du den erst mal konventionell, zb laut
AVR-GCC-Tutorial zum Laufen bringst.
In deinem Code sind so viele Stolpersteine, dass man gar nicht weiß, wo
man anfangen soll mit der Korrektur.
> int main(void)> {>> DDRC |= (0<<PC5)|(0<<PC4)|(0<<PC3)||(0<<PC2)|(0<<PC1)|(0<<PC0);> // AD-Channels>> DDRD |=> (1<<PD7)|(1<<PD6)|(1<<PD5)|(1<<PD4)|(1<<PD3)|(1<<PD2)|(1<<PD1)|(1<<PD0);> // LED´s>> while(1)> {> Init_Timer0();> AD_INIT_Test();>> }
Was soll das bringen, ADC und Timer ständig neu zu initialisieren? Lass
doch die Dinge arbeiten, wenn sie erst mal richtig konfiguriert sind!
>> return(0);> }>> void AD_INIT_Test(void)> {>> ADMUX |= (0<<REFS1)|(1<<REFS0);> ADMUX |= (0<<ADLAR);>>> ADMUX |= (0<<MUX3)|(1<<MUX2)|(0<<MUX1)|(1<<MUX0); // ADC - 5> //ADMUX |= (0<<MUX3)|(1<<MUX2)|(0<<MUX1)|(0<<MUX0); // ADC - 4>> ADCSRA |= (1<<ADPS2)|(1<<ADPS1)|(0<<ADPS0);>> // Set ADC Scaler to 125KHz Sample rate @ 8MHz> // 8MHz / 64 = 125kHz || 110 = 64>>> //ADCSRA &= ~(1 << ADATE); // Disable free running Mod>> //ADCSRB |= (0<<ADTS2)|(0<<ADTS1)|(0<<ADTS0);// 000 Free Running Mode> ADCSRB |= (0<<ADTS2)|(1<<ADTS1)|(1<<ADTS0);// 011 Compare Match> TIMER.0> //ADCSRB |= (1<<ADTS2)|(0<<ADTS1)|(0<<ADTS0);// 100 --> Timer.0> Overflow> ADCSRB |= (0<<ACME);>> ADCSRA |= (1<<ADEN); // ADC Enable> ADCSRA |= (1<<ADATE); // Auto trigger Mode enabled> //ADCSRA |= (1<<ADSC); // Start Single Conversion>> while (ADCSRA & (1<<ADSC)) // Wait for result> {}>> PORTD = ADCL; // Write result on Port.D --> LED
L lesen alleine reicht nicht.
Du MUSST das H Register lesen! Zwingend.
>> ADCSRA |= (1<<ADIE); // Enable ADC Interrupt> }>>>> ISR(ADC_vect)> {>> ADCSRA &= ~(1<<ADIE); // Disable ADC Interrupt --> Stop> ADCSRA |= (1 << ADIE); // Enable ADC Interrupt> ADCSRA |= (0 << ADIF); // Reset Interrupt Flag
Interrupt Flags werden anders gelöscht. Ausserdem passiert das in der
ISR alles automatisch. Lass doch den ADC enabled. Was soll das bringen,
den jedesmal ein bzw. auszuschalten.
Viel wichtiger wäre es, sich das Ergebnis abzuholen. Aber ausgerechnet
das tust du nicht.
>> // ADCSRA |= (1 << ADSC); // Start single conversion> }>> void Init_Timer0(void)> {>>> TCCR0A |= (0<<WGM02)|(1<<WGM01)|(1<<WGM00); // Fast PWM Mode> TCCR0A |= (1<<COM0A1)|(0<<COM0A0); // clear OC0A @ Compare Match>> TCCR0B = (1<<CS02)|(0<<CS01) |(1<<CS00);> // Clock Division: clk/1024 --> 8.MHz / 1024 = 7812.5 Hz / 255 = 30Hz>>> TIMSK0|= (1<<OCIE0A); // Enable Output Compare Flag> TIMSK0|= (1<<TOIE0); // Enable Overflow Flag>> OCR0A = 1; // shortest edge width> }>>>> //----------------------------------------------------------------------
----------------------------------------------
> // ISR Timer.0> //----------------------------------------------------------------------
----------------------------------------------
>>> ISR(TIMER0_COMPA_vect)> {> // clear Compare Flag>> TIFR0 = (0<<OCF0A);>
Lass das Flag in Ruhe. (So löscht du es sowieso nicht). Das wird schon
ganz von alleine gelöscht, sobald die ISR betreten wird. Darum brauchst
du dich nicht kümmern.
> }>> ISR(TIMER0_OVF_vect)> {> // clear Overflow Flag>> TIFR0 = (0<<TOV0);
Detto.
>> }
Wozu brauchst du die ISR, wenn du sowieso nichts da drinnen machst?
Sind nur potentielle Fehlerquellen.
Die Bits für den Auto Trigger des ADC hab ich nicht kontrolliert. Wie
gesagt: bring halt erst mal den ADC ganz konventionell zum Laufen.
Danke das dir mal zeit genommen hast drüberzuschauen...
Karl Heinz Buchegger schrieb:> L lesen alleine reicht nicht.> Du MUSST das H Register lesen! Zwingend.
Ja habe auf meinem Board, leider nur 8 Led´s von den es mir vorerst
reicht nur die unteren 8 für die Testzwecke zu lesen.
Karl Heinz Buchegger schrieb:> Lass doch den ADC enabled. Was soll das bringen,> den jedesmal ein bzw. auszuschalten.
War noch von meinem anderen Programm so drinne, da Ich genau zwischen
diesen 2 Zeilen Disable/Enable den ADC Kanal umstelle. Was Ich auch
wieder einfügen werde sobald Ich den mal richtig zum laufen gebracht
habe...aber vorerst hast auf jeden Fall recht. Weg damit!
Karl Heinz Buchegger schrieb:> Viel wichtiger wäre es, sich das Ergebnis abzuholen. Aber ausgerechnet> das tust du nicht.
Ist es also sinnvoller in der ISR das Ergebnis an eine
Variable,Port,etc. zu übergeben? Da es bei mir ja nur in der Init
Methode abgeholt worden ist...
Karl Heinz Buchegger schrieb:> Wozu brauchst du die ISR, wenn du sowieso nichts da drinnen machst?> Sind nur potentielle Fehlerquellen.
Geb Ich dir vollkommen recht.
spess53 schrieb:> sei() oder wie das in C heisst fehlt auch. Ohne sieht es mau mit> interrupts aus.
Stimmt. Bei den meisten sind ja 2 Anforderungen für freigabe des IR
nötig. I-Bit SREG und das IR freigabe bit der Einheit
Martin28 schrieb:> Danke das dir mal zeit genommen hast drüberzuschauen...>> Karl Heinz Buchegger schrieb:>> L lesen alleine reicht nicht.>> Du MUSST das H Register lesen! Zwingend.>> Ja habe auf meinem Board, leider nur 8 Led´s von den es mir vorerst> reicht nur die unteren 8 für die Testzwecke zu lesen.
Ist egal.
Du MUSST das H-Register lesen.
Wird das L-Register gelesen, wird der komplette ADC gegen Updates
gesperrt. Erst das lesen des H-Registers löst diese Sperre wieder.
Kein Lesen vom H-Register ... keine Updates.
Martin28 schrieb:>> Viel wichtiger wäre es, sich das Ergebnis abzuholen. Aber ausgerechnet>> das tust du nicht.>> Ist es also sinnvoller in der ISR das Ergebnis an eine> Variable,Port,etc. zu übergeben? Da es bei mir ja nur in der Init> Methode abgeholt worden ist...
Du musst unterscheiden zwischen
* Initialisierung
* laufender Betrieb
Initialisierung sind alle Schritte, die notwendig sind, um eine
Komponente in einen lauffähigen Zustand zu versetzen
der laufende Betrieb macht das was sein Name sagt: Was gibt es in der
Hauptschleife zu tun.
Initialisiert wird normalerweise nur einmal!
> Stimmt. Bei den meisten sind ja 2 Anforderungen für freigabe des IR> nötig. I-Bit SREG und das IR freigabe bit der Einheit
Nicht bei den meisten.
JEDE Komponente hat eine speziell auf sie abgestimmte
Interrupt-Freigabe. Und dann gibt es noch die globale
Interrupt-Freigabe. Ist die auf 'aus' gibts keine Interrupts.
Karl Heinz Buchegger schrieb:> Wird das L-Register gelesen, wird der komplette ADC gegen Updates> gesperrt. Erst das lesen des H-Registers löst diese Sperre wieder.> Kein Lesen vom H-Register ... keine Updates.
Dann ist das glaube Ich mal einer der großen Fehlerquellen die Ich habe.
Denn Ich habe hier schon die ganze Zeit an meinem Poti rumgedreht und
der Wert wurde nie aktualisiert.
Werde mal alles verbessern und dann alles nochmal posten.
Vielen Dank erstmal für die ausführliche Hilfe
Gruß Martin
Guten Abend nochmal,
also Ich habe es jetzt hinbekommen! Es lag unter anderem auch
tatsächlich an der allgemeinen IR Freigabe sei()
Noch eine kleine Frage, wie bekomme Ich es hin das mein Programm das Ich
posten will auch mit einem schönen "weißen" Hintergrund zu sehen ist?^^
Grüße Martin
Noch eine Frage,
meine U(Dach) Spannung des Timer.0 sind etwas über 3V. Da mein ADC jetzt
komischerweise ab einer Spannung von auch etwa 3V jetzt nichts mehr
messen kann(wird zumindest NICHT) auf die LEDS ausgegeben, habe Ich mir
gedacht es könnte eben gerade an der Spannung des Timers liegen.
Ist es nicht normal das die Output Amplitude des Timers nicht 5V
entsprechen sollte?
Grüße Martin
Martin28 schrieb:> Noch eine kleine Frage, wie bekomme Ich es hin das mein Programm das Ich> posten will auch mit einem schönen "weißen" Hintergrund zu sehen ist?^^
Die Anleitung lesen, die direkt über dem Fenster steht, in das du deinen
Text eingibst. Die steht ja nicht zum Spaß da...
Martin28 schrieb:> meine U(Dach) Spannung des Timer.0 sind etwas über 3V. Da mein ADC jetzt> komischerweise ab einer Spannung von auch etwa 3V jetzt nichts mehr> messen kann(wird zumindest NICHT) auf die LEDS ausgegeben, habe Ich mir> gedacht es könnte eben gerade an der Spannung des Timers liegen.> Ist es nicht normal das die Output Amplitude des Timers nicht 5V> entsprechen sollte?
Wieso sollte den Timer irgendwelcghe Spannungspegel interessiere oder
diese einen Einfluss auf den ADC haben?
Das dürfte entweder ein Hardwarefehler oder ein Brainerror sein...
Rolf Magnus schrieb:> ... verstehe allerdings nicht, warum du fragst. Im Ursprungsposting tust> du das doch schon.
Ne das war Ich nicht! Hat glaube der Moderator verändert...
Aber trotzdem Danke für die Info
Rolf Magnus schrieb:> Die Anleitung lesen, die direkt über dem Fenster steht, in das du deinen> Text eingibst. Die steht ja nicht zum Spaß da...
Ist was dran...
STK500-Besitzer schrieb:> Wieso sollte den Timer irgendwelcghe Spannungspegel interessiere oder> diese einen Einfluss auf den ADC haben?> Das dürfte entweder ein Hardwarefehler oder ein Brainerror sein...
Also ist dat ganz normal das der einen Output-Pegel von bissle etwas
über 3V hat? Habe bisher angenommen, das richtet sich nach der an A(vcc)
angeschlossenen Spannung, die bei mir 5V entsprechen.
Oder kann mir jemand erkläre warum das gerade 3V sind. Habe dazu im
Datasheet irgendwie nichts gefunden.
Grüße Martin
Hi
>Oder kann mir jemand erkläre warum das gerade 3V sind. Habe dazu im>Datasheet irgendwie nichts gefunden.
Erzähle erst mal, wiedu das gemessen hast.
MfG Spess
Martin28 schrieb:> Oder kann mir jemand erkläre warum das gerade 3V sind. Habe dazu im> Datasheet irgendwie nichts gefunden.
Du hast da eine PWM an den Output-Pin gekoppelt! D.h. da ist eine
Wechselspannung drauf! Der SPannungshub am OC-Pin ist nach wie vor 5V,
aber dein Messgerät zeigt dir nur 3V an, weil die Spannung ständig 0V,
5V, 0V, 5V, 0V, 5V, etc.... macht.
spess53 schrieb:> Erzähle erst mal, wiedu das gemessen hast.
Also bin da mit nem differetial Tastkopf einmal auf Masse von meinem
Board und einmal auf dem PIN PB1 was ja dem OC1A Register entspricht.
Habe Timer.0 und Timer.1 im Betrieb und bei beiden wird 3V Peak
angezeigt. Da ganze wird natürlich über ein Oszi gemessen. Teiler etc.
sind alles auf 1x eingestellt. Also nicht das Ich da irgendeine division
drin habe oder ähnliches..
Karl Heinz Buchegger schrieb:> Du hast da eine PWM an den Output-Pin gekoppelt! D.h. da ist eine> Wechselspannung drauf! Der SPannungshub am OC-Pin ist nach wie vor 5V,> aber dein Messgerät zeigt dir nur 3V an, weil die Spannung ständig 0V,> 5V, 0V, 5V, 0V, 5V, etc.... macht.
Ja gut, aber das müsste mir das Oszi doch anzeigen!?