cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F030F4P6 - ADC 12b with DMA - 4 bits missing

maxime23
Associate
Posted on October 01, 2014 at 17:04

Hello Guys,

I'm starting a new simple project with the STM32F030F4P6 chip and some analog sensors.

In this project I need values from 3 channels from ADC1 (AN5:7) and send them to UART1. My problem is the value after the DMA transfer contain only the 8 first bit of the sample (4 Msb are missing). I try different DMA configurations, try another IDE (1st was CooCox, now I'm working with Keil µV5 but nothing change) .

ps. It work fine with ADC Res = 8 bit, but it's not enough for the application.

It also work in 12bit mode without DMA, but I need to read all channel in one ADC shot. 

Please follow below, maybe you'll have some suggestions

// To simplify tests I work with one channel

volatile unsigned short ADCConvertedValues[1];

void DMA1_Channel1_IRQHandler(void){

if(DMA_GetFlagStatus(DMA1_FLAG_TC1) != RESET){

STREAM_TRAME[3] =   ADCConvertedValues[0]&0xFF;

STREAM_TRAME[4] =   (ADCConvertedValues[0]&0x0F00)>>8;

DMA_ClearFlag(DMA1_FLAG_TC1);

}

}

void adc_init(void){

//DMA NVIC

InitNVIC.NVIC_IRQChannel = DMA1_Channel1_IRQn;

InitNVIC.NVIC_IRQChannelPriority = 2;

InitNVIC.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&InitNVIC);

DMA_DeInit(DMA1_Channel1);

InitDMA.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;

InitDMA.DMA_MemoryBaseAddr = (uint32_t)ADCConvertedValues;

InitDMA.DMA_DIR = DMA_DIR_PeripheralSRC;

InitDMA.DMA_BufferSize = 1;

InitDMA.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

InitDMA.DMA_MemoryInc = DMA_MemoryInc_Enable;

InitDMA.DMA_PeripheralDataSize = DMA_MemoryDataSize_HalfWord;

InitDMA.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;

InitDMA.DMA_Mode = DMA_Mode_Circular;

InitDMA.DMA_Priority = DMA_Priority_High;

InitDMA.DMA_M2M = DMA_M2M_Disable;

DMA_Init(DMA1_Channel1, &InitDMA);

DMA_Cmd(DMA1_Channel1, ENABLE);

DMA_ITConfig(DMA1_Channel1,DMA_IT_TC,ENABLE);

ADC_DMARequestModeConfig(ADC1,ADC_DMAMode_Circular);

ADC_DMACmd(ADC1,ENABLE);

// divide systemClock for ADCClock to optain 12MHz => 48M/4=12M

RCC_ADCCLKConfig(RCC_ADCCLK_PCLK_Div4);

ADC_StructInit(&InitAdc);

InitAdc.ADC_Resolution = ADC_Resolution_12b;

InitAdc.ADC_ContinuousConvMode = ENABLE;

InitAdc.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;

InitAdc.ADC_DataAlign = ADC_DataAlign_Right;

InitAdc.ADC_ScanDirection = ADC_ScanDirection_Upward;

ADC_Init(ADC1, &InitAdc);

ADC_ChannelConfig(ADC1,    ADC_Channel_7, ADC_SampleTime_239_5Cycles);

ADC_GetCalibrationFactor(ADC1);

ADC_Cmd(ADC1, ENABLE);

while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADEN));

ADC_StartOfConversion(ADC1);

}

After this, TIMx reload periodically one channel (ch2) of DMA1 to send data via UART1.

Samples are included in one array who contain START and END flags. There are no problems with the sending,

I get all fields of the array but STREAM_TRAME[4] always contain 0x00

___________________________________________________________

Extra testing :

With the source code bellow I obtain two bytes who contain the full sample

from de DMA but these datas are sometime wrong (I think the last bit of the LSB ans the 1 bit of the MSB are wrongs)

Please find enclosed a snapshot of data for this configuration.

volatile unsigned char ADCConvertedValues[2];

void DMA1_Channel1_IRQHandler(void){

if(DMA_GetFlagStatus(DMA1_FLAG_TC1) != RESET){

STREAM_TRAME[3] =   ADCConvertedValues[0];

STREAM_TRAME[4] =   ADCConvertedValues[1];

DMA_ClearFlag(DMA1_FLAG_TC1);

}

}

void adc_init(void){

...

DMA_DeInit(DMA1_Channel1);

InitDMA.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;

InitDMA.DMA_MemoryBaseAddr = (uint32_t)ADCConvertedValues;

InitDMA.DMA_DIR = DMA_DIR_PeripheralSRC;

InitDMA.DMA_BufferSize = 2;

InitDMA.DMA_PeripheralInc = DMA_PeripheralInc_Enable;

InitDMA.DMA_MemoryInc = DMA_MemoryInc_Enable;

InitDMA.DMA_PeripheralDataSize = DMA_MemoryDataSize_Byte;

InitDMA.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;

InitDMA.DMA_Mode = DMA_Mode_Circular;

InitDMA.DMA_Priority = DMA_Priority_High;

InitDMA.DMA_M2M = DMA_M2M_Disable;

DMA_Init(DMA1_Channel1, &InitDMA);

DMA_Cmd(DMA1_Channel1, ENABLE);

DMA_ITConfig(DMA1_Channel1,DMA_IT_TC,ENABLE);

ADC_DMARequestModeConfig(ADC1,ADC_DMAMode_Circular);

ADC_DMACmd(ADC1,ENABLE);

// divide systemClock for ADCClock to optain 12MHz => 48M/4=12M

RCC_ADCCLKConfig(RCC_ADCCLK_PCLK_Div4);

ADC_StructInit(&InitAdc);

InitAdc.ADC_Resolution = ADC_Resolution_12b;

InitAdc.ADC_ContinuousConvMode = ENABLE;

InitAdc.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;

InitAdc.ADC_DataAlign = ADC_DataAlign_Right;

InitAdc.ADC_ScanDirection = ADC_ScanDirection_Upward;

ADC_Init(ADC1, &InitAdc);

...

}

Best, 

Max 
0 REPLIES 0