PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : AVR ADC spuckt immer den gleichen Wert aus



scales
25.08.2007, 04:00
Ich will mit nem Mega32 ne Spannung zwischen 0V und 2,5V messen, dafür hab ich am ADC-Referenzpin (AREF) 2,5V angelegt und zum testen an Port C Pin 7 eine Spannung von 1,2V.
(hab auch alles nochmal nachgemessen)

Allerdings spuckt der ADC immer nur den gleichen Wert aus: 1284
Und der ist sogar ausserhalb des eigentlich möglichen bereichs (0 - 1023).

durch senden eines beliebigen zeichens per rs232 spuckt der avr die werte über die selbige schnittstelle aus, das hab ich mit dummy-werten ausprobiert, daran kann es also nicht hängen.

Ich lass den ADC im Free Running Modus mit Interrupt laufen, der Interrupt wird ordnungsgemäß aufgerufen.
Das komische ist allerdings, egal ob ich den ADC überhaupt einschalte oder nicht, in ADCH/ADCL steht immer 1284.

Hier ist der Code:

.include "m32def.inc"

; Defines
.def temp = r16
.def adc_low = r17
.def adc_high = r18
.def adc_buffer = r19
;ZL = r30
;ZH = r31

; Interrupt Vektor Tabelle
.org 0x000
rjmp reset
nop
reti
nop
reti
nop
reti
nop
reti
nop
reti
nop
reti
nop
reti
nop
reti
nop
reti
nop
reti
nop
reti
nop
reti
nop
rjmp USART_rx
nop
reti
nop
rjmp USART_tx
nop
rjmp ADC_ready
nop
reti
nop
reti
nop
reti
nop
reti
nop

reset:

; Stack initialisieren
ldi temp, LOW(RAMEND)
out SPL, temp
ldi temp, HIGH(RAMEND)
out SPH, temp

; USART initialisieren

; 9600 Baud
ldi temp, 0
out UBRRH, temp
ldi temp, 71
out UBRRL, temp

; 8 bit
ldi temp, (1<<URSEL)|(3<<UCSZ0)
out UCSRC, temp

; TX und RX Interrupts
sbi UCSRB, TXCIE
sbi UCSRB, RXCIE

; TX und RX
sbi UCSRB, TXEN
sbi UCSRB, RXEN

; I/O-Ports konfigurieren
ldi temp, 0b11111111
out DDRC, temp
ldi temp, 0b00000000
out PORTC, temp

; ADC initialisieren
ldi temp, (1<<MUX2) | (1<<MUX1) | (1<<MUX0)
out ADMUX, temp
ldi temp, (1<<ADEN) | (1<<ADATE) | (1<<ADIE)| (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0)
out ADCSRA, temp

; Interrupts aktivieren
sei

sbi ADCSRA, ADSC

; Endlosschleife
schleife:
rjmp schleife

; ADC Messung fertig
ADC_ready:
push temp
in temp, SREG
push temp

ldi adc_low, ADCL
ldi adc_high, ADCH

pop temp
out SREG, temp
pop temp
reti

; Byte empfangen
USART_rx:
push temp
in temp, SREG
push temp

ldi ZL, LOW(_goon1)
ldi ZH, HIGH(_goon1)
in temp, UDR
mov temp, adc_low
mov adc_buffer, adc_high
out UDR, temp

pop temp
out SREG, temp
pop temp
reti

_goon1:
push temp
in temp, SREG
push temp

ldi ZL, LOW(_goon2)
ldi ZH, HIGH(_goon2)
out UDR, adc_buffer

pop temp
out SREG, temp
pop temp
reti

_goon2:
reti

; Byte gesendet
USART_tx:
ijmp

ich kann mir da keinen reim mehr drauf machen, hab auch schon mehrere Mega32 durchprobiert, alle liefern 1284.[/code]

radbruch
25.08.2007, 09:52
Hallo


; I/O-Ports konfigurieren
ldi temp, 0b11111111
out DDRC, temp
ldi temp, 0b00000000
out PORTC, temp

Der Pin muss ein Eingang sein.

Gruß

mic

izaseba
25.08.2007, 11:59
ldi adc_low, ADCL
ldi adc_high, ADCH

Hehe, das ist lustig, in m32def.inc sind ADCL u. ADCH so definiert:


ADCL = 0x04
ADCH = 0x05

und 0x0504 ergibt 1284 ändere ldi in in ...
Außerdem bist Du Dir sicher, daß Du die interne 2,56 mit

ldi temp, (1<<MUX2) | (1<<MUX1) | (1<<MUX0)
out ADMUX, temp
einstellst ?
Muß da nicht noch REFS0 oder REFS1 mit rein?
Schau nochmal in Dattenblatt rein, ich weiß es nicht mehr genau.

Gruß Sebastian

radbruch
25.08.2007, 12:08
Hallo

Das war mir ja klar, dass ich falsch lag. Assembler sollte man können, oder wenigstens im Datenblatt die Beschreibung der Instruktionen anschauen. Sorry.


dafür hab ich am ADC-Referenzpin (AREF) 2,5V angelegt
Er will eine externe Referenz verwenden, also müste das ADMUX richtig sein.

Gruß

mic

izaseba
25.08.2007, 12:17
Ne, Radbruch, das war schon richtig, was Du geschrieben hast, ich habe es nur nicht widerholt, wozu auch ;-)
Also Pins als Eingang, ldi weg, in dafür rein und ADMUX in ruhe lassen...
Ich habe zu schnell gelesen, dachte nur, er will die interne Referenz nutzen :-$

Gruß Sebastian

P.S. Wer C versteht, der versteht auch Assembler ...

scales
25.08.2007, 13:47
ach verdammt, ganze nacht verschwendet wegen so nem mist,
wenn ich IN statt LDI benutzt funzt alles.

aber Port C auf Eingang stellen macht keinen Sinn, der ADC ist an Port A und standardmäßig auf Eingang.

radbruch
25.08.2007, 15:03
Hallo


aber Port C auf Eingang stellen macht keinen Sinn
Das war natürlich Quatsch, der ATMega8 hat seine ADC0-4 auf Port C, klassische Verwirrung meinerseits.

Gruß

mic