Hallo,
um zu prüfen, ob ich die AD-Wandler-HW und die dazugehörigen Register richtig verstanden habe, habe ich den ATmega8 folgendermassen beschaltet.
AVcc = AVref = Vcc
PC0, PC1, PC2, PC3 jeweils ein Poti (22kOhm, 0-5V)
Die Wandlungswerte sollen als Zeitvorgabe für zwei PWM-Signale benutzt werden, weil man die (je nach Zeitbasis) gut mit einer LED oder dem Oszi beobachten kann.
ADC0 = high für PortB0
ADC1 = low für PortB0
ADC2 = high für PortB1
ADC3 = low für PortB1
Ergebnis: Die Wandlungsergebnisse sind richtig. Die Kanäle sind aber um eine Position verschoben.
ADC3 = high für PortB0
ADC0 = low für PortB0
ADC1 = high für PortB1
ADC2 = low für PortB1
Wo liegt mein Denkfehler? Was für einen Bock habe ich geschossen?
Danke im Voraus
Schak
um zu prüfen, ob ich die AD-Wandler-HW und die dazugehörigen Register richtig verstanden habe, habe ich den ATmega8 folgendermassen beschaltet.
AVcc = AVref = Vcc
PC0, PC1, PC2, PC3 jeweils ein Poti (22kOhm, 0-5V)
Die Wandlungswerte sollen als Zeitvorgabe für zwei PWM-Signale benutzt werden, weil man die (je nach Zeitbasis) gut mit einer LED oder dem Oszi beobachten kann.
ADC0 = high für PortB0
ADC1 = low für PortB0
ADC2 = high für PortB1
ADC3 = low für PortB1
Code:
On ADC OnAdc 'ADC-Interrupt-Routine festlegen
'
'--[Variablen]---------------------------------------------
Dim AdChannel as Byte
'AD-Wandlerwerte
Dim highPortB0 as Integer
Dim highPortB1 as Integer
Dim lowPortB0 as Integer
Dim lowPortB1 as Integer
'
Dim hiPortB0Zaehler as Integer
Dim hiPortB1Zaehler as Integer
Dim PortB0Zaehler as integer
Dim PortB1Zaehler as Integer
'
'----------------------------------------------------------
'Initialisierung
'----------------------------------------------------------
PORTB = &B00000011
DDRB = &B00000011
'
'Bits7+6=01: Aref ist intern verbunden
'Bit5=1: LeftAdjust, nur 8 Bit in ADCH
'Bits3..0=0000: Pin ADC0 wählen
ADMUX = &B01100000
AdChannel = 0
'Bit7=1:AdcAn
'Bit6=1:Start
'Bit5=1:Freilaufend
'Bit3=1:InterruptAn
'Bits2..0=111: AdcClock=AvrClock/128
ADCSRA = &B11101111
ADCSRA = &B11101111
'
'Globale Interrupt-Freigabe
SREG.7 = 1
'----------------------------------------------------------
'Hauptprogramm
Do
IF PortB0Zaehler <= 0 THEN
PortB0Zaehler = lowPortB0 + highPortB0 'Taktlaenge
hiPortB0Zaehler = highPortB0 'high-Zeit
PortB = PortB OR &B00000001 'PortB0 = high
ELSE
decr PORTB0ZAEHLER
IF hiPortB0Zaehler <= 0 THEN 'high-Zeit vorbei
PortB = PortB AND &B11111110 'PortB0 = low
ELSE
decr hiPORTB0ZAEHLER
ENDIF 'Ende: high-Zeit
ENDIF 'Ende: Taktlaenge
Loop 'Ende: Hauptschleife
'--[Interrupt]---------------------------------------------
OnAdc: 'ADC-Interrupt-Routine
'Kanal-Weiterschaltung
ON AdChannel GOTO ADCHANNEL0 , ADCHANNEL1 , ADCHANNEL2 , ADCHANNEL3
ADCHANNEL0:
highPortB0 = ADCH
AdChannel = 1
GOTO END_OnAdc
ADCHANNEL1:
lowPortB0 = ADCH
AdChannel = 2
GOTO END_OnAdc
ADCHANNEL2:
highPortB1 = ADCH
AdChannel = 3
GOTO END_OnAdc
ADCHANNEL3:
lowPortB1 = ADCH
AdChannel = 0
GOTO END_OnAdc
END_OnAdc:
ADMUX = &B01100000 OR AdChannel
Return
Ergebnis: Die Wandlungsergebnisse sind richtig. Die Kanäle sind aber um eine Position verschoben.
ADC3 = high für PortB0
ADC0 = low für PortB0
ADC1 = high für PortB1
ADC2 = low für PortB1
Wo liegt mein Denkfehler? Was für einen Bock habe ich geschossen?
Danke im Voraus
Schak