STM32G4 DMA ADC LL
时间: 2025-05-22 20:44:47 浏览: 14
### STM32G4 系列微控制器中使用 DMA 和 ADC 的低层 (LL) 库操作
在 STM32 微控制器家族中,DMA 控制器允许外设和存储器之间的数据传输无需 CPU 干预,从而提高系统的效率。对于 STM32G4 系列中的 ADC 使用 LL 库实现 DMA 数据传输,可以参考官方文档以及示例代码来理解其工作原理。
以下是基于 STM32CubeMX 工具生成的项目框架下如何配置并编写代码以实现 DMA 和 ADC 协同工作的说明:
#### 1. 配置 ADC 和 DMA
在 HAL/LL 层级开发环境中,通常需要完成以下初始化设置:
- **ADC 初始化**: 设置采样时间、分辨率以及其他参数。
- **DMA 初始化**: 将 DMA 请求绑定到指定的 ADC 外设通道,并定义目标缓冲区地址。
```c
// 定义用于存储 ADC 转换结果的数组
uint16_t adcBuffer[NUMBER_OF_ADC_CHANNELS];
void MX_DMA_Init(void)
{
__HAL_RCC_DMAMUX1_CLK_ENABLE(); // 启用 DMAMUX 时钟(如果适用)
hdma_adc.Instance = DMA1_Channel1; // 假设使用 DMA1 Channel1
hdma_adc.Init.Request = DMA_REQUEST_0;
hdma_adc.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_adc.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_adc.Init.MemInc = DMA_MINC_ENABLE;
hdma_adc.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
hdma_adc.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
hdma_adc.Init.Mode = DMA_CIRCULAR; // 圆形模式适合连续采集
hdma_adc.Init.Priority = DMA_PRIORITY_HIGH;
HAL_DMA_Init(&hdma_adc);
__HAL_LINKDMA(hadc, DMA_Handle, hdma_adc); // 绑定 ADC 到 DMA
}
void MX_ADC_Init(void)
{
hadc.Instance = ADC1;
LL_ADC_InitTypeDef ADC_InitStruct = {0};
ADC_InitStruct.Resolution = LL_ADC_RESOLUTION_12B;
ADC_InitStruct.DataAlign = LL_ADC_DATA_ALIGN_RIGHT;
ADC_InitStruct.ScanDirection = LL_ADC_SCAN_DIRECTION_FORWARD;
LL_ADC_Init(ADC1, &ADC_InitStruct);
}
```
上述代码片段展示了如何通过 `LL` 函数接口初始化 ADC 和 DMA[^1]。
#### 2. 开启转换过程
一旦完成了硬件资源的分配与初始化,可以通过调用特定函数触发 ADC 转换流程。这里展示了一个简单的启动方法:
```c
void StartADCTransfer(void)
{
/* Enable the peripheral clock */
__HAL_RCC_ADC_CLK_ENABLE();
/* Configure and enable channels */
LL_ADC_SetChannelSingleEnd(ADC1, LL_ADC_CHANNEL_4); // 假设使用第四个输入端口作为测试源
LL_ADC_SetSamplingTimeCommonChannels(ADC1, LL_ADC_SAMPLINGTIME_COMMON_1, LL_ADC_SAMPLETIME_2CYCLES_5);
/* Start conversion with DMA request enabled */
LL_ADC_StartCalibration(ADC1);
while(LL_ADC_IsActiveFlag_CAL(ADC1)) {} // Wait until calibration is finished
LL_ADC_Enable(ADC1);
LL_ADC_ClearFlag_EOS(ADC1); // 清除可能存在的标志位干扰
LL_ADC_REG_StartConversionSwStart(ADC1); // 手动软件方式开启一次新的测量周期
}
```
此部分逻辑确保了每次读取之前都进行了必要的校准动作,并且正式开始了由软件控制的第一轮扫描活动。
#### 3. 中断处理程序设计
为了及时响应来自外部设备的数据就绪信号或者错误情况报告,在中断服务子程序(ISR)内部应该加入适当的操作指令集:
```c
void DMA1_Channel1_IRQHandler(void)
{
if (__HAL_DMA_GET_FLAG(&hdma_adc, DMA_FLAG_TCIF1))
{
__HAL_DMA_CLEAR_FLAG(&hdma_adc, DMA_FLAG_TCIF1);
// Process data inside 'adcBuffer'
HandleNewADCMeasurements();
}
}
```
当检测到完整的事务完成后会执行回调机制通知应用程序层继续下一步骤处理已接收完毕的信息包。
---
###
阅读全文
相关推荐



















