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
// 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.
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!
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. ;-)
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?!
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.