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.
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 | }
|
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.
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?
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.
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?
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
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.
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.
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.
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...
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.