ADC采集是平时非常常用的一个功能,以STM32407为例,其内部有三个12位ADC,每个ADC最高采样率可达2.4MSPS,支持多个通道采集。ADC的工作模式有很多种,包括独立模式、交替采样、多通道扫描等,可通过软件触发或定时器触发采样。本篇文章介绍一种比较常规的使用方式。


前期准备

  • STM32硬件电路板及仿真器(以STM32F407单片机为例)
  • Keil v5以上版本(MDK-ARM)
  • 串口调试助手


实现功能

STM32的ADC通过DMA采样一个直流电压,并将电压值并通过串口发送到上位机。

STM32CubeMX配置

首先,时钟等的配置参考之前文章的介绍(​​STM32CubeMX之GPIO的使用​​​)。串口配置参考​​STM32CubeMX之串口通信​​。ADC配置如下:

STM32CubeMX之ADC采集_内存地址

选择开启ADC1的通道0(IN0),配置该通道的参数:

  1. Mode为独立模式,因为只用了一个ADC,所以只能是独立模式。
  2. ADC时钟分频系数为2,该时钟的设置与采样率有关,12位分辨率时,15个ADC时钟周期完成一次采样。
    本例中PCLK2时钟频率的42MHz,2分频后为21MHz,采样率Fs = 21MHz/15=1.4MHz。
  3. 分辨率设置为12位,也可以选择10位、8位或6位。
  4. 数据对齐方式为右对齐,即12为AD数据占用16为数据的低12位。
  5. 扫描模式为Disable,因为只有1个通道,不需要扫描。
  6. 连续转换为Enable,即ADC完成一次转换后自动开始下一次转换。
  7. 开始DMA传输。
  8. 通道数为1,
  9. 触发模式为软件触发,因为已经设置连续转换,因此只需要触发一次即可。
    触发模式可以选择定时器触发,这样可以根据定时器设定采样的周期。
  10. 其它参数没有用到,暂不作介绍。
    设置ADC的DMA传输:

STM32CubeMX之ADC采集_内存地址_02

外设地址不自增,内存地址自增。外设地址即为ADC地址,不会变,内存地址一般为一个数值,DMA向内存传输一个数据后,内存地址自动加1,下次传输到下一个地址。


传输模式为循环传输,即内存地址自增到结尾后,从第一个地址重新开始传输。

数据宽度为Half Word,即2字节。


编写程序

设置完成后点击生成代码,初始化部分已经自动生成,用户只要添加ADC采样和串口发送代码就行。

启动ADC采样:


HAL_ADC_Start_DMA(&hadc1,(uint32_t*)ADC_Buf,ADC_LENGHT);//启动ADC采样 DMA传输到ADC_Buf数组

转换为电压并通过串口发送出去。因为已经启动DMA传输,AD转换的值已经自动循环存储到ADC_Buf中。对于实时性要求不高的直流信号,直接从ADC_Buf中读取数据,求平均值作为最终的转换结果即可。程序如下:



void Get_Volt_Send()
{
uint32_t ADCValue = 0;
uint16_t volt;
char str[10];

for(uint16_t i=0;i<ADC_LENGHT;i++)
{
ADCValue += ADC_Buf[i];
}
ADCValue = ADCValue/ADC_LENGHT;//求平均值
volt = ADCValue * 3300 / 4096;//转换为电压 单位mV,参考电压3300mV,12位AD对应4096
sprintf(str,"%4dmV\r\n",volt);
HAL_UART_Transmit_DMA(&huart1,(uint8_t*)str,8);//串口发送
}

上位机打开串口助手查看结果:

STM32CubeMX之ADC采集_数据_03


至此,一个简单的AD应用已经完成。如果需要采样高速的交流信号,可通过外部定时器触发,设置固定的采样率进行采样,采用双缓冲乒乓操作的方式进行采样和数据处理,这里不做详细介绍。