Hi, ich bekomm den ADC einfach nicht in den Free Running mode bzw. erhalte ich keine INterrupts mehr. Im Datenblatt hab ich nichts gefunden und in der Suche nru 1 das aber kein wirklicher Free Running Mode ist (Timer interrupt startet ADC). Ich verwende AVR Studio 4.18 mit WinAVR 20100110 Mein µC ist ein ATtiny 25 Ich möchte das der ADC dauernd läuft, nach jeder Wandlung möchte ich den ADC Wert auslesen und abhängig davon "etwas" tun. Mit meinem momentanen Programm wird der Interrupt nur 1 mal ausgeführt. Ist mit dem Interrupt was falsch oder mti dem Free Running Mode? Und was ist falsch.. MfG Tobais #include <avr/io.h> #include <stdint.h> #include <avr/interrupt.h> volatile uint16_t ADC_wert; ISR(ADC_vect) { ADC_wert = ADCW; } int main(void) { SREG |= (1<<7); //Global Interrupt enable DDRB &= ~(1<<PB3); //PB3 als Eingang DDRB |= ((1<<PB0) | (1<<PB1)); //PB0 & PB1 als Ausgang ADMUX |= ((1<<REFS2) | (1<<REFS1) | (1<<MUX1) | (1<<MUX0)); ADMUX &= ~((1<<REFS0) | (1<<ADLAR) | (1<<MUX3) | (1<<MUX2)); ADCSRA |= ((1<<ADEN) | (1<<ADATE) | (1<<ADIE)); ADC_wert = 0; ADCSRA |= (1<<ADSC); //Start des AD-Wandlers while(1) { //etwas tun } return 0; }
Das Bitgewurschtel ist zwar bissel undurchsichtig (wenn du ein Register initial beschreibst, lohnt sich |= bzw. &= ~ nicht wirklich, denn du kannst stattdessen das ganze Register auf einmal zuweisen), aber funktionieren sollte das. SREG |= (1<<7) heißt übrigens besser sei(). Steht in <avr/interrupt.h>, die du für die ISR sowieso einbinden musst.
Hi, danke für die Hinweise. Allerdings habe ich bei einem anderen Beitag den Tip bekommen es so zu machen mit den Registern. Bisher hab ich immer 0xYY geschrieben. Die <avr/interrupt.h> hab ich eingebunden und wenn ich sei() anstelle SREG |= (1<<7) schreibe bleibt mein Problem bestehen! MfG Tobias
Ich meine herausgefunden zu haben, dass es nicht an den Interrupts liegt sondern an dem Free Running Mode. Wenn ich es so schreibe ISR(ADC_vect) { ADC_wert = ADCW; ADCSRA |= (1<<ADSC); } funktioniert es. Allerdings würde es mich trotzdem interessieren warum es nicht geht mit dem Free Running Mode. MfG Tobias
Hi nimm das 1<<ADATE raus damit lässt du den ADC auf eine nicht eingestellte Trigger Quelle warten. dann sollte das laufen PS: das Löschen von Bits die im Reset zustand eh 0 sind kannst du dir sparen, löscht der Compiler eh. MfG Tec
Anfänger_Tobias schrieb: > Allerdings habe ich bei einem anderen Beitag den Tip bekommen es so zu > machen mit den Registern. Bisher hab ich immer 0xYY geschrieben. Das solltest du ja auch nicht tun. ;-) Einfacher wäre halt nur:
1 | DDRB = ((1<<PB0) | (1<<PB1)); // PB0 & PB1 als Ausgang, alles andere |
2 | // ist Eingang
|
3 | |
4 | // 2.56 V reference without external bypass,
|
5 | // ADC3 (aka. PB3) single-ended input
|
6 | ADMUX = ((1<<REFS2) | (1<<REFS1) | (1<<MUX1) | (1<<MUX0)); |
7 | // enable ADC in free-running mode with interrupts, prescaler 2
|
8 | ADCSRA = ((1<<ADEN) | (1<<ADATE) | (1<<ADIE)); |
> Die <avr/interrupt.h> hab ich eingebunden und wenn ich sei() anstelle > SREG |= (1<<7) schreibe bleibt mein Problem bestehen! Das war auch nicht zu erwarten, dass sich davon was ändert, davon wird lediglich das I-Bit zwei Takte schneller eingeschaltet, aber der Gesamteffekt bleibt natürlich der gleiche. Was mir beim Durchgucken der Registerbits noch aufgefallen ist ist, dass du den ADC mit einem Taktteiler von nur 1:2 betreibst. Das ist selbst bei 1 MHz CPU-Takt schon jenseits des empfohlenen Bereichs (aber tolerierbar, wenn du nur 8 Bit Genauigkeit haben willst), bei 8 MHz ist es aber jenseits von gut und böse. Ich würde zwar denken, dass der ADC trotzdem noch wandelt und Interrupts generieren sollte (also nicht etwa fest geht), halt nur Schrott wandelt. Trotzdem solltest du nochmal nachgucken, ob du nicht einen anderen Wert für den Prescaler brauchst.
Tec Nologic schrieb: > nimm das 1<<ADATE raus damit lässt du den ADC auf eine nicht > eingestellte Trigger Quelle warten. Das ist, mit Verlaub, Unsinn. Wenn man nichts an ADCSRB ändert, ist die voreingestellte Triggerquelle für den auto-trigger-Modus der free running mode. > PS: das Löschen von Bits die im Reset zustand eh 0 sind kannst du dir > sparen, löscht der Compiler eh. Nicht der Compiler, sondern der Controller, und zwar bei einem Hardware-Reset.
Hi, danke für den Tip mit dem Prescaler, ich hatte zuvor einen 128kHz Takt, deshalb hatte ich keinen Prescaler benötigt. Jetzt hab ich aber Default 8MHz mit Teiler 1/8 als 1MHz. Ich hab den Code soweit überarbeitet, allerdings funktioniert der free running Mode noch immer (im Debugger!) nicht. MfG Tobias Hier der überarbeitete Code: #include <avr/io.h> #include <stdint.h> #include <avr/interrupt.h> ISR(ADC_vect) { if(ADCW>0x00FF) ADC_wert = 0xFF; else ADC_wert = ADCW & 0x00FF; } ISR(TIM0_OVF_vect) { OCR0A = OCR0A_wert; } int main(void) { sei(); //Global Interrupt enable DDRB = (1<<PB0); //PB0 als Ausgang der PWM //ADC PB3, 2,56V, Autotrigger, Inerrupt Enable, f/16, ADMUX = ((1<<REFS2) | (1<<REFS1) | (1<<MUX1) | (1<<MUX0)); ADCSRA = ((1<<ADEN) | (1<<ADATE) | (1<<ADIE) | (1<<ADPS2)); ADCSRB = 0; //PWM PB0, non inverted PWM, fast PWM, Interrupt Enable, f, GTCCR = ((1<<TSM) | (1<<PSR0)); TCCR0A = ((1<<COM0A1) | (1<<WGM01) | (1<<WGM00)); TCCR0B = (1<<CS00); TIMSK = (1<<TOIE0); ADCSRA |= (1<<6); //Start des AD-Wandlers GTCCR &= ~(1<<TSM); //Start des Timers while(1) {//CODE } return 0; }
Der Code ist für den Beitrag gekürzt, die volatile uint8_t ADC_wert; volatile uint8_t OCR0A_wert; hab ich aus Versehen auch weg gekürzt. Im vollständigen Code sind sie enthalten!
Ich habe deinen Quellcode genommen, noch ein
1 | OCR0A_wert = ADC_wert / 2; |
in die ADC-ISR reingebaut (damit irgendwo auch was passiert), dann für einen ATtiny25 compiliert, aber in einen ATtiny85 geflasht. Hatte gerade nur einen '85 als DIP herumliegen, den man bequem in einen STK500 stöpseln kann. In dieser Richtung sind die Controller aber tatsächlich binärkompatibel. Dann habe ich 1,3 kHz Sinus an den ADC-Eingang gelegt. Oszillogramm liegt bei, ich denke, es ist klar, dass der free running mode ganz prima funktioniert. ;-)
Wow, Danke für die Mühe... Dann würde ich behaupten, dass der AVR Debugger das nicht kann, aber der µC schon... MfG Tobias
Anfänger_Tobias schrieb: > Dann würde ich behaupten, dass der AVR Debugger das nicht kann, aber der > µC schon... Debugger oder Simulator? Der Simulator sollte für den Digitalteil eigentlich brauchbar sein mittlerweile (so du den "V2"-Simulator im AVR Studio benutzt), dem würde ich nur bei den Analoggeschichten nicht übern Weg trauen. Das reine Abtasten des ADC ist aber komplett digital und sollte damit sogar im Simulator funktionieren, alles andere wäre ein Bug. Irgendwo in den Untiefen des AVR Studio müsste es aber eine Beschreibung geben, was im Simulator alles nicht ordentlich funktioniert, kannste ja mal suchen. (Ich habe hier kein Windows und damit auch kein AVR Studio, sorry.) Bitte schreib beim nächsten Mal aber dazu, dass du deine Erkenntnis nur aus einer Simulation gewonnen hast, das ist nicht unwichtig. Außerdem solltest du dir mal bitten ansehen, wie man C-Code im Forum.
Hi, ähm ok, ich mein natürlich Simulator und ich verwende nicht den Simulator2, werd ich aber dann jetzt mal ausprobieren. Das mit dem nicht unwichtig hab ich mir gedacht, deshalb habe ich geschrieben: "Ich hab den Code soweit überarbeitet, allerdings funktioniert der free running Mode noch immer (im Debugger!) nicht." Allerdings war da Debugger das falsche Wort, hätte Simulator heißen müssen. Ich denk mit dem letzten nicht ganz vollständigen Satz wolltest du sagen, dass ich die Formatierung verwenden soll?!
1 | #include formatierung
|
2 | int main (void) |
3 | {
|
4 | if(c-Code) |
5 | }
|
MfG Tobias
Anfänger_Tobias schrieb: > ähm ok, ich mein natürlich Simulator und ich verwende nicht den > Simulator2, werd ich aber dann jetzt mal ausprobieren. Hätte gar nicht gedacht, dass diese relativ neuen Teile überhaupt noch vom alten Simulator unterstützt werden. Ja, generell ist der V2-Simulator wohl ein 1:1-Abbild der Digital- logik, wie sie im AVR tatsächlich implementiert worden ist, d. h. der ist auf automatischem Weg aus der IC-Beschreibung abgeleitet. Damit sollte er taktzyklengenau den Digitalteil des ICs wider- spiegeln. > Allerdings war da Debugger das falsche Wort, hätte Simulator heißen > müssen. Ja, den Debugger kann man auch zusammen mit einem Emulator benutzen, um am "lebenden Objekt" zu debuggen. > Ich denk mit dem letzten nicht ganz vollständigen 'tschuldigung. > Satz wolltest du > sagen, dass ich die Formatierung verwenden soll?! Ja.
Verdammt, unwissenheit schützt echt nicht vor Strafe, hätte ich gleich das mti dem Simulator gesagt, hätte ich den SImulator 2 verwendet und das Problem wäre sofort gelöst gewesen.
1 | Simulator 2 kann den Free Running Mode!! |
Danke für den Hinweis!!! MfG Tobias
Anfänger_Tobias schrieb:
> Simulator 2 kann den Free Running Mode!!
Dann wär's ja jetzt Zeit für reale Hardware. ;-)
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.