文章目录
随着开发项目的累计,将ADC与DMA结合使用,可以实现高效的数据采集和处理。
一、STM32 ADC与DMA的结合使用
初始化ADC:
配置ADC的工作模式(单次转换或连续转换)、采样时间、分辨率等参数。对于需要连续采集的应用场景,应启用ADC的连续转换模式。
配置DMA:
设置DMA的源地址(ADC的数据寄存器地址)、目标地址(内存地址)、传输方向(从外设到内存)、传输长度及模式(单次传输或循环传输)。在ADC数据采集的应用中,通常选择循环传输模式,以实现数据的持续采集。
启动DMA传输:
在ADC启动转换后,DMA会自动从ADC的数据寄存器读取数据,并存储到指定的内存地址中。此时,CPU可以执行其他任务,无需参与数据传输过程。
中断处理(可选):
根据实际需求,可以配置DMA传输完成中断或ADC转换完成中断。当中断发生时,CPU执行相应的中断服务程序,处理已采集的数据。
二、示例代码
初始化
void MX_ADC1_Init(void)
{
ADC_ChannelConfTypeDef sConfig = {0};
/** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
/
hadc1.Instance = ADC1;
hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
hadc1.Init.Resolution = ADC_RESOLUTION_12B;
hadc1.Init.ScanConvMode = ENABLE;
hadc1.Init.ContinuousConvMode = ENABLE;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = 5;
hadc1.Init.DMAContinuousRequests = ENABLE;
hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
Error_Handler();
}
/* Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
*/
sConfig.Channel = ADC_CHANNEL_3;
sConfig.Rank = 1;
sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
//数据存储在ADC_Values
HAL_ADC_Start_DMA(&hadc1,(uint32_t *)ADC_Values,ADC_MAX_NUM);
}
GPIO设置
void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(adcHandle->Instance==ADC1)
{
/* USER CODE BEGIN ADC1_MspInit 0 */
/* USER CODE END ADC1_MspInit 0 /
/ ADC1 clock enable */
__HAL_RCC_ADC1_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/**ADC1 GPIO Configuration
PA3 ------> ADC1_IN3
/
GPIO_InitStruct.Pin = GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/ ADC1 DMA Init /
/ ADC1 Init /
hdma_adc1.Instance = DMA2_Stream0;
hdma_adc1.Init.Channel = DMA_CHANNEL_0;
hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_adc1.Init.MemInc = DMA_MINC_ENABLE;
hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
hdma_adc1.Init.Mode = DMA_CIRCULAR;
hdma_adc1.Init.Priority = DMA_PRIORITY_LOW;
hdma_adc1.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_adc1) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(adcHandle,DMA_Handle,hdma_adc1);
/ ADC1 interrupt Init /
HAL_NVIC_SetPriority(ADC_IRQn, 6, 0);
HAL_NVIC_EnableIRQ(ADC_IRQn);
/ USER CODE BEGIN ADC1_MspInit 1 */
/* USER CODE END ADC1_MspInit 1 */
}
}
中断设置
void ADC_IRQHandler(void)
{
HAL_ADC_IRQHandler(&hadc1);
}
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance == ADC1){
//转换完成判断
}
}
三、应用优势
STM32 ADC结合DMA方式读取数据的优势主要体现在以下几个方面:
高效性:
DMA传输无需CPU干预,可以显著提高数据传输效率。在高速数据采集的应用场景中,这一优势尤为明显。
减轻CPU负担:
由于DMA承担了数据传输的任务,CPU可以专注于执行其他更复杂的任务,从而提高了系统的整体性能。
灵活性:
通过灵活配置ADC和DMA的参数,可以满足不同应用场景的需求。例如,可以通过调整ADC的采样时间和分辨率来优化数据采集的精度和速度;通过选择DMA的传输模式和长度来控制数据传输的行为。
易用性:
STM32提供了丰富的库函数和工具链支持,使得ADC和DMA的配置和使用变得简单快捷。开发者可以通过图形化的配置工具(如STM32CubeMX)或编写简单的代码来实现复杂的数据采集和处理功能。
标签:DMA,HAL,STM32,Init,ADC,ADC1,hadc1 From: https://blog.csdn.net/u013050118/article/details/143016280