stm32f4的adc的DMA采样 标准库
时间: 2025-07-01 16:36:48 浏览: 11
### STM32F4 使用标准库实现 ADC 的 DMA 采样
为了在 STM32F4 上通过标准库实现 ADC 和 DMA 配合工作的功能,可以按照以下方法进行操作。以下是详细的说明以及代码示例。
#### 1. 初始化 ADC 模块
初始化 ADC 涉及多个步骤,包括启用时钟、设置分辨率、扫描模式和数据对齐方式等[^4]。这些配置可以通过修改寄存器来完成:
```c
void ADC_Init(void) {
// 启用 ADC1 的时钟
RCC->APB2ENR |= RCC_APB2ENR_ADC1EN;
// 设置 ADC 分辨率为 12 位
ADC1->CFGR &= ~ADC_CFGR_RES;
ADC1->CFGR |= ADC_CFGR_RES_12b;
// 启用扫描模式
ADC1->CFGR |= ADC_CFGR_SCAN_ENABLE;
// 数据右对齐
ADC1->CFGR |= ADC_CFGR_DATAALIGN_RIGHT;
// 设置 ADC 时钟预分频因子
ADC1->CFGR |= ADC_CFGR_CKMODE_EDGE;
// 校准 ADC 并启动它
ADC1->CR |= ADC_CR_ADEN | ADC_CR_ADDIS;
}
```
上述代码片段展示了如何通过直接访问寄存器的方式初始化 ADC 模块。
---
#### 2. 配置 DMA 控制器
DMA 是一种高效的数据传输机制,在此场景下用于将 ADC 转换后的结果自动存储到指定内存区域中。需要先初始化 DMA 控制器并将其绑定到 ADC 外设上。
```c
#define BUFFER_SIZE 10
uint16_t ADC_Buffer[BUFFER_SIZE];
void DMA_Init(void) {
// 启用 DMA1 时钟
RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN;
// 清除 DMA1_Stream1 的所有标志位
DMA1_Stream1->ICR = DMA_SxISR_GIF | DMA_SxISR_TCIF | DMA_SxISR_HTIF | DMA_SxISR_TEIF;
// 配置 DMA Stream1
DMA1_Stream1->PAR = (uint32_t)&(ADC1->DR); // 外设地址指向 ADC 数据寄存器
DMA1_Stream1->M0AR = (uint32_t)ADC_Buffer; // 内存地址指向缓冲区首地址
DMA1_Stream1->NDTR = BUFFER_SIZE; // 设置要传输的数据量
DMA1_Stream1->CR = DMA_SxCR_MINC | // 开启内存增量模式
DMA_SxCR_DIR_PERIPHERAL_TO_MEM |// 方向:外设 -> 内存
DMA_SxCR_PSIZE_16BIT | // 外设数据宽度为 16 位
DMA_SxCR_MSIZE_16BIT | // 内存数据宽度为 16 位
DMA_SxCR_PL_HIGH | // 设定优先级为高
DMA_SxCR_EN; // 启动 DMA 流程
}
```
在此部分中,`DMA_Init()` 函数负责配置 DMA 控制器的相关参数,并使其能够与 ADC 进行交互。
---
#### 3. 将 ADC 绑定至 DMA
当 ADC 和 DMA 均已正确初始化之后,还需要进一步建立两者之间的联系。具体来说,就是使能 ADC 的 DMA 请求功能[^1]。
```c
void Bind_ADC_with_DMA(void) {
// 启用 ADC 的 DMA 功能
ADC1->CFGR |= ADC_CFGR_DMNGT_SWSTART | ADC_CFGR_DMACFG_CONTINUOUS;
// 启动 ADC 并开启 DMA 转换请求
HAL_ADC_Start_DMA(&hadc1, (uint32_t*)ADC_Buffer, BUFFER_SIZE);
}
```
这里调用了 `HAL_ADC_Start_DMA()` 来启动基于 DMA 的连续 ADC 转换过程。
---
#### 4. 完整流程总结
完整的实现流程如下所示:
1. **初始化 ADC**:设置其工作模式(如分辨率、扫描顺序等)。
2. **初始化 DMA**:分配目标缓冲区并将该控制器连接到 ADC。
3. **关联二者**:激活 ADC 中的 DMA 支持选项。
4. **运行测试**:验证是否成功完成了预期数量的样本采集任务。
最终效果应满足每秒多次快速读取模拟输入电压的需求[^5]。
---
### 示例代码汇总
下面是综合以上各部分内容的一个简单例子:
```c
#include "stm32f4xx_hal.h"
#define BUFFER_SIZE 10
uint16_t ADC_Buffer[BUFFER_SIZE];
int main() {
// 系统时钟初始化
SystemClock_Config();
// 初始化 GPIO 口作为 ADC 输入端口
MX_GPIO_Init();
// 初始化 ADC
ADC_Init();
// 初始化 DMA
DMA_Init();
// 关联 ADC 和 DMA
Bind_ADC_with_DMA();
while (1) {
// 主循环可执行其他任务...
}
}
void ADC_Init(void) { /* ... */ }
void DMA_Init(void) { /* ... */ }
void Bind_ADC_with_DMA(void) { /* ... */ }
```
---
阅读全文
相关推荐


















