目录

【ADC概述】

        【ADC全称】

        【ADC性能指标】

        【ADC特性】

        【ADC通道】

        【ADC转换顺序】

        【ADC触发方式】

        【ADC转化时间】

        【ADC转化模式】 

        【电压转换】

【demo · ADC_MQ2】

【补充】


【ADC概述】

        【ADC全称】
        Analog-to-Digital Converter,指模拟 / 数字转换器

        ADC性能指标
        ●  量程:能测量的电压范围
        ●  分辨率:ADC能辨别的最小模拟量,通常以输出二进制数的位数表示,比如: 8 10、  12、16位等;位数越多,分辨率越高,一般来说分辨率越高,转化时间越长
        ●  转换时间:从转换开始到获得稳定的数字量输出所需要的时间称为转换时间

        ADC特性
        ●  12位精度下转换速度可高达1MHz
        ●  供电电压:V SSA : 0V V DDA 2.4V~3.6V
        ●  ADC输入范围:VREF- ≤ VIN ≤ VREF+
            
由VREF-、VREF+ 、VDDA 、VSSA、这四个外部引脚决定
            一般把VSSA 和VREF- 接地,把VREF+ 和VDDA 接3V3,则ADC 输入电压范围:0~3.3V
        ●  采样时间可配置,采样时间越长, 转换结果相对越准确 , 但是转换速度就越慢
        ●  ADC 的结果可以左对齐/ 右对齐方式存储在 16 位数据寄存器中(因为12位数据有16个坑)

        ADC通道

        总共2ADCADC1ADC2),每个ADC18个转换通道: 16个外部通道、 2个内部通道(温度传感器、内部参考电压)

        外部的16 个通道在转换时又分为规则通道和注入通道,其中规则通道最多有 16 路,注入通道最多有4路。如果在规则通道转换过程中,有注入通道插队,那么就要先转换完注入通道,等注入通道转换完成后,再回到规则通道的转换流程。
        规则组:正常排队的人
        注入组:有特权的人(军人、孕妇)

        ADC转换顺序】
        每个ADC只有一个数据寄存器, 16 个通道一起共用这个寄存器,所以需要指定规则转换通道的转换顺序。
        规则通道中的转换顺序由三个寄存器控制:SQR1 SQR2 SQR3 ,它们都是 32 位寄存器。 SQR 寄存器控制着转换通道的数目和转换顺序,只要在对应的寄存器位SQx 中写入相应的通道,这个通道就是第x 个转换。

        和规则通道转换顺序的控制一样,注入通道的转换也是通过注入寄存器来控制,只不过只有一个 JSQR寄存器来控制,控制关系如下:

        注入序列的转换顺序是从JSQx[ 4 : 0 ] x=4-JL[1:0] )开始。只有当 JL=4 的时候,注入通道的转换顺序才会按照JSQ1 JSQ2 JSQ3 JSQ4 的顺序执行。
        ADC触发方式】
        1. 通过向控制寄存器 ADC_CR2 ADON 位写 1 来开启转换,写 0 停止转换
        2. 也可以通过外部事件(如定时器)进行转换
        ADC转化时间】
        ADC挂载在 APB2 总线 PCLK2 上(最高72MHz),经过分频器得到 ADC 时钟( ADCCLK ),最高 14 MHz。分频因子由RCC 时钟配置寄存器RCC_CFGR 的位15:14 ADCPRE[1:0] 设置,可以是2/4/6/8 分频,注意这里没有1 分频
  转换时间=采样时间+12.5个周期 
        当ADCLK = 14MHZ(最高),采样时间设置为1.5 周期(最快),那么总的转换时间(最短)Tconv = (1.5 周期+ 12.5 周期)s / 14MHz= 14 周期= 1us

        一般我们设置PCLK2=72M,经过ADC 预分频器能分频到最大的时钟只能是12M(6分频),采样周期设置为1.5 个周期,算出最短的转换时间为1.17us,这个才是最常用的。
        注意采样周期要大于转换时间
        【ADC转化模式】 
        扫描模式
                关闭扫描模式:只转换ADC_SQRx或 ADC_JSQR 选中的第一个通道
                打开扫描模式:扫描所有被ADC_SQRx或 ADC_JSQR 选中的所有通道
        单次转换/ 连续转换
                单次转换:只转换一次
                连续转换:转换一次之后,立马进行下一次转换
【ADC校准】
        【电压转换】

        模拟电压经过ADC 转换后,是一个12 位的数字值,如果通过串口以16 进制打印出来的话,可读性比较差,那么有时候我们就需要把数字电压转换成模拟电压,也可以跟实际的模拟电压(用万用表测)对比,看看转换是否准确。

        我们一般在设计原理图的时候会把ADC 的输入电压范围设定在:0~3.3v,因为ADC 是12 位的,那么12 位满量程对应的就是3.3V,12 位满量程对应的数字值是:2^12。数值0 对应的就是0V。

        如果转换后的数值为X ,X 对应的模拟电压为Y,那么会有这么一个等式成立: 2^12 / 3.3 = X/ Y,=> Y = (3.3 * X ) / 2^12。

【demo · ADC_MQ2】

demo概述:读取MQ-2传感器数据

在 CubeMX_USART_NVIC 基础上进行修改

 

int main(void)
{
    uint32_t smoke_value = 0;

    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    MX_USART1_UART_Init();
    MX_ADC1_Init();

	HAL_UART_Receive_IT(&huart1, &buf, 1);
	printf("hello zzq\r\n");
	HAL_Delay(1000);
    while (1)
    {
        /* ADC关键代码 */
        HAL_ADCEx_Calibration_Start(&hadc1);        //校准ADC,不校准会导致ADC测量不准确
		HAL_ADC_Start(&hadc1); 						// 启动ADC单次转换
		HAL_ADC_PollForConversion(&hadc1, 50); 		// 等待ADC转换完成,超时时间50ms
		smoke_value = HAL_ADC_GetValue(&hadc1); 	// 读取ADC转换数据
		printf("smoke_value = %f\r\n", 3.3/4096 * smoke_value);	// 把数据转换为电压
		//printf("smoke_value = %d \r\n", smoke_value);
		HAL_Delay(500);
        /* ADC关键代码 */

		if(UART1_RX_STA & 0x8000)
		{
			printf("收到数据:");								// 把“”中的内容打印到串口
			printf("%s",UART1_RX_Buffer);						// 将收到的数据发送到串口
			//HAL_UART_Transmit(&huart1, UART1_RX_Buffer, UART1_RX_STA & 0x3fff, 0xffff);		// 将收到的数据发送到串口
			while(huart1.gState != HAL_UART_STATE_READY);		// 等待发送完成
			printf("\r\n");
			UART1_RX_STA = 0;																// 重新开始下一次接收
			memset(UART1_RX_Buffer,0,sizeof(UART1_RX_Buffer));	// 清空缓冲区
		}

注意:校准函数:HAL_ADCEx_Calibration_Start(&hadc1);

           在初始化之后,在start之前,可以写在   void MX_ADC1_Init(void)   的最后

【补充】

IN0~IN15: 16路12位ADC采样通道,外部模拟量信号输入

Temperature Sensor Channel: MCU内置温度传感器采样通道,用来测量器件周围的温度。在MCU内部与ADC1_IN16通道相连

Vrefint Channel: 内部参考电压检测通道,ADC 的参考电压都是通过 Vref+ 引脚提供的并作为ADC转换器的基准电压,当Vref+直接取自VDD电压时,易受VDD波动而影响,因此可以该通道对参考电压进行校准,以提升ADC计算精度。在MCU内部与ADC1_IN17通道相连

EXTI Conversion Trigger: 外部触发转换。
ADC转换可由外部事件触发,EXTSEL[2:0]和JEXTSEL[2:0]控制位允许应用程序选择8个可能的事件中的某一个,触发规则通道组合注入通道组的采样。这里若选择Disable,则可以在6个来自片上定时器的内部信号中选择一个作为触发源;
若选择Injected Trigger/Regular Trigger/Injected and Regular Trigger,表示由外部引脚信号触发相应的通道组。
 

ADCs_Common_Settings:(ADC模式设置)

Mode:Independent mode
独立模式。此模式中,双ADC同步不工作,ADC1和ADC2相互独立工作。
如果不需要ADC同步或者只是用了一个ADC的时候,应该设成独立模式,多个ADC同时使用时会有其他模式,如双重ADC同步模式,两个ADC同时采集一个或多个通道,可以提高采样率。对应ADC控制寄存器1(ADC_CR1)中的DUALMOD[3:0]位。

ADC_Settings:(ADC设置)

Data Alignment:(数据对齐方式)
数据左对齐/右对齐,一般选择使用右对齐。

Scan Conversion Mode:(扫描模式)
扫描模式使能。对应ADC控制寄存器1(ADC_CR1)中的SCAN位。
如果只是用了一个通道的话,设置为DISABLE;
如果使用了多个通道的话,可以选择设置ENABLE或者DISABLE;(后面结合具体场景介绍)

Continuous Conversion Mode:(连续转换模式)
数据的连续转换,对应ADC控制寄存器2(ADC_CR2)中的CONT位。
设置为ENABLE,即使能连续转换;设置为DISABLE,则是单次转换。
两者的区别在于连续转换直到所有的数据转换完成后才停止转换,而单次转换则只转换一次数据就停止,要再次触发转换才可以进行转换

Discontinuous Conversion Mode:(间断模式)
间断模式,对应ADC控制寄存器1(ADC_CR1)中的DISCEN位。
如果单通道不需要采用间断,多通道具体分析,后面示例中具体介绍

ADC_Regular_ConversionMode:规则通道组采样设置

Enable Regular Conversions:(常规转换模式)
使能规则通道组转换。

Number of Conversion:(转换通道数量)
规则通道组序列长度为3,即包含3个采样通道。

External Trigger Conversion Source:(外部触发转换源)
选择外部触发源,
Regular Conversion launched by software 规则的软件触发 调用函数触发
Timer X Capture Compare X event 外部引脚触发,
Timer X Trigger Out event 定时器通道输出触发

Rank:ADC转换通道顺序
当使用多通道采集的时候,可以在这里设置每个通道采集的先后顺序

ADC_Injected_ConversionMode:注入通道设置
参数和上面的规则通道一样;
需要注意的是,注入通道的功能和规则通道的一样,但是注入通道的优先级要比规则通道的高;

WatchDog: 模拟看门狗中断
 

        在CubeMX的ADC配置中,在Mode里有一个选项是EXTI Conversion Trigger,可选Regular Trigger。在Configuration里的ADC_Regular_ConversionMode中也有一个选项是External Trigger Conversion Source,可选项是Regular Conversion launchcd by software、Timer 3 Trigger Out event等,我想知道EXTI Conversion Trigger和External Trigger Conversion Source的作用分别是什么?有什么区别,尤其是EXTI Conversion Trigger的Regular Trigger和External Trigger Conversion Source的Timer 3 Trigger Out event我感觉作用很像?

配置项 作用 适用场景
EXTI Conversion Trigger 配置 外部中断(EXTI) 能否触发ADC转换(Regular或Injected模式) 外部信号(如按键、传感器)触发ADC采样
External Trigger Conversion Source 配置 硬件触发源(如Timer、输入捕获、输出比较等) 触发ADC Regular转换 的具体事件 定时器周期采样、PWM同步采样等

        Continuous Conversion Mode 设置为 Disable 时,除非HAL_ADC_Start(&hadc1);     写在while内,否则只采样一次,若写在while内则会循环采样,具体看下面的文章:

HAL ADC连续转换模式 Continuous Conversion Mode-CSDN博客

STM32 HAL库 STM32CubeMX -- ADC_stm32cube 定时器触发adc_Dir_xr的博客-CSDN博客

STM32L0 ADC使用HAL库关于校准问题的说明

【STM32】HAL库ADC测量精度提高方案(利用内部参考电压VREFINT计算VDDA来提高精度)-CSDN博客

【ADC常用滤波算法】

STM32十种常见采样滤波算法【限幅滤波法、中位值滤波法、算术平均滤波法等等】_哔哩哔哩_bilibili

1. 限幅滤波法(Limiter Filter)
        原理
:设置允许的最大偏差Δ,若相邻采样值差值>Δ则视为干扰,用前值替代。
        公式if |xₙ - xₙ₋₁| > Δ then xₙ = xₙ₋₁
        特点:简单快速,适合消除突发性脉冲噪声。
        缺点:无法处理缓变干扰。

2. 中位值滤波法(Median Filter)
        原理
:连续采样N次(N为奇数),取中间值作为输出。
        特点:对脉冲噪声抑制强,适合高干扰环境。
        缺点:需要排序运算,实时性较差(N较大时)。

3. 算术平均滤波法(Arithmetic Mean Filter)
        原理
:对N次采样取算术平均值。
        公式y = (x₁ + x₂ + ... + xₙ)/N
        特点:平滑随机噪声,适合稳定信号。
        缺点:降低响应速度,对突发噪声无效。

4. 滑动平均滤波法(Moving Average Filter)
        原理
:维护长度为N的队列,每次采样更新队列并计算均值。
        特点:实时性好,适合流式数据。
        缺点:需要存储N个数据,内存占用较大。

5. 中位值平均滤波法(Median-Average Filter)
        原理
:先取中值剔除异常点,再对剩余数据平均(如去掉最大/最小值后求平均)。
        特点:兼具抗脉冲干扰和噪声平滑能力。
        应用:工业传感器信号处理(如压力、温度)。

6. 限幅平均滤波法(Limiter-Average Filter)
        原理
:先限幅剔除超差数据,再对剩余数据平均。
        特点:综合限幅和平均的优点,适合含偶发干扰的信号。

7. 一阶滞后滤波法(First-Order Lag Filter)
        原理
:当前输出=α×当前输入 + (1-α)×前次输出(0<α<1)。
        特点:类似低通滤波,抑制高频噪声。
        缺点:产生相位滞后,α越小滞后越明显。

8. 加权递推平均滤波法(Weighted Moving Average)
        原理
:为历史数据分配递减权重(如指数加权)。
        公式yₙ = βxₙ + (1-β)yₙ₋₁
        特点:强调近期数据,适合时变信号。

9. 消抖滤波法(Debounce Filter)
        原理
:连续N次采样值相同才输出,否则保持原值。
        应用:按键检测、机械开关信号处理。

10. 限幅消抖滤波法(Limiter-Debounce Filter)
        原理
:先限幅判断是否跳变,再消抖确认稳定值。
        特点:抗干扰+防抖动,适合带噪声的阶跃信号。

具体实现:

5个通道,参考为14,去高低各2,余10取平均
对于5个通道(CH0~CH4)和14次采样,实际存储形式应为:

[CH0_1, CH1_1, CH2_1, CH3_1, CH4_1,  // 第1轮采样
 CH0_2, CH1_2, CH2_2, CH3_2, CH4_2,  // 第2轮采样
 ...
 CH0_14, CH1_14, CH2_14, CH3_14, CH4_14] // 第14轮采样

总数据量 = 5通道 × 14次 = 70个数据
数组索引计算:ADC_Value[采样序号][通道号] → 需重组为二维数组

数据重组与滤波实现
1. 定义DMA缓冲区

#define ADC_CHANNELS  5  // 5个通道
#define SAMPLE_SIZE   14 // 每个通道采样14次

uint32_t ADC_RawData[ADC_CHANNELS * SAMPLE_SIZE]; // DMA一维数组
uint32_t ADC_Sorted[ADC_CHANNELS][SAMPLE_SIZE];   // 重组后的二维数组

2. 重组数据(通道分离)

void Reorganize_ADC_Data(void) {
    for(int sample=0; sample<SAMPLE_SIZE; sample++) {
        for(int ch=0; ch<ADC_CHANNELS; ch++) {
            // 从交错数据中提取各通道独立序列
            ADC_Sorted[ch][sample] = ADC_RawData[sample * ADC_CHANNELS + ch];
        }
    }
}

3. 滤波(以通道0为例)

float Filter_Channel0(void) {
    uint32_t *ch_data = ADC_Sorted[0]; // 取通道0的14个数据
    
    // 冒泡排序(优化建议:使用快速排序)
    for(int i=0; i<SAMPLE_SIZE-1; i++) {
        for(int j=0; j<SAMPLE_SIZE-i-1; j++) {
            if(ch_data[j] > ch_data[j+1]) {
                uint32_t temp = ch_data[j];
                ch_data[j] = ch_data[j+1];
                ch_data[j+1] = temp;
            }
        }
    }
    
    // 去掉首尾各2个值,计算中间10个的平均
    uint32_t sum = 0;
    for(int i=2; i<SAMPLE_SIZE-2; i++) {
        sum += ch_data[i];
    }
    return (float)sum / (SAMPLE_SIZE-4);
}

【ADC的几种不同用法】

        ADC支持单次转换、循环转换、配合DMA一起使用,具体参考:
https://cloud.tencent.com/developer/article/1802304

【AD芯片与差分AD输入、隔离AD输入方案】

        ADC的不同输入模式:单端、伪差分、真差分


        ADC的单端输入、伪差分输入、差分输入区别?_差分adc-CSDN博客        [转载] 单端(Single-Ended)模式与差分(Differential)模式的区别_adc differential-CSDN博客

        部分单片机内部ADC有差分模式,部分没有。

        请教原子哥关于STM32的ADC是否支持差分输入?-OpenEdv-开源电子网

        STM32差分ADC采样的问题 (amobbs.com 阿莫电子技术论坛)

STM32F334 ADC差分应用问题怎么解决 - STM32/STM8技术论坛 - 电子技术论坛 - 广受欢迎的专业电子论坛!

        AD芯片:
        芯片之CL1606、AD7607-CSDN博客
        ADC芯片CS1238,CS1237介绍和代码-CSDN博客

        隔离AD方案:

隔离AD设计:先隔离后采样与先采样后隔离 (amobbs.com 阿莫电子技术论坛)

        差分AD方案:

【求助】求推荐一个多通道+差分+隔离ADC采集方案 (amobbs.com 阿莫电子技术论坛)

        AD7606是否支持差分输入:

用AD7606实现8路单端或4路差分数模转换 - ADI 技术 - 电子技术论坛 - 广受欢迎的专业电子论坛!
请问AD7606能支持差分信号输入吗 - ADI 技术 - 电子技术论坛 - 广受欢迎的专业电子论坛!
求助:采集电流信号,可以不用差分电路吗(AD7606)? (amobbs.com 阿莫电子技术论坛)
AD7606支持全差分输入吗-嵌入式系统与物联网技术-世纪电源网社区

        看过的一些AD芯片:

AD7606(亚德诺-ADI)_PDF_数据手册_Datasheet_规格书 - 半导小芯 | 8通道DAS,内置16位、双极性、同步采样ADC

AD7609(亚德诺-ADI)_PDF_数据手册_Datasheet_规格书 - 半导小芯 | 8 通道差分 DAS,采用 18 位双极同步采样 ADC

ADS1256(德州仪器-TI)_PDF_数据手册_Datasheet_规格书 - 半导小芯 | 适用于工厂自动化和过程控制且具有 PGA 的 24 位、30kSPS、8 通道 Δ-Σ ADC

TIL300(德州仪器-TI)_PDF_数据手册_Datasheet_规格书 - 半导小芯 | PRECISION LINEAR OPTOCOUPLER

CS1237(芯海-Chipsea)_PDF_数据手册_Datasheet_规格书 - 半导小芯 | 24-bit Sigma-Delta ADC

LH001-55(领慧立芯-Legendsemi)_PDF_数据手册_Datasheet_规格书 - 半导小芯 | 集成 PGA 功能和内部基准的 24-位模数转换器

MCT1256(模数智芯-MAGICORE)_PDF_数据手册_Datasheet_规格书 - 半导小芯 | 低噪声,24Bit ADC

SCA7606(智芯微-SMARTCHIP)_PDF_数据手册_Datasheet_规格书 - 半导小芯 | 8通道,16bit,200ksps,双极性输入,同步采样模拟数字转换器(ADC)芯片

Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐