基于HAL库的DMA+ADC简单应用

本文介绍了如何在Cubemx中正确配置ADC的Rank和Channel,以及使用DMA进行数据采集,并在KEIL5中设置变量存储ADC数据,通过HAL_ADC_Start_DMA函数实现DMA传输,最后通过串口发送采样数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

cubemx配置

ADC:记得rank和channel要选择好,rank1对Chanel1,rank2对channel2.

我之前就是因为眼花了,搞到rank1、2都采样了channel1。

DMA:添加ADC1的通道,模式Circular,勾选内存地址自增,都是半字长。

KEIL5配置:

变量:两个成员的uint6_t数组 ,分别存储ADC1的channel1和channel2读取到的数据

初始化:HAL_ADC_Start_DMA()函数。

主循环:通过串口发送采样数据

实验现象:持续发送数据

### STM32 HAL ADC Timer DMA FFT 示例代码 为了实现ADC与定时器、DMA以及FFT的协同工作,在STM32上可以采用如下方法: #### 初始化配置 初始化过程中,需确保ADC模块能够按照指定的时间间隔启动转换操作,并通过DMA自动传输数据到存储区。同时,还需准备用于FFT处理的数据缓冲区。 ```c // 定义全局变量保存采样点数和FFT长度 #define SAMPLE_POINTS 1024 float32_t adcBuffer[SAMPLE_POINTS]; // 存储原始ADC样本值 float32_t fftInput[SAMPLE_POINTS*2]; // FFT输入数组, 实部+虚部 uint8_t isConversionComplete = 0; // 转换完成标志位 void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_DMA_Init(void); static void MX_ADC1_Init(void); static void MX_TIM6_Init(void); int main(void){ /* Reset of all peripherals, Initializes the Flash interface and Systick. */ HAL_Init(); /* Configure the system clock */ SystemClock_Config(); /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_DMA_Init(); // 初始化DMA控制器 MX_ADC1_Init(); // 初始化ADC外设 MX_TIM6_Init(); // 设置定时器作为触发源 // 启动ADC连续模式下的DMA请求 if (HAL_ADC_Start_DMA(&hadc1, (uint32_t*)adcBuffer, SAMPLE_POINTS) != HAL_OK){ Error_Handler(__FILE__, __LINE__); } while(1){ if(isConversionComplete){ // 当一次完整的序列采集完毕时 memcpy((char *)fftInput, (const char *)adcBuffer, sizeof(float32_t)*SAMPLE_POINTS); arm_cfft_radix4_f32(&fftInstance, fftInput); // 执行快速傅里叶变换 // 对于后续的结果解析... isConversionComplete = 0; } // 其他任务... } } ``` 上述代码片段展示了如何基于HAL构建基本框架[^1]。这里定义了一个`adcBuffer[]`用来接收来自ADC的实际读数值;而另一个更大的数组`fftInput[]`则专门服务于FFT算法所需的复数表示法——其中前半部分存放实部(即实际测量所得电压),后半部分预留给零填充构成对应的虚部。 当所有的采样都完成后,会触发中断服务例程ISR更新状态标记`isConversionComplete=1`,从而允许主线程继续执行下一步骤的操作,比如调用ARM CMSIS DSP Library中的`arm_cfft_radix4_f32()`来进行频域分析[^2]。 #### 中断回调函数 每当一组新的ADC样品准备好之后就会触发这个回调事件处理器,它负责通知应用程序层已经完成了必要的准备工作以便进一步处理这些新获得的信息。 ```c /* ADC conversion complete callback in non blocking mode */ void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc){ if(hadc->Instance==ADC1){ isConversionComplete = 1; } } ``` 这段简单的逻辑确保了只有当全部预期数量的模拟量都被成功数字化并转移到目标位置以后才会激活相应的指示符,进而促使主循环内的条件分支得以满足去发起下一轮更深层次的数据挖掘活动。 #### 关键注意事项 - **时序同步**:考虑到实时性和精度的要求,建议仔细调整各个组件之间的工作节奏,特别是要保证ADC采样的速率既不会过低影响最终效果也不会过高超出硬件承受范围。 - **资源分配**:合理规划RAM空间对于嵌入式开发至关重要,尤其是在涉及到大量浮点运算的情况下更是如此。应尽可能优化内存布局减少不必要的浪费。 - **错误检测机制**:尽管示例中省略了一些异常情况的捕捉流程,但在真实项目里务必要加入完善的保护措施防止意外状况的发生造成不可预见的问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

毛毛洋2022

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值