我用 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__);
}
|
|