2021-03-26 08:13 PM
Hello everyone.
Recently I started to use LL library & STM32CubeIDE to do my project.
I'm trying to use DMA to transfer data which converted from ADC multiple channel from peripheral to memory.
the DMA data is total wrong, converted data is almost the same. I searched a lot, but I can't fix it.
the DMA data is fine when I convert single channel.
really need some help...
mcu f103ve
Scan conversion mode ON
Continuous conversion mode ON
Number of conversion 6
trigger by software
here is the code.
void MX_ADC1_Init(void)
{
/* USER CODE BEGIN ADC1_Init 0 */
/* USER CODE END ADC1_Init 0 */
LL_ADC_InitTypeDef ADC_InitStruct = {0};
LL_ADC_CommonInitTypeDef ADC_CommonInitStruct = {0};
LL_ADC_REG_InitTypeDef ADC_REG_InitStruct = {0};
LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
/* Peripheral clock enable */
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_ADC1);
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOC);
/**ADC1 GPIO Configuration
PC0 ------> ADC1_IN10
PC1 ------> ADC1_IN11
PC2 ------> ADC1_IN12
PC3 ------> ADC1_IN13
PC4 ------> ADC1_IN14
PC5 ------> ADC1_IN15
*/
GPIO_InitStruct.Pin = LL_GPIO_PIN_0|LL_GPIO_PIN_1|LL_GPIO_PIN_2|LL_GPIO_PIN_3
|LL_GPIO_PIN_4|LL_GPIO_PIN_5;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG;
LL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/* ADC1 DMA Init */
/* ADC1 Init */
LL_DMA_SetDataTransferDirection(DMA1, LL_DMA_CHANNEL_1, LL_DMA_DIRECTION_PERIPH_TO_MEMORY);
LL_DMA_SetChannelPriorityLevel(DMA1, LL_DMA_CHANNEL_1, LL_DMA_PRIORITY_LOW);
LL_DMA_SetMode(DMA1, LL_DMA_CHANNEL_1, LL_DMA_MODE_CIRCULAR);
LL_DMA_SetPeriphIncMode(DMA1, LL_DMA_CHANNEL_1, LL_DMA_PERIPH_NOINCREMENT);
LL_DMA_SetMemoryIncMode(DMA1, LL_DMA_CHANNEL_1, LL_DMA_MEMORY_INCREMENT);
LL_DMA_SetPeriphSize(DMA1, LL_DMA_CHANNEL_1, LL_DMA_PDATAALIGN_HALFWORD);
LL_DMA_SetMemorySize(DMA1, LL_DMA_CHANNEL_1, LL_DMA_MDATAALIGN_HALFWORD);
/* USER CODE BEGIN ADC1_Init 1 */
LL_DMA_ConfigAddresses(DMA1, LL_DMA_CHANNEL_1, LL_ADC_DMA_GetRegAddr(ADC1, LL_ADC_DMA_REG_REGULAR_DATA), (uint32_t)voltageRawValue, LL_DMA_DIRECTION_PERIPH_TO_MEMORY);
LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_1, 6);
LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1);
// my code here
/* USER CODE END ADC1_Init 1 */
/** Common config
*/
ADC_InitStruct.DataAlignment = LL_ADC_DATA_ALIGN_RIGHT;
ADC_InitStruct.SequencersScanMode = LL_ADC_SEQ_SCAN_ENABLE;
LL_ADC_Init(ADC1, &ADC_InitStruct);
ADC_CommonInitStruct.Multimode = LL_ADC_MULTI_INDEPENDENT;
LL_ADC_CommonInit(__LL_ADC_COMMON_INSTANCE(ADC1), &ADC_CommonInitStruct);
ADC_REG_InitStruct.TriggerSource = LL_ADC_REG_TRIG_SOFTWARE;
ADC_REG_InitStruct.SequencerLength = LL_ADC_REG_SEQ_SCAN_ENABLE_6RANKS;
ADC_REG_InitStruct.SequencerDiscont = LL_ADC_REG_SEQ_DISCONT_DISABLE;
ADC_REG_InitStruct.ContinuousMode = LL_ADC_REG_CONV_CONTINUOUS;
ADC_REG_InitStruct.DMATransfer = LL_ADC_REG_DMA_TRANSFER_UNLIMITED;
LL_ADC_REG_Init(ADC1, &ADC_REG_InitStruct);
/** Configure Regular Channel
*/
LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_1, LL_ADC_CHANNEL_11);
LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_11, LL_ADC_SAMPLINGTIME_1CYCLE_5);
/** Configure Regular Channel
*/
LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_2, LL_ADC_CHANNEL_10);
LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_10, LL_ADC_SAMPLINGTIME_1CYCLE_5);
/** Configure Regular Channel
*/
LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_3, LL_ADC_CHANNEL_10);
LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_10, LL_ADC_SAMPLINGTIME_1CYCLE_5);
/** Configure Regular Channel
*/
LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_4, LL_ADC_CHANNEL_10);
LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_10, LL_ADC_SAMPLINGTIME_1CYCLE_5);
/** Configure Regular Channel
*/
LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_5, LL_ADC_CHANNEL_10);
LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_10, LL_ADC_SAMPLINGTIME_1CYCLE_5);
/** Configure Regular Channel
*/
LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_6, LL_ADC_CHANNEL_10);
LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_10, LL_ADC_SAMPLINGTIME_1CYCLE_5);
/* USER CODE BEGIN ADC1_Init 2 */
LL_ADC_Enable(ADC1);
LL_ADC_StartCalibration(ADC1);
while(LL_ADC_IsCalibrationOnGoing(ADC1));
LL_ADC_REG_StartConversionSWStart(ADC1);
//my code here
/* USER CODE END ADC1_Init 2 */
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
for(int i = 0; i < 6; i++)
{
voltageValue[i] = __LL_ADC_CALC_DATA_TO_VOLTAGE(3300, voltageRawValue[i], LL_ADC_RESOLUTION_12B);
printf("%d ", voltageValue[i]);
}
printf("\n");
LL_mDelay(200);
// my code here
}
/* USER CODE END 3 */
}
2021-04-05 06:45 AM
Hi @NVoid.1 ,
Glad to know that your problem is fixed!
It will be interesting to share with other Community members the solution you found for the issue you were facing.
-Amel
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.