Forum: Mikrocontroller und Digitale Elektronik STM32 ADC mit DMA


von pxc (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

ich versuche gerade den ADC meines STM32F072RB so einzurichten, dass er 
einmal meine 4 ADC-Kanäle durchscannt und dann wartet bis er erneut dazu 
aufgefordert wird. Das Ganze mit Hilfe des DMA, das einfach nur ein 
Array füllen soll und bei neuer Messung dies einfach nochmal 
überschreibt.

Leider sind die Beispiele von ST teilweise sehr verwirrend, ich habe mir 
jetzt vieles aus einem Beispiel zusammengefügt das permanent und ohne 
neue Aufforderung scannt.


Meine Frage ist, wie triggere ich jetzt den ADC, dass er eine Messung 
startet (und nach 4 Werten aufhört)? Weiß jemand weiter?

Diese main.c ist natürlich nur zum testen dieser ADC mit DMA Geschichte, 
die echte main würde einmal pro Durchgang in die Funktion 
triggerADCbla(..) springen und den ADC auffordern zu messen.

von pxc (Gast)


Lesenswert?

Mit ADC_StartOfConversion scheint er zumindest schonmal etwas richtig zu 
machen. Wenn ich 3,3V an PA0 anlege gibt er in ADC_ConvertedValue[0] 
4095 aus, die anderen werte sollten 0 sein, sind aber alle zwischen 
11xx-27xx.

Gebe ich die 3,3V auf den PA1 springt ADC_ConvertedValue[0] auf 0 (was 
er auch soll) und ADC_ConvertedValue[1] auf 4095 was auch korrekt ist. 
Die anderen beiden (PB0 und PB1) zeigen Quatsch an.

Bei 3,3V auf PB0 und PB1 wird immer noch ein gezappel zwischen 1100-2200 
angezeigt und ADC_ConvertedValue[1] ist ebenfalls auf einem Unsinnswert.



1
uint16_t ADC_ConvertedValue[5];
2
3
int main(void){
4
  
5
  uint32_t i;
6
  
7
  vInitGPIO();
8
  vInitADCwithDMA();
9
  vInitDMAChannelForADC();
10
  
11
  while(1){
12
    
13
           ADC_StartOfConversion(ADC1);
14
    
15
           for (i = 0; i < 1000000; i++){}
16
    
17
           /* Test DMA1 TC flag */
18
           while((DMA_GetFlagStatus(DMA1_FLAG_TC1)) == RESET ); 
19
    
20
           /* Clear DMA TC flag */
21
           DMA_ClearFlag(DMA1_FLAG_TC1);
22
    
23
  }
24
  
25
26
}

von pxc (Gast)


Lesenswert?

Es muss natürlich
1
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
2
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE); // B heißen, anstatt A



Leider zeigen PA1, PB0 und PB1 immer noch undefinierte Werte.

von Nop (Gast)


Lesenswert?

Sicher, daß das hier so sein soll:
1
// settings for each ADC channel
2
  ADC_ChannelConfig(ADC1, ADC_Channel_0, ADC_SampleTime_13_5Cycles);
3
  ADC_ChannelConfig(ADC1, ADC_Channel_1, ADC_SampleTime_13_5Cycles);
4
  ADC_ChannelConfig(ADC1, ADC_Channel_8, ADC_SampleTime_13_5Cycles);
5
  ADC_ChannelConfig(ADC1, ADC_Channel_9, ADC_SampleTime_13_5Cycles);

Also daß immer ADC1 dasteht?

von pxc (Gast)


Lesenswert?

Nop schrieb:
> Sicher, daß das hier so sein soll:
>
>
1
// settings for each ADC channel
2
>   ADC_ChannelConfig(ADC1, ADC_Channel_0, ADC_SampleTime_13_5Cycles);
3
>   ADC_ChannelConfig(ADC1, ADC_Channel_1, ADC_SampleTime_13_5Cycles);
4
>   ADC_ChannelConfig(ADC1, ADC_Channel_8, ADC_SampleTime_13_5Cycles);
5
>   ADC_ChannelConfig(ADC1, ADC_Channel_9, ADC_SampleTime_13_5Cycles);
>
> Also daß immer ADC1 dasteht?

Ja.

void ADC_ChannelConfig(ADC_TypeDef* ADCx, uint32_t ADC_Channel, uint32_t 
ADC_SampleTime)

ADCx ist das Peripheral und da mein Controller nur einen ADC hat ist es 
ADC1.

von pxc (Gast)


Lesenswert?

Komme dem Rätsel vielleicht auf die Spur, aber stehe trotzdem auf dem 
Schlauch.

Habe jetzt mal tatsächlich an den Pins gemessen. Es liegen Spannungen an 
ihnen an, ohne dass etwas angeschlossen ist. Da es ein Discovery Board 
ist, dachte ich an Chips, die eventuell mit den Pins verbunden sind, 
aber selbst Pins die einfach frei sind haben eine Spannung... Wie kann 
das sein, wenn der Pin als Analog Input konfiguriert wird und kein 
Pullup/Pulldown aktiviert wird?

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

pxc schrieb:
> Wie kann
> das sein, wenn der Pin als Analog Input konfiguriert wird und kein
> Pullup/Pulldown aktiviert wird?

Es gibt nur einen internen S&H Kondensator für einen ADC, auch wenn er 
mehrere Kanäle hat.
Der Eingangsmultiplexer verbindet damit die Ladung des S&H von einem 
Eingang mit einem anderen Eingang. Das ist auch der Grund, warum solche 
ADC Eingänge niederohmig angetrieben werden sollen, der S&H Kondensator 
muss während der Samplephase komplett aufgeladen werden.
Legst du die unbenutzten ADC Kanäle auf Masse, werden sie 0 anzeigen, 
wie erwartet.

: Bearbeitet durch User
von pxc (Gast)


Lesenswert?

Aber wenn nichts angeschlossen ist, sollte man doch eigentlich 0 
erwarten, da der Kondensator für jeden einzelnen Channel den er sampelt 
neu geladen werden muss. Oder sehe ich das falsch?

Trotzdem haben die ADC Pins 1 - 1,5V, ohne dass überhaupt irgendwas 
angeschlossen ist.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

pxc schrieb:
> da der Kondensator für jeden einzelnen Channel den er sampelt
> neu geladen werden muss.

Es ist niemand da, der ihn entladen würde. Auf der einen Seite ein 
hochohmiger ADC, auf der anderen Seite ein offener Eingang, bzw. nur 
dein Messgerät. Der Kondensator wird umgeladen, wenn er auf einen 
beschalteten Eingang kommt. Der Treiber für diesen Eingang lädt, bzw. 
entlädt den Kondensator.

von Emil (Gast)


Lesenswert?

Wie macht man das bei den STM32 dann eigentlich, wenn man eine 
Kabelbrucherkennung an einem ADC realisieren möchte? Ein Pull-Down ist 
wahrscheinlich keine gute Idee. Bei den kleinen Atmels geht das einfach 
so. Nichts angeschlossen und der ADC zeigt 0.

von pxc (Gast)


Lesenswert?

Matthias S. schrieb:
> pxc schrieb:
>> da der Kondensator für jeden einzelnen Channel den er sampelt
>> neu geladen werden muss.
>
> Es ist niemand da, der ihn entladen würde. Auf der einen Seite ein
> hochohmiger ADC, auf der anderen Seite ein offener Eingang, bzw. nur
> dein Messgerät. Der Kondensator wird umgeladen, wenn er auf einen
> beschalteten Eingang kommt. Der Treiber für diesen Eingang lädt, bzw.
> entlädt den Kondensator.

Okay, ein Kanal an GND und einer an 3,3V liefert schonmal das was man 
erwarten würde. Ich denke das wird wohl das Problem gewesen sein. Danke 
dir für den Hinweis, man lernt nie aus...

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Emil schrieb:
> Nichts angeschlossen und der ADC zeigt 0.

Das nehme ich dir nicht ab. Probier mal mehr als einen Kanal einzulesen 
und lass einen Nachbar Kanal frei. (Wohlgemerkt, nicht die Tinys mit dem 
eingebauten Opamp). Du wirst sehen, das der Nachbarkanal vom 
angesteuerten Kanal 'mitgezogen' wird.

> Wie macht man das bei den STM32 dann eigentlich, wenn man eine
> Kabelbrucherkennung an einem ADC realisieren möchte?

Da es für kritische Anwendungen sein muss, würde ich in einem solchen 
Fall den ADC immer mit einem Buffer treiben, also z.B. mit einem OpAmp.

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
Noch kein Account? Hier anmelden.