Hallo! Aufbauend auf einer AVR-Entwicklungsplatine, habe ich mal versucht einen Teil des UART- Tutorials auf dieser Seite so zu verändern, dass der Widerstand (bzw. die Spannung) eines zwischen AVCC und PC3 geschalteten Fotowiderstandes ausgemessen und der Messwert per UART an den Computer gesendet wird. In den Registerdefinitionen im assembler-code habe ich mich im wesentlichen an das Atmega8-Datenblatt gehalten. Jedoch habe ich aus dem Datenblatt noch nicht verstanden, wie MUX eingestellt werden muss (bzw. wie man den zu messenden PC - Pin auswählt). Ich denke das ist der Grund, dass über die serielle Schnittstelle kein Messwert, sondern nur "Quadrat-Quadrat-A" ankommt. Was muss ich an diesem Code verändern bzw. ergänzen, um ihn zum laufen zu bekommen? mit freundlichen G´üßen, Andy p.s.: Ich habe im Netz keine Adresse mit grundlegenden ADC-tutorials gefunden, die sich sowohl auf die Hardware(anschluss von sensoren) als auch auf die software beziehen. Daher bin ich über jeden Hinweis in dieser Richtung dankbar!
Hallo Du hast fälschlicherweise nicht die Source-Datei angehängt, sondern das Projektfile. Bringe noch den Source, sonst können wir dir wenig helfen ;-) Vermutung für dein Problem: Du misst mit dem ADC die Spannung. Dann erhälst du ja einen Wert, den du z.B. in nem Register speicherst. Nun nimmst du diesen Wert und schreibst ihn direkt ins Datenregister des UART. Dieser Wert wird an der Schnittstelle des PC empfangen, und zwar wieder als Zahl. Dein Terminalprogramm nimmt nun die ASCII-Tabelle hervor, guckt sich an, welches Zeichen denn mit dieser Zahl codiert ist und zeigt dieses Zeichen an. Kommt eine 65 herein, dann siehst du ein A. Kommt eine Zahl herein, zu der kein ASCII-Zeichen passt, dann siehst du ein Viereck. Ich denke, du verstehst, in welche Richtung ich denke? Gruss Michael
Hi Mr chip! So weit (ASCII-code) hatte ich noch garnicht gedacht! Klingt plausibel, aber ich befürchte bei meinem programm liegt der Fehler ehwer etwas trivialer, da ich in assembler noch ganz neu bin (Phase: lesen und lernen..) .include "m8def.inc" .def temp = r16 .equ CLOCK = 4000000 .equ BAUD = 9600 .equ UBRRVAL = CLOCK/(BAUD*16)-1 ; Stackpointer initialisieren ldi temp, LOW(RAMEND) out SPL, temp ldi temp, HIGH(RAMEND) out SPH, temp ; Baudrate einstellen ldi temp, LOW(UBRRVAL) out UBRRL, temp ldi temp, HIGH(UBRRVAL) out UBRRH, temp ; Frame-Format: 8 Bit ldi temp, (1<<URSEL)|(3<<UCSZ0) out UCSRC, temp sbi UCSRB,TXEN ; TX aktivieren ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; PORTC als Eingang definieren ldi r16,0x00 out DDRC, r16 ; ADC einschalten (set ADC enable bit) sbi ADCSRA, ADEN ; select Free Running Mode sbi ADCSRA, ADFR ; start first conversion sbi ADCSRA, ADSC ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; loop: in r24,ADCL in r25,ADCH ldi temp, ADCL rcall serout ldi temp, ADCH rcall serout ldi temp, 'A' rcall serout ldi temp, 10 rcall serout ldi temp, 13 rcall serout rjmp loop serout: sbis UCSRA,UDRE ; Warten bis UDR für das nächste ; Byte bereit ist rjmp serout out UDR, temp ret ; zurück zum Hauptprogramm
> ldi temp, ADCL
Das geht nicht! ADCL ist ein Register. ldi braucht aber einen
konstanten Wert. Da müsste der Assembler eigentlich schon ne
Fehlermeldung ausspucken!
...Wo wartest Du eigentlich darauf, dass der ADC mit der Wandlung fertig ist? Hab jetzt auf Anhieb nix gefunden... Du solltest vielleicht das ADIF oder ADBSY mal abfragen. > dass der Widerstand (bzw. die Spannung) eines > zwischen AVCC und PC3 geschalteten Fotowiderstandes > ausgemessen... BTW: wie ist eigentlich der Widerstand angeschlossen? Mir kommt das ein bisschen komisch vor...
Also, bei genauerer Betrachtung fehlt da ne ganze Menge. Beim ADC muss auf jeden Fall der Prescaler korrekt eingestellt werden. Das sehe ich im Programm oben nicht. Außerdem willst Du ja anscheinend an PC3 messen. Dazu musst Du aber auch im Register ADMUX den Kanal 3 auswählen. Dann wie gesagt die Warteschleife für den ADC. Und dann natürlich das, was mr.chip schon vermutet hat: Wenn Du den blanken Binärwert, den der ADC (bei korrekter Konfiguration) ausspuckt, per UART an einen PC schickst und über ein Terminal-Programm anzeigen lässt, werden natürlich die entsprechenden ASCII-Zeichen angezeigt und nie und nimmer der Wert. Du erhältst normalerweise Werte zwischen 0 und 1023 (dezimal). Das heißt Du musst diese Werte zunächst in (vier) ASCII-Stellen umwandeln. Dann kann Dein Terminal-Programm die auch korrekt anzeigen...
> liegt der Fehler ehwer etwas trivialer
Auch. Fakt ist allerdings auch, dass du Zahlen
nicht so einfach an ein Terminal übertragen kannst.
Du brauchst eine Routine, die dir eine Zahl in einen
String umwandelt.
Wenn dein Register den Zahlenwert 189 enthält, dann müssen
auf der Schnittstelle die Zeichen '1', '8' und '9'
übertragen werden.
Wenn ich du wäre, würde ich mal damit anfangen so eine
Routine zu schreiben.
Zum testen würde ich auch mal komplett auf den ADC verzichten,
ein Register mit einem Zahlenwert laden und nachsehen, ob
das Terminal die richtige Zeichenfolge dafür erhält. Der Grund
warum ich damit anfangen würde ist ganz einfach: Die Routine
brauchst du zum Testen der restlichen Programmbestandteile (in
deinem Fall ADC) wie ein Stückchen Brot. Woher willst du
wissen was dein ADC macht, wenn du dir nicht mal seine
Ergebnisse anschauen kannst.
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.