PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : verschiedene ADC Kanäle im free run lesen



malthy
16.02.2011, 22:56
Hallo,

Ich finde gerade nicht die entscheidende Info um mehrere ADC Kanäle im free run Modus auslesen zu können. Ich starte den ADC erstmal mit

Config Adc = Free , Prescaler = 128 , Reference = Internal_2.56

Damit sollte der ADC loslaufen. Soweit ich verstanden habe, stehen dann in ADCL und ADCH Low- bzw. Highbyte der laufenden Wandlung. Aber wie kann ich nun gezielt einen bestimmten Kanal in diese Register bekommen? Bisher habe ich nur in Erfahrung gebracht, dass das über das Setzen der entsprechende Bits in ADMUX.MUX0...3 funktioniert. Wenn ich diese Bits in einer Schleife entpsrechend den gewünschten Kanälen setze, bekomme ich aber dennoch kontinuierlich den immer gleichen Wert in ADCL bzw ADCH. Was mache ich falsch?

Vielen Dank schonmal für alle Infos!
Malte

Hackes
16.02.2011, 23:03
Hi,

ich vermute, du beziehst Dich auf BASCOM?! Du ließt die Register ADCL und ADCH direkt aus. Davon habe ich noch keine Ahnung, bin noch lange kein Profi aber den Wert des entsprechenden ADCs bekommst Du über den Befehl

I=GETADC(1..8)

In den Klammern gibst Du den Kanal an. Bin mir aber gerade nicht sicher, obs von 0..7 oder von 1..8 zählt.

Vielleicht hilfts Dir.

Gruß, Hackes

Hackes
16.02.2011, 23:04
Ein Schmeilie??? ;-)

I = GETADC ( 1 .. 8 )

So sollte es gehen...

malthy
16.02.2011, 23:09
Moin Hackes,

nee, das hilft nicht. Aber ich hab mein Problem vielleicht auch etwas zu knapp formuliert. Also erstens: ja, es geht um BASCOM, deshalb dieses Unterforum. Zweitens: GETADC ist eigentlich dafür gedacht, im single Modus die Werte für einen Kanal abzuholen. Ich möchte aber den ADC im free run betreiben, weil das deutlich schneller ist. Mit GETADC bekomme ich dabei zwar auch einen Wert, aber immer den gleichen, unabhängig vom Kanal den ich angebe. Und das meinte die BASCOM-Hilfe wohl, als sie feststellte "'The single mode must be used with the GETADC() function". Trotzdem Danke fürs Nachdenken!

Gruß
Malte

Hackes
16.02.2011, 23:25
Büdde Büdde, keine Thema mit dem Nachdenken.

Aber gerade machst Du MICH nachdenklich? Ist das wirklich so???

Ich habe gerade meinen Lappi nicht zur Hand, mit dem ich progge. Also in meinen Programmen arbeite ich bisher IMMER mit GETADC und bin mir fast sicher, daß ich auch schon den free running mode benutzt habe dabei. Aber ich mag mich irren.

ABer vielleicht kannst mir bei Gelegenheit helfen. Ich frage mich schon die ganze Zeit, WIE SCHNELL kann ich AKTUALISIERTE Werte vom ADC bekommen? Bisher arbeite ich immer mit nem LCD zur Anzeige und wenn ich die ADC schneller abfrage, sprich das LCD schneller als ca. 0,5 Sekunden aktualisieren will, kommt Müll zur Anzeige. Vielleicht ist aber auch das LCD das Problem?

Wie schnell schaffst DU es, die/den ADC abzufragen??? Stehe da noch ein bischen auf dem Schlauch. Wie machst Du es so?

Gruß, Hackes

abryx
17.02.2011, 09:52
Ich verwende den Freerun Modus für schnellstmögliche Messwerterfassung, die halt mit Bascom möglich ist.

Mit GETADC(x) benutzt Du IMMER ADC=Single als Modus, auch wenn Du FREE angibt ;-)

Beispiel für den Free-Modus (aus einem Tutorial)
Daraus kannst Du Dir das dann ableiten.



'initialize ADC
Config Adc = Free , Prescaler = 32 , Reference = Avcc 'ADC is automatically started, so immediately
Stop Adc 'stop ADC before it reach interrupt and we change channel

'define constants
Const Number_of_channels = 6 'ADC0-ADC5 on ATmega8 (value can also be for example 2 if we use ADC0-ADC1)
Const Adc_low_array_size = Number_of_channels * 2 'overlay bytes on word array
Const Adc_high_array_size = Adc_low_array_size - 1 'Adc_high array is smaller by 1 because of offset

'define variables
Dim Adc_value(number_of_channels) As Word
Dim Adc_low(adc_low_array_size) As Byte At Adc_value(1) Overlay
Dim Adc_high(adc_high_array_size) As Byte At Adc_value(1) + 1 Overlay
Dim Inital_admux_value As Byte
Dim Old_channel_value As Byte

'enable interrupts
Enable Adc 'will set ADCSRA.ADIE bit
Enable Interrupts

'define interrupts
On Adc Adc_isr

'initialize start conditions
Old_channel_value = 1 ' (0 * 2) + 1
Inital_admux_value = Admux 'store ADMUX register before channels are changed
Start Adc 'This will set ADC Enable bit, but not also ADCSRA.ADSC bit, so
Set Adcsra.adsc 'set ADC Start Conversion bit manually


'------------------------------------------------------------------------------
'The Interrupt Handler For The ADC Interrupt
'------------------------------------------------------------------------------
Adc_isr:
Adc_low(old_channel_value) = Adcl 'read ADCL first then ADCH
Adc_high(old_channel_value) = Adch 'it will not work other way

'new AD conversion has allready started so its time to change channel, but before we do that we need to
'store current channel, because channel change will not take effect until next conversion has started

Old_channel_value = Admux 'save status of ADMUX register
Old_channel_value = Old_channel_value Xor Inital_admux_value 'leave only channel number, remove informations about reference source
Old_channel_value = Old_channel_value * 2 'multiply by 2 and
Incr Old_channel_value 'add 1 to make it compatible with overlayed variables

If Old_channel_value => Adc_high_array_size Then Admux = Inital_admux_value Else Incr Admux 'change channel
'Toggle Admux.mux0 'you can use your own change channel logic (this will toggle ADC0 and ADC1)
'place it on the end of ISR to be on the safe side that at least 1 ADC clock cycle has passed
Return

Hackes
17.02.2011, 22:14
Hi,

hm, ok, ist also immer SINGLE. Wieder was gelernt. Vielen Dank für das Codebeispiel! Werde mir das Morgen mal zu Gemüte führen! :cheesy:

Gruß, Hackes