Forum: Mikrocontroller und Digitale Elektronik STM32F103: Auswahl des richtigen ADC Modus


von Jürgen (Gast)


Angehängte Dateien:

Lesenswert?

Moin Moin!

Ich benutze den STM32F103RET6 und habe 2 Signale die abgetastet werden 
sollen. Folgende Randbedingungen sind gegeben:

Signal 1 an PIN PA1 bzw. ADC123_IN1
Signal 2 an PIN PA0 bzw. ADC123_IN0

Signal 1 soll mit 8 kHz abgetastet werden, bis 256 Werte gesampelt sind.
Signal 2 soll mit 80 kHz abgetastet werden, bis 2560 Werte gesampelt 
sind.

Wichtig ist, dass die Werte des ersten Signals immer möglichst synchron 
mit jedem zehnten Wert des zweiten Signals abgetastet werden.
Die Werte sollen am besten per DMA in den Speicher übertragen werden.

Nun lese ich grade die Application Note *STM32 ADC modes and their 
applications* und überlege, welcher Modus sich dafür am besten eignet. 
Grundsätzlich erscheinen mir die Dual modes eher geeignet als die 
Independent modes. Ins Auge gefallen ist mir besonders der *Dual regular 
simultaneous mode* (Seite 9), da dort steht:

"The dual regular simultaneous mode can be used in applications where 
two signals should be sampled and converted at the same time."

Was meint ihr dazu? Ist evtl. ein anderer Modus besser geeignet? 
Bauschmerzen machen wir die unterschiedlichen Abtastfrequenzen, wobei 
ich ja notfalls das Signal 1 auch mit 80 kHz abtasten könnte, und dann 
hinterher eben viele Werte wegschmeissen könnte.

In dem Beispielprogramm dazu, das ja leider ohne Interrupts arbeitet 
stehen die Zeilen: (2 Mal warum auch immer?)
1
ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 1, ADC_SampleTime_239Cycles5);    
2
  ADC_RegularChannelConfig(ADC1, ADC_Channel_17, 2, ADC_SampleTime_239Cycles5);

Könnte ich statt ADC_SampleTime_239Cycles5 auch einfach die äquivalenten 
Cycles zu 1/8k und 1/80k angeben?

Vielleicht hat von euch ja schonmal jemand etwas ähnliches vorgehabt... 
Bin über jeden Tip dankbar :)

Vielen Dank! :)

von Michael D. (Gast)


Lesenswert?

Servus!

Magst Du die Signale Zeitgleich mit 2 ADCs (1ADC pro Kanal) oder 
hintereinander mit einem ADC abtasten?

Bei ersterem..
Da würd ich den Dual Regular Simulataneous Mode empfehlen.

ADC_RegularChannelConfig(.....)
braauchst Du dann für dann für zb: ADC1, Chan1 und ADC2, Chan 2..

Den Interrupt für den ADC brauchst du gar nicht, wenn du damit den DMA 
ansteuerst..

Der DMA gibt dann den Interrupt wenn er fertig ist (hier würd ich mir 
auch den Double Buffer Mode ansehen um die eigenen Werte nicht zu 
überschreiben.

Ich würde beide Kanäle mit der selben Frequenz abtasten und bei dem 
einen Kanal die überflüssigen Werte wegschmeissen. Der STM32 hat eh 
häufti Speicher..

Mfg,
Mike

von Jürgen (Gast)


Lesenswert?

Ok zeitgleich mit 2 ADCs hört sich gut an. Wie stelle ich denn die 
genaue Abtastfrequenz ein? Mache ich das zwangsweise über einen 
Hardwaretimer? Oder wozu gibt es dieses ADC_SampleTime_239Cycles5 u.ä.?

von Michael D. (Gast)


Lesenswert?

Servus!

Ich kenne den von Dir verwendeten Typen nicht im Detail da ich selbst 
einen F40x verwende, es sollte aber mit dem F103 auch alles gehen...

Nachdem ich von dir
ADC_RegularChannelConfig
gelesen habe, nehme ich an du verwendest die StdPeriphLib..

Über diese lässt sich beim ADCTrigger ein Timer einstellen (soweit ich 
weis geht dass nicht bei allen Timern (ich glaub TIM3 und noch einer 
funktionieren)).
Timer Interrupt brauchst du nicht zu aktivieren.

Die Samplintime sagt nichts über die Abtastfrequenz aus, sondern nur wie 
"lange" der Kanal gemessen wird (Längere Zeit ist meistens besser)

Mfg

von abc (Gast)


Lesenswert?

TIM2-5 sind die General Purpose Timer die für diese Anwendung vollkommen 
reichen.


TIM1,TIM6-7 Advanced

von Michael D. (Gast)


Lesenswert?

#define ADC_ExternalTrigConv_T1_CC1 /*!< For ADC1 and ADC2 */
#define ADC_ExternalTrigConv_T1_CC2 /*!< For ADC1 and ADC2 */
#define ADC_ExternalTrigConv_T2_CC2 /*!< For ADC1 and ADC2 */
#define ADC_ExternalTrigConv_T3_TRGO/*!< For ADC1 and ADC2 */
#define ADC_ExternalTrigConv_T4_CC4 /*!< For ADC1 and ADC2 */
#define ADC_ExternalTrigConv_Ext_IT11_TIM8_TRGO/*!< For ADC1 and ADC2 */

#define ADC_ExternalTrigConv_T1_CC3/*!< For ADC1, ADC2 and ADC3 */
#define ADC_ExternalTrigConv_None  /*!< For ADC1, ADC2 and ADC3 */

#define ADC_ExternalTrigConv_T3_CC1 /*!< For ADC3 only */
#define ADC_ExternalTrigConv_T2_CC3 /*!< For ADC3 only */
#define ADC_ExternalTrigConv_T8_CC1 /*!< For ADC3 only */
#define ADC_ExternalTrigConv_T8_TRGO/*!< For ADC3 only */
#define ADC_ExternalTrigConv_T5_CC1 /*!< For ADC3 only */
#define ADC_ExternalTrigConv_T5_CC3 /*!< For ADC3 only */

Hab meine ADCs so konfiguriert (F4)
ADC_InitStructure.ADC_ExternalTrigConvEdge = 
ADC_ExternalTrigConvEdge_Rising;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_TRGO;

von Jürgen (Gast)


Lesenswert?

Super, danke für eure Tips. Eine Frage hätt ich noch. Wenn ich durch 
meinen Timer Interrupts generieren liesse, und in der ISR immer eine 
einzelne Messung starte, kann ich ja durch das Toggeln eines Pins immer 
leicht feststellen, ob die Abtastfrequenz stimmt.
Wenn ich den ADC allerdings automatisch durch einen Timer starten lasse, 
kann ich ja nicht ohne Weiteres die Samplerate überprüfen, oder doch? 
Hat jemand eine Idee, wie ich überprüfen könnte, dass der ADC genau in 
den richtigen Intervallen gestartet wird?

von Michael D. (Gast)


Lesenswert?

Servus!

Zum testen kann man ja den TimerIRQ einschalten und darin einen Pin 
toggeln lassen.

Später (wenn der ADC vom Timer getriggert wird) kann man das dann auch 
im DMA-Interrupt machen.

Die Zeit entspricht dann eben Abtastfrequenz (=Timer) * Anzahl Samples 
;-)

Mach ich auch so.

Mfg,
Mike

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.