Mikrocontroller und Digitale Elektronik
›
Thread
STM32F4 ADC 2 Channel DMA nur einer wird übertragen
B
bibu
Gast
05.11.2013 00:25
#3389686
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);
}
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
NP
Nils P.
(ert)
05.11.2013 13:06
#3390195
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;
B
bibu
Gast
05.11.2013 13:35
#3390242
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.
B
bibu
Gast
05.11.2013 15:14
#3390395
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
B
bibu
Gast
05.11.2013 15:19
#3390404
Ich sehe grad PB0 ist nicht im nut im ADC1,2 drin...
NP
Nils P.
(ert)
05.11.2013 15:24
#3390416
Asche auf mein Haupt... der ADC_CommonInitStructure.ADC_DMAAccessMode
ist nur für den Multimode interessant -.-
jetzt liegts an PortB, der kann nicht ADC3...
B
bibu
Gast
05.11.2013 23:02
#3391241
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);
D
DMA
Gast
05.11.2013 23:09
#3391250
B
bibu
Gast
05.11.2013 23:30
#3391284
Danke.
Es war der DMA_Channel.
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.
Noch kein Account?
Die Registrierung ist kostenlos und dauert nur eine Minute.
Jetzt registrieren