[STM32L4] STM32L4 ADC+DMA 多通道采集异常

[复制链接]
10|0
咚了个咚 发表于 2026-6-27 16:42 | 显示全部楼层 |阅读模式
我用 STM32L476 的 ADC+DMA 采集多路传感器信号,一共 12 路通道。

仅配置 4 路通道(ADC1_IN1、IN6、IN7、IN8)时采集完全正常;

一旦通道数量增加到 6 路及以上,采样数据就会错乱:

通道 1 的采样值被通道 6 的数据覆盖,本该存放通道 6 数据的缓冲区位置为空、无有效数值。

下面是我的部分代码,工程是基于 NUCLEO-L476RG 开发板。

int main(void)

{



/* Reset of all peripherals, Initializes the Flash interface and the Systick. */

HAL_Init();

SystemClock_Config();

/* Initialize all configured peripherals */

MX_GPIO_Init();

MX_DMA_Init();

// MX_USART1_UART_Init();

MX_ADC1_Init();

/* Infinite loop */

/* USER CODE BEGIN WHILE */

while (1)

{ // if interruptted, indi_int = 1

if (indi_int == 1)

{

indi_int = 0;

HAL_GPIO_WritePin(GPIOE, GPIO_PIN_8, GPIO_PIN_SET);

HAL_ADC_Start_DMA(&hadc1,(uint32_t*)adcValue,BUF_SIZE*CHANNEL_COUNT); // start conversion

HAL_GPIO_WritePin(GPIOE, GPIO_PIN_9, GPIO_PIN_SET);

}



if (indi_led == 1)

{

HAL_UART_Transmit(&huart1,(uint8_t*)datastore1,BUF_SIZE,3000);

HAL_UART_Transmit(&huart1,(uint8_t*)datastore2,BUF_SIZE,3000);

HAL_UART_Transmit(&huart1,(uint8_t*)datastore3,BUF_SIZE,3000);

indi_led = 0;

HAL_UART_Transmit(&huart1,(uint8_t*)datastore4,BUF_SIZE,3000);

HAL_GPIO_WritePin(GPIOE, GPIO_PIN_9, GPIO_PIN_RESET);       

HAL_GPIO_WritePin(GPIOE, GPIO_PIN_8, GPIO_PIN_RESET);

indi_int = 0;

HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);

}

}

}



// transfer data from adcValue to the varibles for each channel

void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc)

{

        uint16_t tem_index=0;

        uint16_t data_num=0;

        for(tem_index=0;tem_index<BUF_SIZE/2;tem_index++)

        {

//HAL_GPIO_WritePin(GPIOE, GPIO_PIN_8, GPIO_PIN_SET);

data_num=tem_index*4; // 6 for 6-channel

datastore1[tem_index]=adcValue[data_num];

datastore2[tem_index]=adcValue[data_num+1];

datastore3[tem_index]=adcValue[data_num+2];

datastore4[tem_index]=adcValue[data_num+3];

//datastore5[tem_index]=adcValue[data_num+4];

//datastore6[tem_index]=adcValue[data_num+5];

        }

}



void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)

{

        uint16_t tem_index=BUF_SIZE/2;

        uint16_t data_num=0;

        for(tem_index=BUF_SIZE/2;tem_index<BUF_SIZE;tem_index++)

        {

data_num=tem_index*4; // 6 for 6-channel

datastore1[tem_index]=adcValue[data_num];

datastore2[tem_index]=adcValue[data_num+1];

datastore3[tem_index]=adcValue[data_num+2];

datastore4[tem_index]=adcValue[data_num+3];

//datastore5[tem_index]=adcValue[data_num+4];

//datastore6[tem_index]=adcValue[data_num+5];

//HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);

HAL_ADC_Stop_DMA(&hadc1);

indi_led = 1;

        }

}



/* ADC1 init function */

static void MX_ADC1_Init(void)

{

ADC_MultiModeTypeDef multimode;

ADC_ChannelConfTypeDef sConfig;



/**Common config

*/

hadc1.Instance = ADC1;

hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;

hadc1.Init.Resolution = ADC_RESOLUTION_8B;

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 = 4; // change to 6 for the 6-channel case

hadc1.Init.DiscontinuousConvMode = DISABLE;

hadc1.Init.NbrOfDiscConversion = 1;

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(__FILE__, __LINE__);

}



/**Configure the ADC multi-mode

*/

multimode.Mode = ADC_MODE_INDEPENDENT;

if (HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode) != HAL_OK)

{

_Error_Handler(__FILE__, __LINE__);

}



/**Configure Regular Channel

*/

sConfig.Channel = ADC_CHANNEL_1;

sConfig.Rank = 1;

sConfig.SamplingTime = ADC_SAMPLETIME_24CYCLES_5;

sConfig.SingleDiff = ADC_SINGLE_ENDED;

sConfig.OffsetNumber = ADC_OFFSET_NONE;

sConfig.Offset = 0;

if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)

{

_Error_Handler(__FILE__, __LINE__);

}



/**Configure Regular Channel

*/

sConfig.Channel = ADC_CHANNEL_6;

sConfig.Rank = 2;

if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)

{

_Error_Handler(__FILE__, __LINE__);

}



/**Configure Regular Channel

*/

sConfig.Channel = ADC_CHANNEL_7;

sConfig.Rank = 3;

if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)

{

_Error_Handler(__FILE__, __LINE__);

}



/**Configure Regular Channel

*/

sConfig.Channel = ADC_CHANNEL_8;

sConfig.Rank = 4;

if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)

{

_Error_Handler(__FILE__, __LINE__);

}


您需要登录后才可以回帖 登录 | 注册

本版积分规则

162

主题

171

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部
0