STM32·HAL库开发(十五)ADC模数转换——案例:ADC读取传感器值

目录

【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: 模拟看门狗中断
 

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

HAL ADC连续转换模式 Continuous Conversion Mode-优快云博客

STM32 HAL库 STM32CubeMX -- ADC_stm32cube 定时器触发adc_Dir_xr的博客-优快云博客

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

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

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

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


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

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

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

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

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

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

        隔离AD方案:

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

        差分AD方案:

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

        AD7606是否支持差分输入:

用AD7606实现8路单端或4路差分数模转换 - ADI 技术 - 电子技术论坛 - 广受欢迎的专业电子论坛!
请问AD7606能支持差分信号输入吗 - ADI 技术 - 电子技术论坛 - 广受欢迎的专业电子论坛!
求助:采集电流信号,可以不用差分电路吗(AD7606)? (amobbs.com 阿莫电子技术论坛)
https://bbs.21dianyuan.com/forum.php?mod=viewthread&tid=315769

        看过的一些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)芯片

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值