stm32adcdma采样
时间: 2025-05-18 12:27:40 浏览: 23
### STM32 ADC 使用 DMA 进行采样
在嵌入式开发中,STM32 微控制器支持通过直接存储器访问(DMA)来高效地处理模数转换器(ADC)的数据采集。这种方式可以显著减少 CPU 的负担并提高数据传输效率。
#### 配置 ADC 和 DMA 控制器
为了实现这一功能,首先需要初始化 ADC 模块以及配置相应的 DMA 请求通道。具体来说:
- **使能时钟**:确保为 ADC 及其关联的 GPIO 端口启用了外设时钟。
- **设置输入通道**:指定要读取模拟信号的具体引脚,并将其模式设定为模拟输入。
- **校准 ADC**:执行一次自检过程以保证测量精度。
- **启动连续转换模式**:允许持续不断地获取新的样本值直到停止命令下达为止。
- **绑定中断服务程序(可选)**:如果希望实时响应完成事件,则需注册对应的 ISR 函数地址给 NVIC 中断向量表项。
对于 DMA 方面的操作如下所示:
- **分配缓冲区空间**:定义一个数组用于保存即将传回的结果集。
- **创建描述符链表节点**:构建包含源地址、目标位置指针以及其他必要参数在内的结构体实例列表。
- **激活请求映射关系**:告知硬件每当有新数据可用时就触发特定编号的流/通道活动。
- **开启事务流程控制位开关**:最终确认整个机制处于工作状态之下。
下面给出一段简单的 C 语言代码片段作为示范[^1]:
```c
#include "stm32f4xx_hal.h"
#define BUFFER_SIZE 8 /* 缓冲大小 */
uint16_t adcValue[BUFFER_SIZE];/* 存储ADC采样结果 */
static void SystemClock_Config(void);
static void Error_Handler(void);
int main(void)
{
HAL_Init();
SystemClock_Config();
__HAL_RCC_GPIOA_CLK_ENABLE(); // Enable clock for GPIO port A
__HAL_RCC_ADC1_CLK_ENABLE(); // Enable clock for ADC1
ADC_ChannelConfTypeDef sConfig = {0};
static ADC_HandleTypeDef hadc1;
hadc1.Instance = ADC1;
hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
hadc1.Init.Resolution = ADC_RESOLUTION_12B;
hadc1.Init.ScanConvMode = DISABLE;
hadc1.Init.ContinuousConvMode = ENABLE;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = 1;
if (HAL_ADC_Init(&hadc1) != HAL_OK){
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_0;
sConfig.Rank = 1;
sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK){
Error_Handler();
}
// 初始化DMA
static DMA_HandleTypeDef hdma_adc1;
__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();
}
__HAL_LINKDMA(&hadc1,DMA_Handle,&hdma_adc1);
// 开始ADC-DMA循环采样
if(HAL_ADC_Start_DMA(&hadc1,(uint32_t*)adcValue,BUFFER_SIZE)!= HAL_OK){
Error_Handler();
}
while(1){}
}
void Error_Handler(){
while(1){};
}
```
这段程序展示了如何利用 HAL 库函数简化上述提到的各项任务。注意这里采用了环形模式 (`DMA_CIRCULAR`) 来不断更新 `adcValue[]` 数组内的数值而无需额外干预。
阅读全文
相关推荐


















