Und wo liegt das Problem?
Mach einen freilauf ADC, und werte in der Interruptroutine die Werte aus. Bei Bedarf kann ich Dir ein Codeschnipsel schicken,
Gruß Sebastian
hallo, am adc-0 (avr16) wird durch ein rad-encoder immer ein wert zwischen 60 und 240 ausgegeben. beim wert unter 100 soll die variable hochgezählt werden und bei einem wert über 200 soll die variable hochgezählt werden.
kann keine lösung über interrupt finden.
mfg pebisoft
Und wo liegt das Problem?
Mach einen freilauf ADC, und werte in der Interruptroutine die Werte aus. Bei Bedarf kann ich Dir ein Codeschnipsel schicken,
Gruß Sebastian
was ist ein freilauf-adc . komme mit dieser adc-auswertung im interrupt nicht klar.
mfg pebisoft
Ganz einfach :
Freilauf ADC -> der wert wird ständig ausgelesen
Ich weiß zwar nicht in welcher Sprache Du progst, aber ich mach es so in Assembler:
Der ADFR bit schaltet Free Run modus ein.Code:ldi tmp,(1<< ADEN) | (1<<ADFR) | (1<<ADIE) | (1<<ADSC) | (1<<ADPS0) | (1<<ADPS1) | (1<<ADPS2) out ADCSRA,tmp ldi tmp,(1<<REFS0) | (1<<ADLAR) | (1<<MUX0) out ADMUX,tmp
Du mußt Dir auch noch den passenden Interruptvektor einrichten
Code:.org ADCCaddr rjmp ADCcomplete ; ADC Interrupt Vector Address
Jetzt Springt er nachdem er jedesmal fertig ist mit ADC nach ADCcomplete
in ADCcomplete routine:
Es wird zwar der LOW Byte überschrieben, das macht aber nichts weil der wert linksgerichtet ist (sehe ADLAR Bit in ADMUX) und die zwei unteren bits kann man ruhig hier weglassen.Code:in tmp,ADCL in tmp,ADCH
Jetzt prüfst Du den Wert in tmp nach Deinen >100 oder <200 und änderst den Zähler entsprechend.
Zum schluß reti und fertig.
Hoffe, daß es verständlich war, wenn Du C benutzt wird es wohl auch kein Problem sein die Assembler schnipsel zu verstehen.
Gruß Sebastian
ich progge in winavr-c.
mfg pebisoft
Dann ist das wohl kein Problem das von mir geschriebene umzusetzen.ich progge in winavr-c.
mach doch etwa so :
Der InterrupthandlerCode:ADCSRA=(1<< ADEN) | (1<<ADFR) | (1<<ADIE) | (1<<ADSC) | (1<<ADPS0) | (1<<ADPS1) | (1<<ADPS2); ADMUX = (1<<REFS0) | (1<<MUX0);
Dein Zähler muß Du nur volatile Deklarieren, damit er im Interrupt auch zugänglich ist.Code:SIGNAL (SIG_ADC) { int result; result = ADCL + (ADCH << 8); if (result < 100){ zaehler++; } else if (result > 200) { zaehler--; } }
Naja und sonstige headers nicht vergessen (signal.h interrupt.h)
Ich hoffe, daß es Dir weiterhilft
Gruß Sebastian
sag mal : 1<<ADFR kennt er nicht, gibt es für ADFR noch einen anderen ausdruck.
"adc_lcd.c:44: error: `ADFR' undeclared (first use in this function)"
mfg pebisoft
Ein Auszug aus meiner iom16.h :
Der ADFR ist dabei Bit Nr. 5 also muß es heissen (1<<ADATE) und nicht (1<<ADFR)#define ADCSRA _SFR_IO8(0x06)
#define ADPS0 0
#define ADPS1 1
#define ADPS2 2
#define ADIE 3
#define ADIF 4
#define ADATE 5
#define ADSC 6
#define ADEN 7
Komisch, warum das so ist weiß ich nicht, ich dachte, daß wäre 1:1 von den Bits des AVR´s
übernommen.
Ist es ein Bug, oder warum haben sie den Namen geändert ?
Na ja versuch es mit ADATE
Gruß Sebastian
EDIT:
Ups, stimmt alles nicht so ganz, also :
es gibt wirklich kein ADFR bei MEGA 16 sondern ADATE:
also ADATE doch einschaltenBit5 - ADATE: ADC Auto Trigger Enable
When this bit is writen to one Auto Triggering of the ADC is enabled.
Und wann er dann Triggerd bestimmt der Register SFIOR
Für Free Running mode sieht es dann so aus
SFIOR &= ~(1<<ADTS0) | (1<<ADTS1) | (1<<ADTS2);
Sehe auch Dattenblatt Seite 215.
Damit hast Du den Free Running eingeschaltet.
Ich habe es mit Dattenblatt von Mega 8 verglichen, wußte nicht, daß sie das bei Mega 16
sooooo verändert haben![]()
hallo, funktioniert klasse, vielen dank für deine schnelle hilfe.
mfg pebisoft
ps:
Und wann er dann Triggerd bestimmt der Register SFIOR
Für Free Running mode sieht es dann so aus
SFIOR &= ~(1<<ADTS0) | (1<<ADTS1) | (1<<ADTS2);
was ist das.
habe es nicht eingesetzt, es läuft trotzdem automatisch mit dem interrupt.
Freut mich.
Gruß Sebastian
Lesezeichen