stm32 adc+dma hal
时间: 2025-02-25 15:27:46 浏览: 76
### STM32 ADC与DMA结合使用的HAL库实现
#### 初始化ADC配置
为了使STM32能够利用DMA进行高效的AD转换,在初始化阶段需完成必要的硬件资源设定。这包括但不限于时钟配置、GPIO引脚定义以及具体到ADC模块本身的参数调整[^1]。
```c
static void MX_ADC_Init(void)
{
/* USER CODE BEGIN ADC_Init 0 */
/* USER CODE END ADC_Init 0 */
ADC_ChannelConfTypeDef sConfig = {0};
/** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
*/
hadc.Instance = ADC1;
hadc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
hadc.Init.Resolution = ADC_RESOLUTION_12B;
hadc.Init.ScanConvMode = DISABLE;
hadc.Init.ContinuousConvMode = ENABLE;
hadc.Init.DiscontinuousConvMode = DISABLE;
hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc.Init.NbrOfConversion = 1;
if (HAL_ADC_Init(&hadc) != HAL_OK)
{
Error_Handler();
}
}
```
#### 配置DMA服务
紧接着是对DMA控制器的相关设置,确保其能按照预设的方式自动搬运由ADC产生的采样数据至指定存储区域。此过程涉及到了DMA流/通道的选择、传输方向的确立还有缓冲区地址指针等细节项的规划[^3]。
```c
static void MX_DMA_Init(void)
{
__HAL_RCC_DMA2_CLK_ENABLE();
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_HIGH;
hdma_adc1.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_adc1) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
__HAL_LINKDMA(&hadc,DMA_Handle,hdma_adc1);
}
/* Link ADC with its corresponding DMA channel */
__weak void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(adcHandle->Instance==ADC1)
{
/* Peripheral clock enable */
__HAL_RCC_ADC1_CLK_ENABLE();
/* ADC1 DMA Init */
MX_DMA_Init();
}
}
```
#### 启动DMA传输并接收数据
一旦上述准备工作就绪,则可通过调用`HAL_ADC_Start_DMA()`接口来触发实际的数据采集流程。该API接受三个参数——指向ADC句柄结构体实例的指针、用于保存结果数组首地址的位置变量以及预期读取样本数量。值得注意的是,这里采用循环模式(`DMA_CIRCULAR`)使得每次DMA操作完成后会自动重载起始位置继续新一轮的任务执行直至程序显式停止为止[^2]。
```c
uint16_t My_adcData[NUMBER_OF_SAMPLES]; // Define buffer to store sampled data points.
int main()
{
...
HAL_ADCEx_Calibration_Start(&hadc); // Perform initial calibration before starting conversions.
HAL_ADC_Start_DMA(&hadc, (uint32_t*)My_adcData, NUMBER_OF_SAMPLES);
while (1){
// Main loop can remain empty as long as we're using interrupt or circular DMA mode.
}
}
```
阅读全文
相关推荐


















