Hallo zusammen, ich hoffe ihr könnt mir helfen. Ich habe ein Problem mit der AD-Wandlung. Zunächst einmal: Ich nutze ein Atmega32 mit einem Quarz von 11MHz. An den Port Pin PA0 (ADC0) habe ich über einen Spannungsteiler eine Spannung von 1,8V angelegt. An AVCC liegt über LC-Kombination 5V, ebenfalls an AREF angelegt. Nun zu den Einstellungen der Register. Die Register, so denke ich jedenfalls, habe ich richtig eingestellt. In ADMUX den Analogkanal ADCO ausgewählt, die Spannungsreferenz auf AVCC gestellt. Außerdem ADLAR auf eins gesetzt, da mich die unteren Bits der ADW zunächst nicht interessieren. Desweiteren den ADW im ADCSRA enabled, den Vorteiler auf 128 eingestellt. Somit 11,059MHz/128=86,4kHz für ADW (sollte ja zwischen 50kHz und 200kHz). Und Auto Trigger disable. (Eigentlich will ich den ADW im free running mode betreiben. Müsste dann ADATE=1 und SFIOR=000xxxxx sein.) In einer Endlosschleife starte ich die AD-Wandlung warte auf das Ergebnis und gebe schließlich ADCH auf dem PORTC aus. (JTAG habe ich deaktiviert (AVR-Studio). Da sonst die JTAG-Pins auf 5V gelegt werden wegen Pull-up Widerstand.). Am PortC sollt nun der AD-Wert anliegen. Klar dieser Wert wird immer wieder überschrieben und das Ergebnis der AD-Wandlung könnte ein wenig variieren. Doch die Tendenz des AD-Wertes sollte doch stimmen. Doch dies ist leider überhaupt nicht der Fall. Am PortC liegt der Wert 0000|0101 an. AD-Wert somit mind. 10100 (101 + die beiden niederwertigsten Bits). Ergibt ein AD-Wert =20. Müsste aber doch 1,8*1024/5=368 sein. Was mache ich falsch in meinem Quelltext. Und gibt es noch etwas beim Free Running Mode zu beachten? .include "m32def.inc" .org 0x000 rjmp main ; Reset main: .def temp = r16 ldi temp, low(RAMEND) ;Startadresse Stack out SPL, temp ldi temp, high(RAMEND) out SPH, temp ldi temp, 0x00 out DDRA, temp ;PORTA (ADC Port) als Eingang ldi temp, 0xFF out DDRC, temp ;PortC als Ausgang out DDRB, temp ;PortB als Ausgang clr temp out PORTC, temp ;PORTC zurücksetzen out PORTB, temp ;Led an ; ADC Multiplexer Selection Register ADMUX ; REFS1 REFS0 ADLAR MUX4 MUX3 MUX2 MUX1 MUX0 ldi temp, 0b01100000 ; REFS1=0 REFS0=1 AVCC with external ; capacitor at AREF pin out ADMUX, temp ; ADLAR=1 ADC conversion result in the ADC ; Data Register is left adjusted ; MUX4 - MUX0: Analog Channel and Gain Selection Bits ; MUX4 - MUX0: 00000 Single Ended Input ADC0 ; ADC Control and Status Register A ADCSRA ; ADEN ADSC ADATE ADIF ADIE ADPS2 ADPS1 ADPS0 ldi temp, 0b11000111 ; ADEN=1 ADC Enable out ADCSRA, temp ; ADSC=1 Start Conversion ; ADATE ADC Auto Trigger Disable ; ADPS2 - ADPS0 ADC Prescaler Select Bits ; ADPS2 - ADPS0=111 division factor=128 ; 11,059MHz/128=86,4kHz ende: sbi ADCSRA, ADSC ; den ADC starten wait_adc: sbic ADCSRA, ADSC ; wenn der ADSC=0, d.h. Umwandlung beendet, ; wird der nächste Befehl übersprungen rjmp wait_adc ldi r16, ADCH out PORTC, r16 jmp ende
Hi > ldi r16, ADCH > out PORTC, r16 mit der ersten Zeile lädst du r16 mit der Adresse von ADCH ($05), nicht mit dem Inhalt. Richtig: in r16,ADCH MfG Spess
Okak, thx a lot. Nun aber nochmal eine Frage. In wie weit unterscheiden sich ldi und in? Muss ich immer den "in" Befehl nutzen, wenn ich ein Registerwert nutzen möchte? So z.B. in temp, SFIOR andi temp, 0b00011111 out SFIOR, temp anstatt ldi temp, SFIOR andi temp, 0b00011111 out SFIOR, temp Vielen Dank casio
casio wrote: > Okak, thx a lot. > Nun aber nochmal eine Frage. In wie weit unterscheiden sich ldi und in? > ? Das solltest du als Assemblerprogrammierer aber schon wissen. ldi = load immediate ldi rxx, yy lädt das Register rxx mit dem direkt angegebenen Wert yy. Daher auch das immediate, weil der zu ladende Wert direkt angegeben wird. in = in in rxx, yy Holt vom Port yy den momentan anliegenden Wert und speichert ihn im Register rxx
LDI lädt ein Register mit einer Konstanten IN lädt ein Register mit dem Inhalt eines I/O-Registers LDS lädt ein Register mit dem Inhalt einer SRAM-Zelle LPM lädt ein Register mit dem Inhalt einer Flash-Zelle über Z-Pointer MOV lädt ein Register mit dem Inhalt eines anderen Registers LD lädt ein Register mit dem Inhalt einer SRAM-Zelle über Pointer LDD lädt ein Register mit dem Inhalt einer SRAM-Zelle über Pointer mit Offset Mehr fällt mir auf die Schnelle nicht ein. Aber bei ATMEL gibt es ein PDF dazu (AVR-Instruction_Set) und im Datenblatt sind auch alle Befehle aufgelistet. ...
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.