hallo, ich habe ein problem mit dem analog digitalwandler meines atmega16. das programm lässt sich einwandfrei compilieren. doch wenn ich den debugger starte, wird der wert umgewandelt, der interrupt gestartet, und wenn er dann in das unterprogramm zurückkehrt, bleibt er in der while schleife stecken, die zum warten bis zum abschluss der wandlung gedacht war. kann mir jemand damit helfen? andabei mein programm: der interrupt muss nicht unbedingt verwendet werden, doch ich hab ihn aus experimentellen gründen aktiviert. #include <avr/io.h> #include <avr/interrupt.h> void main() { volatile int messung; DDRB=0xff; PORTB=0x00; ADMUX=0x20; ADCSRA=0x00; sei(); //Interrupts aktivieren while (1) { messung=ADW(); } } ISR (ADC_vect) { ADCSRA=0x00; } void ADW() { int messung; ADCSRA =0xC8; while(ADSC) //hier steckt der fehler {} messung=ADCH; return messung; } danke für die hilfe
Wolfgang Graf wrote: > while(ADSC) //hier steckt der fehler > {} Gut erkannt! ADSC ist eine Bitnummer, die in einer Headerdatei definiert ist. Und die Nummer ist ungleich Null und dementsprechend immer wahr. Die (leere) Schleife wird also bis zum Sankt Nimmerleinstag ausgeführt... Schau mal im AVR-GCC-Tutorial nach, wie das mit den Bitzugriffen läuft (kleiner Tip: Es hat was mit Schiebeoperatoren zu tun)...
Ist nicht die ISR dafür da zu signalisieren das die Messung beendet ist. Worauf wartest du in der while-Schleife.
Übrigens: Wenn Du am Ende von ADW() einfach
1 | return ADCH; |
schreibst, kannst Du Dir die funktionslokale Variable messung sparen...
>> while(ADSC) //hier steckt der fehler
ADSC ist nur die Bitnummer dieses Bits. Das kannst du
so nicht direkt lesen. Das while(ADSC) endet also nie
weil ADSC ein Wert größer Null ist.
Du musst das Register lesen in dem ADSC steht
und entsprechend verknüpfen:
while(ADCSRA & (1<<ADSC))
So würde ich das Programm nicht strukturieren. Busywait vertrödelt doch nur unnötig Rechenleistung. Dazu gibt es doch Alternativen. Der ADC kann einen Interrupt auslösen wenn er fertig ist. Der ADC kann im Free-Run-Mode vor sich hin werkeln, im Timer-Interrupt fragt (oder hieß das frägt ?) man mal so nebenbei sein letztes Ergebnis ab, sichert es und schaltet bei Bedarf den Eingangsmultiplexer um. Das sind alles Methoden, bei denen der AVR nicht im Busywait hängt und derweil andere Dinge erledigen kann. Gruß aus dem Karvendel, HerBert
Herbert vom Karvenzmann wrote: > So würde ich das Programm nicht strukturieren. Busywait vertrödelt doch > nur unnötig Rechenleistung. Dazu gibt es doch Alternativen. Ich glaube nicht, dass ein Anfänger in seinem ersten Testprogramm irgendeinen Wert auf seine Rechenleistung legt. Warum muss immer alles gleich optimiert werden? Lasst ihn doch erst mal überhaupt was aus seinem ADC rausbekommen. Wenn er das Tutorial durcharbeitet, kommt er früher oder später selbst darauf...
Und ich würde der Funktion einen Datentyp geben, nicht void, bei void kannste keine Werte zurückgeben
Martin wrote: > Und ich würde der Funktion einen Datentyp geben, nicht void, bei void > kannste keine Werte zurückgeben Das stimmt allerdings...
danke für die vielen meldungen, das ganze hat mich schon ein stück weiter gebracht! mfg @ johnny m du hattest recht, das mit der bitnummer war der fehler, ich war es nur so gewohnt, weil man bei einem 8051 controller so eine bitnummer direkt (so wie ich es obend versucht habe) abfragen kann.
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.