STM32F4 ADC 2 Channel DMA nur einer wird übertragen

Gast #3389686
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);
}
#3390195
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;
Gast #3390242
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.
Gast #3390395
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
Gast #3391241
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);

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren