Hi! Ich versuche, einen Ultraschallsensor über den Analog-Comparator des ATmega8535 auszuwerten. D.h., wenn er etwas empfängt, soll der AC in der entsprechenden Frequenz (40 kHz) Interrupts auslösen. Ich habe den negativen Eingang auf Masse gelegt, den positiven Eingang mit dem Sensor, und dann auch mal mit einem Funktionsgenerator, verbunden. Da müßte er doch bei der geringsten Gelegenheit zucken, oder?! Es wird aber kein Interrupt ausgelöst. Was mache ich falsch? Bisher: PortB als Input, Pull-ups ausgeschaltet (laut Atmel-Doku, an PortB liegen die Eingänge des AC: AIN0 und AIN1) AC mit IRQ enabled und IRQ bei toggle gestartet globale IRQ enabled, Endlosschleife in der Routine (SIG_COMPARATOR) soll später ein Zähler inkrementiert werden Passiert aber nix... bitte helft mir. Habe ich einen Denkfehler? QUELLTEXT: #include <avr/io.h> #include <avr/interrupt.h> #include <avr/signal.h> #define START_AC 0xAB /* 10001011 (ACSR)*/ /* INTERRUPTHANDLER Analog Comparator */ SIGNAL(SIG_COMPARATOR) { sbi(PORTA,PA0); /* LED anschalten */ } void main(void) { outp(0xFF,DDRA); /* Port A as output */ cbi(PORTA,PA0); /* eine LED ausschalten, die beim Ausführen des IRQ Handlers angeschaltet wird */ outp(0x00,DDRB); /* Port B as input */ outp(0x00,PORTB);/* switch internal pull-up's off*/ /* Comparator starten */ outp(START_AC,ACSR); /* globaler Interrupt enable */ sei(); /* neverending loop */ for(;;); }
du solltest den -Eingang nicht auf Masse legen, sondern eine kleine Mindestspannung anlegen.
Ja, will ich später, wenn ich den Wert genauer kenne (wird was zwischen 100..300 mV werden) auch tun. Aber meinst Du, das es daran liegt? Theoretisch ist doch einfach jede Spannung größer Masse, also müßte er doch wenigstens irgendwann mal auslösen...
...habe es aber probiert. 100mV an den negativen Eingang. Das Signal am positiven gibt über den Sensor 0.2 Vrms (schwingt). Müßte also passen.... Tuts aber immer noch nicht. ???
...habs gefunden, die zur Kenntnisnahme: Es ist extrem wichtig, in welcher Reihenfolge das Register des AC beschrieben wird: /*Interrupt disablen*/ outp((0<<ACIE),ACSR); /* Comparator ausschalten*/ outp((1<<ACD),ACSR); /* modus setzen (rising edge) */ outp((1<<ACIS0),ACSR); outp((1<<ACIS1),ACSR); /* ACI clearen (optional) */ outp((0<<ACI),ACSR); /* AC anschalten */ outp((0<<ACD),ACSR); /* JETZT ERST Interrupt enablen */ outp((1<<ACIE),ACSR); Das in der Mitte kann natürlich auch in einem Rutsch passieren. ...und dann klappts ooch mit'm nachbarn :-) mz
Ich nehme an, du willst mit outp((0<<ACD),ACSR) das einzelne bit ACD löschen. Tatsächlich werden aber alle gelöscht! Es wird immer ein komplettes Byte geschrieben. 0<<ACD ist übrigens das gleiche wie 0 (die Null wird um ACD Stellen nach links verschoben und ist immer noch Null). Du kannst alle Bits sofort in einem Rutsch so setzen wie du willst: outp((1<<ACIS0)+1<<ACIS1)+(1<<ACIE),ACSR) (ist zumindest in asm so; wird in C wahrscheinlich nicht viel anders sein)
Jau!! Jürgen rulez! Jetzt erhebt sich die Frage, warum überhaupt was ging...?! Naja, das gucke ich morgen.. Danke nochma.... mz
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.