Forum: Mikrocontroller und Digitale Elektronik Kontinuierliche Analog-Digital-Wandlung bricht nach erstem Mal ab (STM32L476RG)


von Crazy_Daisy_57 (Gast)


Lesenswert?

Hallo

Mein Code sollte, einmal gestartet, im "Dauer-Loop" das Signal am Kanal 
5 digitalisieren. Jedoch findet nur eine einzige Konvertierung statt. 
Danach bricht es ab.

Ich dachte, es würde reichen, "continuous" als "Conv. Mode" zu 
konfigurieren (siehe Zeile 42) - offensichtlich müsste ich aber noch 
sonstwas tun.

Ich habe einen DMA-Transfer eingerichtet, welcher zumindest für das eine 
erste Mal funktioniert, um das Resultat in eine globale Variable zu 
kopieren. Das Resultat in ADC_DR wird also grundsätzlich ausgewertet. 
Müsste ich vielleicht noch irgend ein Flag "clearen", damit die nächste 
"Conversion" gestartet wird?
1
#include <stm32l4xx.h>
2
3
extern void delay_ms(unsigned t)
4
5
void setup_adc(void) {
6
  //Configure ADC:
7
  {
8
    //Make sure PA0 is enabled and configured "analog mode".
9
    RCC->AHB2ENR |= RCC_AHB2ENR_GPIOAEN;
10
    GPIOA->MODER |= GPIO_MODER_MODE0;
11
    GPIOA->ASCR |= GPIO_ASCR_ASC0;
12
13
    //Enable the ADC clock.
14
    RCC->AHB2ENR |= RCC_AHB2ENR_ADCEN;
15
16
    //Select SYSCLK as ADC clock
17
    RCC->CCIPR &= ~(RCC_CCIPR_ADCSEL);
18
    RCC->CCIPR |= RCC_CCIPR_ADCSEL;
19
20
    //Configure a prescaler of 8 for the CLK to the ADC.
21
    ADC123_COMMON->CCR &= ~(ADC_CCR_PRESC);
22
    ADC123_COMMON->CCR |= ADC_CCR_PRESC_2; //80 MHz / 8 = 10 MHz
23
24
    //Auto calibrate the ADC:
25
    {
26
      //Enable ADC voltage regulator
27
      ADC1->CR &= ~(ADC_CR_DEEPPWD);
28
      ADC1->CR |= ADC_CR_ADVREGEN;
29
30
      //Delay for min. 2000 us.
31
      delay_ms(2);
32
33
      //(Re-)Load calibration data.
34
      ADC1->CR |= ADC_CR_ADCAL;
35
      while(ADC1->CR & ADC_CR_ADCAL);
36
    }
37
38
    //Configure a resolution of 12 bit.
39
    ADC1->CFGR &= ~(ADC_CFGR_RES);
40
41
    //Enable continuous conversion mode.
42
    ADC1->CFGR |= ADC_CFGR_CONT;
43
44
    //Enable the generation of DMA requests.
45
    ADC1->CFGR |= ADC_CFGR_DMAEN;
46
47
    //Configure data alignment "right aligned".
48
    ADC1->CFGR &= ~(ADC_CFGR_ALIGN);
49
50
    //Configure the sampling time for CH05 to 2.5 ADC clock cycles.
51
    ADC1->SMPR1 &= ~(ADC_SMPR1_SMP5);
52
53
    //Set the number of channels to read during each sequence to "1".
54
    ADC1->SQR1 &= ~(ADC_SQR1_L);
55
56
    //Configure the first (and only) step in the sequence to "ADC12_IN5" (@PA0).
57
    ADC1->SQR1 &= ~(ADC_SQR1_SQ1);
58
    ADC1->SQR1 |= (5 << ADC_SQR1_SQ1_Pos);
59
60
    //Enable the ADC.
61
    ADC1->CR |= ADC_CR_ADEN;
62
    while(!(ADC1->ISR & ADC_ISR_ADRDY));
63
  }
64
65
  //Start ADC conversion.
66
  ADC1->CR |= ADC_CR_ADSTART;
67
}

von Christian (christian_m346)


Lesenswert?

Tatsächlich muss in Zeile 45 auch das Bit "DMACFG" gesetzt werden, damit 
das ganze im "Circular-Mode" arbeitet:
1
ADC1->CFGR |= ADC_CFGR_DMAEN + ADC_CFGR_DMACFG;

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.