2021-01-05 07:30 AM
Hi, I am trying to read multiple ADC channels using DMA method. I am not able to read values. I am not sure what wrong i am doing.
/* ADC1 init function */
void MX_ADC1_Init(void)
{
ADC_ChannelConfTypeDef sConfig = {0};
/** Common config
*/
hadc1.Instance = ADC1;
hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
hadc1.Init.Resolution = ADC_RESOLUTION_12B;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc1.Init.LowPowerAutoWait = DISABLE;
hadc1.Init.ContinuousConvMode = ENABLE;
hadc1.Init.NbrOfConversion = 2;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc1.Init.DMAContinuousRequests = ENABLE;
hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;
hadc1.Init.OversamplingMode = DISABLE;
if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_3;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_2CYCLES_5;
sConfig.SingleDiff = ADC_SINGLE_ENDED;
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.Offset = 0;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_4;
sConfig.Rank = ADC_REGULAR_RANK_2;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
}
I tried with DMA and polling method as well but nothing seems working.
uint32_t value[2];
HAL_ADC_Start_DMA(&hadc1, value, 2); // start adc in DMA mode
//polling method
HAL_ADC_Start(&hadc1);
HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY);
value[0]= HAL_ADC_GetValue(&hadc1);
HAL_ADC_Stop(&hadc1);
HAL_ADC_Start(&hadc1);
HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY);
value[1]= HAL_ADC_GetValue(&hadc1);
HAL_ADC_Stop(&hadc1);
can anyone explain me what i am doing wrong and i am using DMAchannel 1for ADC1.
Thanks in advance.
2021-01-05 08:54 AM
Hi,
you need config DMA channel for ADC and too
sConfig.SamplingTime = ADC_SAMPLETIME_2CYCLES_5;
is low time, your measured signal with this need be very low impedance source.
Try bigger cycle number.
and your value array must be global volatile...
2021-01-05 10:04 AM
> uint32_t value[2];
Your data is 12 bits, so it's storing uint16_t values, not uint32_t values. Otherwise the DMA method should work. If not, post more details about the values you're getting vs the values you expect.
The polling method isn't going to work as written since you're converting two channels. There are ways to get it to work, but DMA is going to be better.
2021-01-06 07:00 AM
I tried with uint16_t but it is same i am getting 4095 as values all the time. Tried with diffrent sample cycles as well.
2021-01-06 07:28 AM
You dont write mcu type , but my ADC1 on F469 i connect to DMA2 Stream0
check datasheet about dma channels and peripherals pairs
2021-01-07 07:46 AM
I am using STM32l4R5 chip. I checked with DMA channel and peripherals pairs. everything should be as it is. I am not getting anything otherthan 0 or 4095.
I am using FreeRTOS in my application does it have any imapact.
2021-01-07 07:48 AM
Maybe stupid , but check with voltmeter on pins how value is here?
2021-01-07 08:13 AM
I recently encounter a similar issue, ADC value was stuck to the value of the first sample while my dma was supposed to run.
This was due to a wrong peripheral initialization sequence and was fixed by having the right : clock - gpio - dma - then adc -...
my two cents...
in main, as generated by CubeMX
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_ADC_Init();
MX_I2C1_Init();
MX_USART1_UART_Init();
MX_CRC_Init();
MX_TIM1_Init();
MX_TIM6_Init();
MX_I2C2_Init();
2021-01-08 02:51 AM
I have checked the pins and i have some voltage on it from range 100mV to 2.4 V range. I have peripheral initialization sequence like : clock - gpio - dma - then adc etc...
Still i can see only 4095 values on all channels.
2021-01-14 06:36 AM
I managed to get values other than 4095 after VREF+ pin to VREFBUF_OUT. I am able to read values with DMA but those values are not exactly same. For example i suppose to get 125 as RAW value then i am getting values from 150 to 400 range.
I tried internal Vrefint channel then i supposed to get 3.3V which is equal to 4095 arround but those values also fluctuating betwwen 2900 to 3980 ??
Any suggestions on what causing this kind of behaviour.