Forum: Mikrocontroller und Digitale Elektronik STM32F4 ADC 2 Channel DMA nur einer wird übertragen


von bibu (Gast)


Lesenswert?

Moin Moin,

ich habe folgendes Problem: Ich bekomme die ADC Werte ausgelesen, aber 
er legt mir auf ADC3ConvertedValue[0] und ADC3ConvertedValue[1] den 
gleichen Wert. Er spiegelt also nur den einen auf den anderen und 
übernimmt nicht die zweite ADC-Auswertung.
Hier die Relevanten Code-Teile:

/* Includes */
#include "stm32f4xx.h"
#include "stm32f4_discovery.h"

#define ADC3_DR_ADDRESS     ((uint32_t)0x4001224C)

__IO uint16_t ADC3ConvertedValue[2]={5,3};
__IO uint32_t ADC3ConvertedVoltage = 0;


int main(void)
{
  mycan();
  mytimer();
  ADC3_CH12_DMA_Config();
  ADC_SoftwareStartConv(ADC3);
  while (1)
  {
    ADC3ConvertedVoltage = ADC3ConvertedValue[0] *3300/0xFFF;
    ADC3ConvertedVoltage = ADC3ConvertedValue[1] *3300/0xFFF;
  }
}

void ADC3_CH12_DMA_Config(void)
{
  ADC_InitTypeDef       ADC_InitStructure;
  ADC_CommonInitTypeDef ADC_CommonInitStructure;
  DMA_InitTypeDef       DMA_InitStructure;
  GPIO_InitTypeDef      GPIO_InitStructure;

  /* Enable ADC3, DMA2 and GPIO clocks 
****************************************/
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2 | RCC_AHB1Periph_GPIOA, 
ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3, ENABLE);

  /* DMA2 Stream0 channel0 configuration 
**************************************/
  DMA_InitStructure.DMA_Channel = DMA_Channel_2;
  DMA_InitStructure.DMA_PeripheralBaseAddr =(uint32_t)ADC3_DR_ADDRESS;
  DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADC3ConvertedValue;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
  DMA_InitStructure.DMA_BufferSize = 2; //neu
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; 
//DMA_MemoryInc_Disable; //neu
  DMA_InitStructure.DMA_PeripheralDataSize = 
DMA_PeripheralDataSize_HalfWord;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
  DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
  DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
  DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
  DMA_Init(DMA2_Stream0, &DMA_InitStructure);
  DMA_Cmd(DMA2_Stream0, ENABLE);

  /* Configure ADC3 Channel12 pin as analog input 
******************************/
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2; //neu
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
  GPIO_Init(GPIOA, &GPIO_InitStructure);



  /* ADC Common Init 
**********************************************************/
  ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
  ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
  ADC_CommonInitStructure.ADC_DMAAccessMode = 
ADC_DMAAccessMode_Disabled;
  ADC_CommonInitStructure.ADC_TwoSamplingDelay = 
ADC_TwoSamplingDelay_5Cycles;
  ADC_CommonInit(&ADC_CommonInitStructure);

  /* ADC3 Init 
****************************************************************/
  ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
  ADC_InitStructure.ADC_ScanConvMode = ENABLE;//DISABLE;//neu
  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
  ADC_InitStructure.ADC_ExternalTrigConvEdge = 
ADC_ExternalTrigConvEdge_None;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_NbrOfConversion = 1;
  ADC_Init(ADC3, &ADC_InitStructure);

  /* ADC3 regular channel12 configuration 
*************************************/
  ADC_RegularChannelConfig(ADC3, ADC_Channel_1, 1, 
ADC_SampleTime_3Cycles);
  ADC_RegularChannelConfig(ADC3, ADC_Channel_2, 2, 
ADC_SampleTime_15Cycles);//neu


 /* Enable DMA request after last transfer (Single-ADC mode) */
  ADC_DMARequestAfterLastTransferCmd(ADC3, ENABLE);

 // ADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE); //neu

  /* Enable ADC3 DMA */
  ADC_DMACmd(ADC3, ENABLE);

  /* Enable ADC3 */
  ADC_Cmd(ADC3, ENABLE);

  ADC_SoftwareStartConv(ADC3);
}

von Dirk H. (dirk_h)


Lesenswert?

Hi,

ich habe mir deinen Code jetzt nicht angesehen, aber ADC mit DMA steht 
bei mir auch noch aus. Allerdings habe ich genau deinen Anwendungsfall 
(2ADcs mit DMA) schon mal gelesen:

http://diller-technologies.de/stm32.html#dma

Vielleicht hilft es dir ja weiter.

Gruß
Dirk

von Nils P. (ert)


Lesenswert?

im debugger schaust du dir hoffentlich die ADC3ConvertedValue[x] an und 
nicht die ADC3ConvertedVoltage ,,,
1
    ADC3ConvertedVoltage = ADC3ConvertedValue[0] *3300/0xFFF;
2
    ADC3ConvertedVoltage = ADC3ConvertedValue[1] *3300/0xFFF;

und schau hier nochmal:
 ADC_CommonInitStructure.ADC_DMAAccessMode = XXXX;

von bibu (Gast)


Lesenswert?

Ja ich schau, wie oben beschrieben, ADC3ConvertedValue[0] und [1] bzw. 
lass es noch über CAN rausgeben. ADC3ConvertedVoltage ist nur noch ein 
Code-Überbleibsel.
Die Werte verändern sich auch. Allerdings beide irgendwie nur von einem 
Sensor nur.

ADC_CommonInitStructure.ADC_DMAAccessMode  hab ich mit disable und 
enable schon ausprobiert, werde es aber gleich nochmal ausprobieren.

er wandelt ja und schick auch die Werte zum DMA aber irgendwie übernimmt 
er für beide Arraywerte einen Sensor. So weit ich denke sollte doch der 
eine Arraywert den einen ADC-Channel zeigen und der Andere den Anderen.


Das Diller-tut guck ich mir dann nochmal an.

von bibu (Gast)


Lesenswert?

Fehler gefunden:
Es war nur ein Kanal aktiviert...:

ADC_InitStructure.ADC_NbrOfConversion = 1;  <--- muss 2 sein...

Trotzdem danke für die Antworten.


Und schon wieder ein neuer, wenn ich den dritten Kanal einbinden will, 
dann kommen da wieder nur komische werte raus, die aber anscheinend 
irgendwie mit dem 2. Kanal reagieren...

Die Änderungen sind im enteffekt nur:

__IO uint16_t ADC3ConvertedValue[3];
DMA_InitStructure.DMA_BufferSize = 3;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //neu
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
ADC_InitStructure.ADC_NbrOfConversion = 3;
ADC_RegularChannelConfig(ADC3, ADC_Channel_8, 3, 
ADC_SampleTime_15Cycles);//neu

von bibu (Gast)


Lesenswert?

Ich sehe grad PB0 ist nicht im nut im ADC1,2 drin...

von Nils P. (ert)


Lesenswert?

Asche auf mein Haupt... der ADC_CommonInitStructure.ADC_DMAAccessMode 
ist nur für den Multimode interessant -.-

jetzt liegts an PortB, der kann nicht ADC3...

von bibu (Gast)


Lesenswert?

so ist das wohl mit dem PortB...
Hab mir gedacht, ich baue das Ganze einfach auf ADC1 um, weil das alle 
von den Pins unterstützen, aber Pustekuchen anscheinend... Hab alle 
relevanten Daten auf ADC1 geändert aber da macht er jetzt nichts mehr. 
Hmmm


#define ADC1_ADRESS ((uint32_t)0x4001204C)


  ADC_InitTypeDef       ADC_InitStructure;
  ADC_CommonInitTypeDef ADC_CommonInitStructure;
  DMA_InitTypeDef       DMA_InitStructure;
  GPIO_InitTypeDef      GPIO_InitStructure;

  /* Enable ADC1, DMA2 and GPIO clocks 
****************************************/
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2 | RCC_AHB1Periph_GPIOA, 
ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);


  /* DMA2 Stream0 channel0 configuration 
**************************************/
  DMA_DeInit(DMA2_Stream0);
  DMA_InitStructure.DMA_Channel = DMA_Channel_2;
  DMA_InitStructure.DMA_PeripheralBaseAddr =(uint32_t)ADC1_ADRESS;
  DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADC1ConvertedValue;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
  DMA_InitStructure.DMA_BufferSize = 3; //neu
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; 
//DMA_MemoryInc_Disable; //neu
  DMA_InitStructure.DMA_PeripheralDataSize = 
DMA_PeripheralDataSize_HalfWord;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
  DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
  DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
  DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
  DMA_Init(DMA2_Stream0, &DMA_InitStructure);
  DMA_Cmd(DMA2_Stream0, ENABLE);

  /* Configure ADC1 Channel12 pin as analog input 
******************************/
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3; 
//neu
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  /* ADC Common Init 
**********************************************************/
  ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
  ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
  ADC_CommonInitStructure.ADC_DMAAccessMode = 
ADC_DMAAccessMode_Disabled;     //Enable
  ADC_CommonInitStructure.ADC_TwoSamplingDelay = 
ADC_TwoSamplingDelay_5Cycles;
  ADC_CommonInit(&ADC_CommonInitStructure);

  /* ADC1 Init 
****************************************************************/
  ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
  ADC_InitStructure.ADC_ScanConvMode = ENABLE;//DISABLE;//neu
  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
  ADC_InitStructure.ADC_ExternalTrigConvEdge = 
ADC_ExternalTrigConvEdge_None;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_NbrOfConversion = 3;

  ADC_Init(ADC1, &ADC_InitStructure);

  /* ADC1 regular channel12 configuration 
*************************************/
  ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, 
ADC_SampleTime_3Cycles);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 2, 
ADC_SampleTime_3Cycles);//neu
  ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 3, 
ADC_SampleTime_3Cycles);


 /* Enable DMA request after last transfer (Single-ADC mode) */
  ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);

 // ADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE); //neu

  /* Enable ADC1 DMA */
  ADC_DMACmd(ADC1, ENABLE);

  /* Enable ADC1 */
  ADC_Cmd(ADC1, ENABLE);

  ADC_SoftwareStartConv(ADC1);

von DMA (Gast)


Lesenswert?


von bibu (Gast)


Lesenswert?

Danke.
Es war der DMA_Channel.

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.