1、初始化
2、DMA设置
3、业务代码—DMA方式
一、
在 main 函数前面添加变量。其中 ADC_Value 作为转换数据缓存数组,ad1,ad2 存
储 PA0( 转换通道 0),PA1( 转换通道 1) 的电压值。
/* USER CODE BEGIN PV */
/* Private variables */
uint32_t ADC_Value[100];
uint8_t i;
uint32_t ad1,ad2;
/* USER CODE END PV */
二、
在 while(1) 前面以 DMA 方式开启 ADC 装换。 HAL_ADC_Start_DMA() 函数第二个参
数为数据存储起始地址,第三个参数为 DMA 传输数据的长度。
/* USER CODE BEGIN 2 */
HAL_ADC_Start_DMA(&hadc1, (uint32_t*)&ADC_Value, 100);
/* USER CODE END 2 */
由于 DMA 采用了连续传输的模式, ADC 采集到的数据会不断传到到存储器中(此处
即为数组 ADC_Value )。 ADC 采集的数据从 ADC_Value[0] 一直存储到 ADC_Value[99] ,然
后采集到的数据又重新存储到 ADC_Value[0] ,一直到 ADC_Value[99] 。所以 ADC_Value
数组里面的数据会不断被刷新。这个过程中是通过 DMA 控制的,不需要 CPU 参与。我
们只需读取 ADC_Value 里面的数据即可得到 ADC 采集到的数据。其中 ADC_Value[0] 为
通道 0(PA0) 采集的数据, ADC_Value[1] 为通道 1(PA1) 采集的数据, ADC_Value[2] 为通
道 0 采集的数据,如此类推。数组偶数下标的数据为通道 0 采集数据,数组奇数下标的
数据为通道 1 采集数据。
三、
在 while(1) 循环中添加应用程序,将采集的数据装换为电压值并输出。
/* USER CODE BEGIN 3 */HAL_Delay(500);for (i = 0, ad1 = 0, ad2 = 0; i < 100;){ad1 += ADC_Value[i++];ad2 += ADC_Value[i++];}ad1 /= 50;ad2 /= 50;printf("\r\n********ADC-DMA-Example********\r\n");printf("[\tmain]info:AD1_value=%1.3fV\r\n", ad1 * 3.3f / 4096);printf("[\tmain]info:AD2_value=%1.3fV\r\n", ad2 * 3.3f / 4096);
程序中将数组偶数下标数据加起来求平均值,实现均值滤波的功能,再将数据装换为电
压值,即为 PA0 管脚的电压值。同理对数组奇数下标数据处理得到 PA1 管脚的电压值。
同时 ADC 采样也可以采用我之前描述的采用定时器对其平滑滤波!
通常片上的 ADC 的精度往往达不到我们的要求,因为它的精度实在是太低了。有两
个替代方案:
1 、 SDADC, 这个是 STM32F373 上特有的功能, 16 位高速 ADC ,支持差分输入。掌
握难度较大。
2 、 ADS, 就是外置 ADC 。 能 做到 0.01mV 的精度!这类芯片只需要进行 SPI 通信操作,便可以获取 ADC 数据
参考: 【ADC-HAL库】DMA方式多通道采集_哔哩哔哩_bilibili