Forum: Mikrocontroller und Digitale Elektronik STM32F4 ADC 1 mehrere Kanäle


von MOBA 2. (Gast)


Lesenswert?

Hallo,

ich habe dazu nichts passendes gefunden:

Ich möchte ADC1 Kanal 0, 1, 2 benutzten.
Kanal 2 wird einmal beim Start gemessen, dann nicht mehr.

Kanals 0, 1 sollen permanent per DMA messen und die Werte in ein Array 
schreiben.


Dazu habe ich folgende Fragen:

1. Muss ich jetzt ADC1, ADC2, ADC3 initialisieren, oder kann ich ADC1 
mit Kanal 0-2 initialisieren. Das verstehe ich noch nicht ganz wie da 
der Zusammenhang ist.

Das ist ermal der Code, für die einfache Conversion:
1
while (HAL_ADC_PollForConversion(&adc2, 2500) != HAL_OK);
2
vcc_mid_voltage = HAL_ADC_GetValue(&adc2);
Ist das korrekt, dass man mit der PollForConversion Funktion warten 
muss, bis der ADC quasi bereit ist?! Hat der sonst keine Funktion ADC 
abgeschlossen? Das timeout (2500) sollten ms sein, hoffe ich.



Jetzt die Frage, wie mache ich das mit den anderen beiden ADC Kanälen?
Wie initialisiere ich die, und wie starte ich den DMA, bzw. wann weiß 
ich wenn der was fertig gemacht hat. Ist die initialisierung so 
überhautp an sich korrekt, oder überschreibe ich die einzelnen Kanäle 
damit wieder?
1
main.c
2
3
adc_init(2, ADC_CHANNEL_0);     //RX_Q
4
adc_init(2, ADC_CHANNEL_1);     //RX_I
5
adc_init(2, ADC_CHANNEL_2);     //mid-voltage for reference


Hier die Implementierung
1
adc.c
2
3
/* ADC1 init function */
4
void adc_init(uint8_t _prescaler, uint32_t _channel)
5
{
6
    ADC_ChannelConfTypeDef sConfig;
7
8
    //Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion
9
    adc_radar.Instance = USED_RADAR_ADC;
10
11
12
    switch (_prescaler)
13
    {
14
        case 2: adc_radar.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;
15
            break;
16
17
        case 4: adc_radar.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
18
            break;
19
20
        case 6: adc_radar.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV6;
21
            break;
22
23
        case 8: adc_radar.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV8;
24
            break;
25
26
        default:
27
                adc_radar.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;
28
    }
29
30
31
    adc_radar.Init.Resolution = ADC_RESOLUTION_12B;
32
    adc_radar.Init.ScanConvMode = DISABLE;
33
    adc_radar.Init.ContinuousConvMode = DISABLE;
34
    adc_radar.Init.DiscontinuousConvMode = DISABLE;
35
    adc_radar.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
36
    adc_radar.Init.DataAlign = ADC_DATAALIGN_RIGHT;
37
    adc_radar.Init.NbrOfConversion = 1;
38
    adc_radar.Init.DMAContinuousRequests = DISABLE;
39
    adc_radar.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
40
    HAL_ADC_Init(&adc_radar);
41
42
    //Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
43
    sConfig.Channel = _channel;
44
    sConfig.Rank = 1;
45
    sConfig.Offset = 0;
46
    sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
47
    HAL_ADC_ConfigChannel(&adc_radar, &sConfig);
48
    HAL_ADC_Start(&adc_radar);
49
}


Klappt das so, muss ich die anders initialisieren oder muss ich gar 
ADC1, 2, 3 getrennt nutzen?!

von Sheriff Silver (Gast)


Lesenswert?

Wie du schon richtig erkannt hast, musst du bei der Benutzung eines ADCs 
und mehreren Channels DMA benutzen.

Wie du diesen aktivierst, steht im Datenblatt. Einfacher geht es, wenn 
du die Konfiguration des Mikrocontrollers mit CubeMX vornimmst. Dort 
kannst du DMA direkt dem ADC zu weisen.

Am besten du googlest mal "STM32 ADC channel selection" und arbeitest 
dich durch die Foren.

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.