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
数据