Moin,
ich habe mit CubeMX ein einfaches Beispiel für den ADC mit DMA
generiert. Die Initialisierung sieht wie folgt aus:
1 | ADC_ChannelConfTypeDef sConfig;
|
2 |
|
3 | hadc1.Instance = ADC1;
|
4 | hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV8;
|
5 | hadc1.Init.Resolution = ADC_RESOLUTION_12B;
|
6 | hadc1.Init.ScanConvMode = ENABLE;
|
7 | hadc1.Init.ContinuousConvMode = ENABLE;
|
8 | hadc1.Init.DiscontinuousConvMode = DISABLE;
|
9 | hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
|
10 | hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
|
11 | hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
|
12 | hadc1.Init.NbrOfConversion = 6;
|
13 | hadc1.Init.DMAContinuousRequests = ENABLE;
|
14 | hadc1.Init.EOCSelection = ADC_EOC_SEQ_CONV;
|
15 | if (HAL_ADC_Init(&hadc1) != HAL_OK)
|
16 | {
|
17 | _Error_Handler(__FILE__, __LINE__);
|
18 | }
|
19 |
|
20 | sConfig.Channel = ADC_CHANNEL_0;
|
21 | sConfig.Rank = 1;
|
22 | sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES;
|
23 | if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
|
24 | {
|
25 | _Error_Handler(__FILE__, __LINE__);
|
26 | }
|
27 |
|
28 | // hier folgen Rank 2-6 analog
|
Der DMA Stream läuft im Circular Mode. Nun starte ich den ADC mit
1 | HAL_ADC_Start_DMA(&hadc1, ADC_Buffer, 12);
|
, wodurch HAL_ADC_ConvCpltCallback kontinuierlich aufgerufen wird, wie
es sein soll. Testweise habe ich nun ein Delay von 100ms in den Callback
eingebaut und dachte, damit einen Overrun provozieren zu können. Dazu
habe ich noch HAL_ADC_ErrorCallback implementiert, allerdings läuft das
Programm munter weiter. Nur der ConvCplt-Callback wird dann entsprechend
seltener ausgeführt.
Meine Frage ist nun: Wie genau arbeitet der DMA Transfer im Continuous
Mode? Werden die Werte vom ADC einfach weiter in mein Array geschrieben,
sodass ich sicherstellen muss, die Werte im Callback schnell genug
abzuholen oder wird einfach weniger gesampled, wenn der Callback zu
lange braucht, wie in meinem Beispiel?