STM32f3 ADC injected Conversion

OP #4296484
Lesenswert?
• ▲
▼
Moin,

ich versuche gerade den ADC auf meinem STM32f3 discovery board zum 
laufen zu bekommen. Leider klappt es nicht so ganz. Die Conversion soll 
über T1 CC4 getriggert werden. ich wollte ADC1 & 2 nutzen. es muss 
jeweils nur ein kanal umgesetzt werden. hier ist mein code, der leider 
noch nicht funktioniert. es wäre toll, wenn jemand mal einen blick drauf 
werfen könnte:
1
    RCC_ADCCLKConfig(RCC_ADC12PLLCLK_Div2);
2
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
3
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_ADC12, ENABLE);
4

5
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2;
6
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
7
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
8
    GPIO_Init(GPIOA, &GPIO_InitStructure);
9

10
    ADC_InitStructure.ADC_ContinuousConvMode = ADC_ContinuousConvMode_Disable;
11
    ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
12
    ADC_InitStructure.ADC_ExternalTrigConvEvent = ADC_ExternalTrigConvEvent_0;
13
    ADC_InitStructure.ADC_ExternalTrigEventEdge = ADC_ExternalTrigEventEdge_None;
14
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
15
    ADC_InitStructure.ADC_OverrunMode = ADC_OverrunMode_Disable;
16
    ADC_InitStructure.ADC_AutoInjMode = ADC_AutoInjec_Disable;
17
    ADC_InitStructure.ADC_NbrOfRegChannel = 1;
18

19
    ADC_Init(ADC1, &ADC_InitStructure);
20
    ADC_Init(ADC2, &ADC_InitStructure);
21

22
    ADC_InjectedInitStructure.ADC_ExternalTrigInjecConvEvent = ADC_ExternalTrigInjecConvEvent_1;
23
    ADC_InjectedInitStructure.ADC_ExternalTrigInjecEventEdge = ADC_ExternalTrigInjecEventEdge_RisingEdge;
24
    ADC_InjectedInitStructure.ADC_NbrOfInjecChannel = 1;
25
    ADC_InjectedInitStructure.ADC_InjecSequence1 = ADC_InjectedChannel_2;
26

27
    ADC_InjectedInit(ADC1, &ADC_InjectedInitStructure);
28

29
    ADC_InjectedInitStructure.ADC_ExternalTrigInjecConvEvent = ADC_ExternalTrigInjecConvEvent_1;
30
    ADC_InjectedInitStructure.ADC_ExternalTrigInjecEventEdge = ADC_ExternalTrigInjecEventEdge_RisingEdge;
31
    ADC_InjectedInitStructure.ADC_NbrOfInjecChannel = 1;
32
    ADC_InjectedInitStructure.ADC_InjecSequence1 = ADC_InjectedChannel_3;
33

34
    ADC_InjectedInit(ADC2, &ADC_InjectedInitStructure);
35

36
    ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
37
    ADC_CommonInitStructure.ADC_Clock = ADC_Clock_AsynClkMode;
38
    ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
39
      ADC_CommonInitStructure.ADC_DMAMode = ADC_DMAMode_OneShot;
40
    ADC_CommonInitStructure.ADC_TwoSamplingDelay = 0;
41

42
    ADC_CommonInit(ADC1, &ADC_CommonInitStructure);
43
    ADC_CommonInit(ADC2, &ADC_CommonInitStructure);
44

45
    ADC_InjectedChannelSampleTimeConfig(ADC1, ADC_InjectedChannel_2, ADC_SampleTime_1Cycles5);
46
    ADC_InjectedChannelSampleTimeConfig(ADC2, ADC_InjectedChannel_3, ADC_SampleTime_1Cycles5);
47

48
    ADC_Cmd(ADC1, ENABLE);
49
    ADC_Cmd(ADC2, ENABLE);
OP #4297449
Lesenswert?
• ▲
▼
Hey,
da hast du wohl recht. inzwischen bin ich auch weg von der injected 
group. leider klappt es immernoch nicht, der DMA IT TC wird nur einmal 
aufgerufen und es wird auch nur der erste ADC wert übertragen, der 
zweite teil bleibt leer.
1
void ADC_DMA_Config(void){
2

3

4
    RCC_ADCCLKConfig(RCC_ADC12PLLCLK_Div2);
5

6
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_ADC12, ENABLE);
7

8
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
9
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
10
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
11

12

13
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 ;
14
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
15
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
16
    GPIO_Init(GPIOA, &GPIO_InitStructure);
17

18
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 ;
19
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
20
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
21
    GPIO_Init(GPIOA, &GPIO_InitStructure);
22

23
    ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
24
    ADC_CommonInitStructure.ADC_Clock = ADC_Clock_AsynClkMode;
25
    ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
26
    ADC_CommonInitStructure.ADC_DMAMode = ADC_DMAMode_OneShot;
27
    ADC_CommonInitStructure.ADC_TwoSamplingDelay = 10;
28

29
    ADC_CommonInit(ADC1, &ADC_CommonInitStructure);
30

31
    ADC_InitStructure.ADC_ContinuousConvMode = ADC_ContinuousConvMode_Disable;
32
    ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
33
    ADC_InitStructure.ADC_ExternalTrigConvEvent = ADC_ExternalTrigConvEvent_0;
34
    ADC_InitStructure.ADC_ExternalTrigEventEdge = ADC_ExternalTrigEventEdge_None;
35
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
36
    ADC_InitStructure.ADC_OverrunMode = ADC_OverrunMode_Disable;
37
    ADC_InitStructure.ADC_AutoInjMode = ADC_AutoInjec_Disable;
38
    ADC_InitStructure.ADC_NbrOfRegChannel = 2;
39
    ADC_Init(ADC1, &ADC_InitStructure);
40

41
    /* ADC1 regular channel7 configuration */
42
    ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 1, ADC_SampleTime_7Cycles5);
43
    ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 2, ADC_SampleTime_7Cycles5);
44

45

46
    DMA_StructInit(&DMA_InitStructure);
47
    DMA_InitStructure.DMA_PeripheralBaseAddr  = (uint32_t)&(ADC1->DR);
48
    DMA_InitStructure.DMA_MemoryBaseAddr  = (uint32_t)&ADCBuffer;
49
    DMA_InitStructure.DMA_DIR  = DMA_DIR_PeripheralSRC;
50
    DMA_InitStructure.DMA_BufferSize  = 2;
51
    DMA_InitStructure.DMA_PeripheralInc  = DMA_PeripheralInc_Disable;
52
    DMA_InitStructure.DMA_MemoryInc  = DMA_MemoryInc_Enable;
53
    DMA_InitStructure.DMA_PeripheralDataSize  = DMA_PeripheralDataSize_HalfWord;
54
    DMA_InitStructure.DMA_MemoryDataSize  = DMA_MemoryDataSize_HalfWord;
55
    DMA_InitStructure.DMA_Mode  = DMA_Mode_Normal;
56
    DMA_InitStructure.DMA_Priority  = DMA_Priority_Medium;
57
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
58
    DMA_Init(DMA1_Channel1, &DMA_InitStructure);
59
    DMA_ClearITPendingBit(DMA1_IT_TC1);
60
    DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE);
61

62

63
    NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;
64
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
65
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
66
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
67
    NVIC_Init(&NVIC_InitStructure);
68

69

70
    ADC_DMAConfig( ADC1, ADC_DMAMode_OneShot);
71
    ADC_DMACmd(ADC1, ENABLE);
72
    ADC_Cmd(ADC1, ENABLE);
73
  }

Über
1
DMA_SetCurrDataCounter(DMA1_Channel1, 2);
2
DMA_Cmd(DMA1_Channel1, ENABLE);
3
ADC_StartConversion(ADC1);

soll das ganze über ein TImer CC ausgelöst werden.

LG Alex
#4297470
Lesenswert?
• ▲
▼
Hi,

hast Du auch den Timer im Mastermodus konfiguriert?
Bei mir (STM32f4) sieht das für das Update-Event als Trigger mit 
HAL-Treibern folgendermaßen aus:
1
sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
2
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_ENABLE;

Dein ADC scheint nicht im Triggermodus konfiguriert zu sein. Bei mir 
wäre das:
1
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;
2
hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T2_TRGO;

Es müssen zudem kontinuierlich DMA-Requests generiert werden, sonst wird 
eben nur einmalig ein Wert übertragen (nicht verwechseln mit 
ContinuousConvMode):
1
hadc1.Init.DMAContinuousRequests = ENABLE;

Hoffe es hilft weiter!

Gruß
Christof
#4297595
Lesenswert?
• ▲
▼
Ok. Dennoch produziert dein ADC keine kontinuierlichen Requests. Beim f3 
wird's etwas anders als bei meinem f4 gemacht:

> DMA one shot mode (DMACFG=0)
> In this mode, the ADC generates a DMA transfer request each time a new
> conversion data is available and stops generating DMA requests once
> the DMA has reached the last DMA transfer (when DMA_EOT interrupt occurs
> - refer to DMA paragraph) even if a conversion has been started again.

Also musst Du den DMA circular mode (DMACFG=1) benutzen, damit nach 
jeder Wandlungsfolge ein Request ausgelöst wird.

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.