】嵌入式 ADC 原理及 IMX6ULL 实战开发)
文章目录前言一、ADC概念二、ADC的流程三、ADC滤波四、IMX6ULL中的ADC4.1 ADC原理框图4.2 相关寄存器HC0HSR0CFGGS4.3 ADC采集光敏电阻前言ADC 是单片机获取现实世界模拟信号的唯一核心接口是嵌入式设备感知物理世界的 “眼睛”。单片机 CPU 只能处理 0、1 数字信号但现实里温度、电压、位移、光照、压力都是连续变化的模拟量必须靠 ADC 转换成数字MCU 才能读取、计算、判断。ADC在嵌入式领域中的重要性不言而喻这篇文章将详细讲解ADC。一、ADC概念ADCAnalog-to-Digital Converter模拟到数字转换器。用于将连续变化的模拟信号转换为离散的数字信号以便数字系统如微处理器、微控制器等能够对其进行处理和分析。我们一般将其简称为模数转换器。模拟信号一般是指连续变化的电压信号其数值在一定范围内变化数字信号由一系列离散的数字表示只能取有限的值通常以二进制形式表示。DAC数模转换器DAC 是 ADC 的反向器件把单片机的数字量转换成连续模拟电压输出。二、ADC的流程模拟电压输入 → 采样保持 → 量化 → 数字量采样ADC将连续变化的模拟信号在一定时间间隔内进行取样。取样频率决定了每秒采集的样本数通常以赫兹Hz表示。采样过程通过保持并测量模拟信号在每个采样时间点的电压值来实现。量化采样得到的连续模拟信号经过量化转换为数字形式。量化是将每个采样值映射到一个离散的数字值的过程。这通常通过比较采样值与参考电压之间的差异并将其转换为数字表示。ADC量化的过程是相对于一个基准值的这个基准值称之为基准电压。一般采用逐次逼近法的ADC会先拿采用电压Vadc跟基准电压Vref的1/2进行比较如果VadcVref则结果为1否则结果为0。之后继续拿Vadc和Vref的1/4或Vref的3/4继续比较。这个过程有点像二分法每次比较都会使量化的结果逼近真实值。很明显比较的次数决定了测量的精度这个精度被称之为ADC的分辨率。ADC分辨率8bit、10bit、12bit、16bitDSP8bit0~25510bit0~102312bit0~4095逐次逼近法若待测电压小于比较电压输出1反之输出0分辨率有几位就比较几次。三、ADC滤波在adc采集过程中一定存在着一些微小波动因此滤波算法是必不可少的。均值滤波保存最近 N 次 ADC 采样数据求算术平均值作为输出高通滤波允许低频信号通过衰减高频噪声低通滤波和低通相反允许高频信号通过滤除缓慢变化的直流 / 低频分量卡尔曼滤波根据上一时刻状态用系统模型预测当前值同时计算预测误差四、IMX6ULL中的ADCI.MX6ULL内部具有两个ADC控制器。都是采用逐次逼近法设计的。每路ADC的分辨率可选分别为8/10/12位。 I.MX6ULL内部ADC具有自动校准功能因此能够保证更高的测量精度最大转换速率为1MHz即完成一次转换所需的时间最快只需要1us。 I.MX6ULL的ADC还具有硬件平均功能和比较功能大大方便了软件设计。我们实验所使用的开发板将基准电压设置为3.3V。每个ADC拥有10个通道这里的通道就是指输入的电压信号是从哪个引脚输入进来的意思。ADC1的10个引脚其实就是GPIO1_IO00~GPIO1_IO09这10个引脚。4.1 ADC原理框图IMX6ULL的时钟源可以是igpclk、igpclk/2和ADACK其中ADACK是IMX6ULL内部提供的时钟源只能提供给ADC外设使用这样做的目的是保证系统处于低功耗状态时ADC依旧能够运行。 ADACK的时钟默认为20MHz。我们后续也将adc时钟配置为ADACK。4.2 相关寄存器寄存器名全称核心功能ADCx_HC0Hard Channel 0通道0控制寄存器。选择ADC输入通道、开启转换完成中断。唯一支持软件触发的通道写通道号就启动ADC转换。ADCx_HSStatusADC状态标志位转换完成标志、比较结果标志查询ADC是否转换结束。ADCx_R0Result 0HC0对应的转换结果寄存器。ADC转换完成后原始采样数值存在这里读这个寄存器拿到ADC数字量。ADCx_CFGConfigurationADC全局配置分辨率12/10/8bit、采样周期、硬件平均次数AVGS、触发方式选择软件/硬件触发。ADCx_GCGlobal Control全局功能使能连续转换、DMA使能、硬件比较功能、硬件均值滤波使能、校准控制。ADCx_GSGlobal Status全局状态包含校准完成标志、比较事件标志。ADCx_CVCompare Value设置ADC阈值开启窗口比较当ADC结果大于/小于该值时触发事件用于电压上下限检测。ADCx_OFSOffset偏移校准给ADC采样值加上/减去固定偏移消除硬件零点误差。ADCx_CALCalibration硬件自校准。上电必须执行ADC校准CAL_CODE保存校准系数用来消除ADC本身失调误差。HC0HSR0CFGGS4.3 ADC采集光敏电阻引脚配置IOMUX 配置 GPIO1_IO01关闭上拉开启引脚保持作为 ADC 模拟输入引脚ADC 寄存器基础配置HC[0]关闭转换完成中断CFG配置硬件平均、采样时间GC使能 ADC 模块ADC 硬件自校准置GC bit7启动校准等待校准结束读取GS bit1判断校准成功与否ADC 采样读取向HC[0]写入通道号软件触发转换轮询HS转换完成标志读取R[0]得到 12bit 原始采样码电压换算电压 原始值 × 3.3V / 4096intadc1_calibration(void){ADC1-GC|(17);// 置位GC寄存器bit7启动ADC硬件自校准while((ADC1-GC(17))!0);// 等待bit7清零 → 校准操作完成if((ADC1-GS(11))0)// 判断GS全局状态寄存器bit1校准成功标志{return1;// bit10 → 校准成功}else{return0;// bit11 → 校准失败}}voidadc1_channel1_init(void){//引脚复用GPIO1_IO01 设置为普通GPIO后续作为ADC输入IOMUXC_SetPinMux(IOMUXC_GPIO1_IO01_GPIO1_IO01,0);//PAD电气配置PKE(1) 使能引脚保持PUE(0) 关闭内部上拉IOMUXC_SetPinConfig(IOMUXC_GPIO1_IO01_GPIO1_IO01,IOMUXC_SW_PAD_CTL_PAD_PKE(1));IOMUXC_SetPinConfig(IOMUXC_GPIO1_IO01_GPIO1_IO01,IOMUXC_SW_PAD_CTL_PAD_PUE(0));ADC1-HC[0]~(17);// HC0寄存器bit7清零关闭转换完成中断ADC1-CFG0;ADC1-CFG|(13)|(30);// CFG配置bit3、bit0~2// bit3: AVGS硬件均值(30):采样周期设置ADC1-GC0;ADC1-GC|(10);// GC bit0 ADC模块全局使能打开ADC电源// 调用校准函数打印校准结果printf(adc1_calibration()?calibration success\n:calibration failed\n);}// 获取ADC原始采样值unsignedshortadc1_get_origin_value(void){ADC1-HC[0]0;ADC1-HC[0]1;// HC0写入通道号1**软件触发ADC转换**while((ADC1-HS(10))0);// 查询HS状态寄存器bit0等待转换完成标志置1returnADC1-R[0]0xFFF;// 读取R0结果寄存器掩码0xFFF保留12bit数据}// 将原始ADC值换算电压 Vref3.3V12bit(0~4095)floatadc1_get_voltage(void){return(float)adc1_get_origin_value()*3.3/4095;}