1
前言
ADC模数转换器是STM32中最重要的外设之一,在许多场景都有非常广泛的运用。本期我们利用STM32的ADC外设配合DMA实现 高速率,定采样率
的ADC采样。这种配合DMA使用的情况适合于一段连续信号的采样。
根据奈奎斯特采样定律,ADC的采样率至少要是信号中最高频率的信号两倍才能顺利的重建信号,但是实际上,ADC的采样率可以在考虑缓存区的情况下尽可能的高,这样子可以帮助我们顺利的重建信号和信号处理。
2
硬件资源
本期我们使用的单片机为STM32G474(当然本文的所有流程其它系列的ST单片机均可以复刻),G4系列的模拟外设功能非常强大。
板载有5个ADC外设,7个高速比较器,4路DAC还有六个运算放大器,在这方面它远超其他系列的单片机。
它的板载运算放大器也十分的优秀也有非常多的功能可以使用。
其ADC最高支持2.4 MSps因此本期我们利用它来信号采集。
3
CubeMX配置
CubeMX配置主要有三个部分: ** ADC,DMA,定时器 **
在ADC中选择一个通道开启,并且打开ADC对应的DMA,DMA选择默认模式即可。由于ADC的位数是12位ADC,因此DMA的位宽选择为Half
Word即16位。
将ADC的触发模式更改为Timer3的事件触发。之后进行定时器的配置。
例如我们的主频是170MHZ,设置分频系数是170-1,计数值为10,这样子我们的定时器触发频率就是100KHZ.
之后将定时器触发输出修改为更新事件。
这样子每次定时器触发都会让ADC进行一次采集,就可以实现精准的采样率设置采集。
接着就可以生成我们的代码了。
4
具体代码
//全局uint16_t ADC_Buffer[1024];//ADC数据缓存区uint8_t Transmit;//传输完成标志位char tx_buffer[64]; // 用于存储格式化后的数据int len;HAL_TIM_Base_Start_IT(&htim3); HAL_ADC_Start_DMA(&hadc2,(uint32_t *)ADC_Buffer,1024); while (1) { /* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
/* 等待 ADC 转换完成 */ if(hadc2.DMA_Handle->State == HAL_DMA_STATE_READY) { HAL_ADC_Stop_DMA(&hadc2); for(int i = 0;i<1024;i++) { len = sprintf(tx_buffer,"A:%drn",ADC_Buffer[i]); HAL_UART_Transmit(&hlpuart1,tx_buffer,len,0xFF); } HAL_ADC_Start_DMA(&hadc2,(uint32_t *)ADC_Buffer,1024); } }
我们在主循环中利用轮询的方式检查DMA是否传输完成,传输完成之后将重启DMA传输。
可以看到正常的采集到了信号,接着我们接入一个方波或者正弦波信号。
用串口示波器就可以看到我们采集的波形了。
这种ADC+DMA的操作对一段数据的连续采样,并且采样率可以做的较高,也可以通过双通道DMA实现无缝采样,在处理第一段数据的时候,DMA可以在不消耗CPU资源的情况下采集第二段数据。
STM32G4的模拟外设极其强大,下一期我们介绍如何使用STM32实现DAC的波形输出。