当前位置: 首页 > news >正文

ARM架构——ADC 模数转换器

目录

一、ADC 基础概念

二、逐次逼近型 ADC

三、关键概念解析

2.1 量程

2.2 分辨率

2.3 精度

2.4 实际应用选择指南

四、IMX6ULL 中的 ADC 模块

4.1 硬件配置

4.2 关键寄存器配置

五、驱动代码实现

5.1 自动校准函数

5.2 初始化函数

5.3 采样与电压转换函数

5.4 主函数集成测试

六、滤波算法选型与实现

6.1 滤波算法对比与选型

6.2 均值滤波优化实现

七、总结


一、ADC 基础概念

  • ADC (Analog-to-Digital Converter):模拟到数字转换器。它是一种电子设备或模块,用于将连续变化的模拟信号转换为离散的数字信号,以便数字系统(如微处理器、微控制器等)能够对其进行处理和分析。
  • 模拟信号:物理世界中连续变化的物理量(如温度、光线、压力等)
  • 数字信号:离散的、不连续的信号(计算机处理的0和1)
  • 传感器:一种能够探测、感知外部环境信息(如温度、光线、压力、运动等),并将这些信息转换成电信号(通常是电压或电流)的装置或器件。

ADC 工作流程:现实世界物理量 → 传感器 → 模拟电压 → ADC → 数字信号 → 数字系统

二、逐次逼近型 ADC

ADC有多种实现方式,其中逐次逼近型ADC在速度和精度间取得了良好平衡:

  • 速度:比双积分型 ADC 快得多
  • 精度:比 Flash 型 ADC 高得多

逐次逼近型 ADC 的核心是一个比较器(Comparator)和一套 “逐次逼近寄存器(SAR)” 逻辑。它的转换过程像一个 “猜数字游戏”:通过不断折半参考电压,逐步确定输入电压对应的二进制每一位(MSB到LSB)。

下图以8位ADC为例,展示了将3.8V模拟电压(参考电压5V)转换为数字信号的过程:

模数转换过程示例
  1. 初始化:将 8 位数字量的最高位设为 1(其余为 0),对应电压为 5V/2 = 2.5V,与输入模拟电压(如 3.8V)比较;
  2. 逐步逼近
    1. 2.5V < 3.8V → 保留最高位 1,次高位设为 1,对应电压2.5V + 1.25V = 3.75V;
    2. 3.75V < 3.8V → 保留次高位 1,第三位设为 1,对应电压3.75V + 0.625V = 4.375V;
    3. 4.375V > 3.8V → 第三位设为 0,第四位设为 1,对应电压3.75V + 0.3125V = 4.0625V;
    4. 重复此过程,直到 8 位全部判定完毕;
  3. 输出结果:最终 8 位数字量为11000100(十六进制 0xC2,十进制 194),换算为实际电压:
    1. 实际电压 = (采样值 / 2^ADC位数) × 参考电压
    2. 代入得:194 / 256 × 5V = 3.7890625V,与输入 3.8V 高度逼近。

三、关键概念解析

2.1 量程

  • 定义:ADC能够测量的输入电压范围
  • 决定因素:参考电压
  • 注意事项:输入电压超过量程会导致失真(削顶)或损坏器件

2.2 分辨率

  • 定义:指ADC的位数
  • 常见位数:8位ADC(256级)、10位ADC(1024级)、12位ADC(4096级)、16位ADC(65536级)
  • 计算:12位ADC的分辨率 = 3.3V / 4096 ≈ 0.8mV

2.3 精度

  • 定义:与测量结果的绝对准确性相关
  • 关键指标:偏移误差、增益误差、INL(积分非线性)、DNL(微分非线性)
  • 重要提示:高精度ADC价格更高,需根据实际需求选择

2.4 实际应用选择指南

  1. 量程选择:确保信号电压范围在ADC量程内
    • 信号太小 → 需先用运放放大
    • 信号太大 → 需用电阻分压
  2. 分辨率选择:根据需要的测量精度选择位数
    • 例:锂电池电压(3.0V-4.2V),12位ADC(4096级)足以满足需求
  3. 精度考量:对绝对准确性要求高的场合,需研究数据手册中的精度指标

四、IMX6ULL 中的 ADC 模块

4.1 硬件配置

特性参数
分辨率12位(0~4095)
通道数10路(ADC1_IN0 ~ ADC1_IN9)
参考电压外部引脚ADC_VREFH(通常接3.3V)
时钟源支持IPG时钟、异步时钟(ADACK)
附加功能硬件平均、自动校准、比较器、DMA支持

4.2 关键寄存器配置

寄存器名称核心功能实战配置(12 位、通道 1)
控制寄存器(ADCx_HC0)中断使能、采样通道选择AIEN=0(禁用中断)、ADCH=1(选择 ADC1_IN1)
状态寄存器(ADCx_HS)转换完成标志位(COCO0)等待 COCO0=1(表示转换完成)
数据寄存器(ADCx_R0)存储采样结果读取低 12 位(CDATA [0~11]),屏蔽高位无效数据
配置寄存器(ADCx_CFG)分辨率、时钟源、采样时间配置MODE=10(12 位)、ADICLK=11(异步时钟)
通用控制寄存器(ADCx_GC)校准启动、时钟使能CAL=1(启动校准)、ASYNC_CLK_EN=1(时钟使能)
通用状态寄存器(ADCx_GS)校准失败标志(CALF)CALF=0(校准成功),失败需写1清零

五、驱动代码实现

5.1 自动校准函数

校准是消除器件固有误差、提升采样精度的关键步骤,必须在初始化时执行:

int adc1_calibration(void) { ADC1->GS |= (1 << 1); // 清零CALF校准失败标志(写1清零) ADC1->GC |= (1 << 7); // 置位CAL位,启动校准 while ((ADC1->GC & (1 << 7)) != 0); // 等待校准完成(CAL位自动清零) if ((ADC1->GS & (1 << 1)) != 0) { return -1; // 校准失败 } else { return 0; // 校准成功 } }

关键逻辑:校准过程中需等待 CAL 位清零,校准失败后需重新初始化,避免带误差采样。

5.2 初始化函数

初始化流程包含引脚配置→寄存器配置→校准三大核心步骤:

void adc1_init(void) { // 1. 引脚配置:GPIO1_IO01复用为ADC1_IN1,禁用上拉 IOMUXC_SetPinMux(IOMUXC_GPIO1_IO01_GPIO1_IO01, 1); // 复用为ADC模式 IOMUXC_SetPinConfig(IOMUXC_GPIO1_IO01_GPIO1_IO01, IOMUXC_SW_PAD_CTL_PAD_PKE(1) | // 使能引脚保持器 IOMUXC_SW_PAD_CTL_PAD_PUE(0)); // 禁用上拉(ADC推荐配置) // 2. 寄存器配置:12位分辨率、异步时钟 ADC1->HC[0] &= ~(1 << 7); // 禁用转换完成中断 ADC1->CFG = 0; // 清空配置寄存器 ADC1->CFG |= (2 << 2); // MODE=10 → 12位分辨率 ADC1->CFG |= (3 << 0); // ADICLK=11 → 异步时钟(ADACK) ADC1->GC = 0; // 清空通用控制寄存器 ADC1->GC |= (1 << 0); // 使能异步时钟输出 // 3. 启动校准并打印结果 printf(adc1_calibration() == 0 ? "Calibration OK\n" : "Calibration Failed\n"); }

5.3 采样与电压转换函数

  • get_adc_value:触发采样并读取 12 位数字量;
  • get_adc_volt:根据核心公式将数字量转换为实际电压。
// 读取ADC采样值(12位,0~4095) unsigned short get_adc_value(void) { ADC1->HC[0] = 0; // 清空通道选择 ADC1->HC[0] |= (1 << 0); // 选择通道1,触发单次采样 while ((ADC1->HS & (1 << 0)) == 0); // 等待转换完成(COCO0=1) return ADC1->R[0] & 0xFFF; // 读取低12位有效数据 } // 转换为实际电压(参考电压3.3V) float get_adc_volt(void) { return get_adc_value() * 3.3 / 4096; // 核心公式 }

5.4 主函数集成测试

main.c 中初始化系统资源后,循环采样并打印电压值,直观验证 ADC 功能:

int main(void) { system_interrupt_init(); // 系统中断初始化 clock_init(); // 时钟初始化 beep_init(); led_init(); // 其他外设初始化 adc1_init(); // ADC初始化 float adc_volt = 0; while (1) { adc_volt = get_adc_volt(); // 读取电压 // 格式化打印(保留3位小数) int m = (int)(adc_volt * 1000) / 1000; int n = (int)(adc_volt * 1000) % 1000; printf("ADC Voltage: %d.%03dV\n", m, n); delay_ms(10); // 10ms采样间隔 } return 0; }

运行结果:串口将持续输出类似 ADC Voltage: 1.234V 的信息,反映传感器的实时电压变化。

六、滤波算法选型与实现

实际应用中,采样信号易受电源纹波、电磁干扰影响,导致数据波动。文档与图片中提到多种滤波算法,以下结合场景选型并实现优化。

6.1 滤波算法对比与选型

滤波算法核心原理适用场景优点缺点
均值滤波多次采样取平均值静态信号(如温度、光线)实现简单、抑制随机噪声响应慢、不适合动态信号
卡尔曼滤波基于概率模型动态修正误差动态信号(如运动物体速度、电流)响应快、精度高公式复杂、参数难调
低通滤波过滤高频噪声、保留低频信号电源纹波干扰严重的场景平滑效果好高频信号失真
高通滤波过滤低频噪声、保留高频信号缓慢漂移的信号(如压力传感器)抑制漂移静态信号误差大

6.2 均值滤波优化实现

在 get_adc_value 基础上扩展,采样 10 次取平均值,抑制随机噪声:

// 均值滤波:10次采样取平均 unsigned short get_adc_value_avg(void) { unsigned int sum = 0; for (int i = 0; i < 10; i++) { ADC1->HC[0] = 0; ADC1->HC[0] |= (1 << 0); while ((ADC1->HS & (1 << 0)) == 0); sum += ADC1->R[0] & 0xFFF; } return sum / 10; // 返回平均值,降低波动 }

七、总结

ADC 是嵌入式系统中连接模拟世界和数字世界的关键组件。在 ARM 架构的 IMX6ULL 处理器中,ADC 模块通过寄存器配置和驱动代码实现,可以方便地与各种传感器配合使用。

掌握 ADC 的使用,对于开发基于 ARM 架构的嵌入式系统至关重要。在物联网、工业控制、智能家居等应用中,ADC 都能发挥重要作用,帮助我们获取和处理各种物理世界的信息。

http://www.jsqmd.com/news/309996/

相关文章:

  • 免费降ai率工具有哪些?2026年亲测5个靠谱平台,这个真能把AI率降下去!
  • 2026年免费降ai率工具怎么选?亲测5个靠谱平台,这个真能把AI率降下去!
  • 【开题答辩全过程】以 基于ssm的电影推荐与分享平台的设计与实现为例,包含答辩的问题和答案
  • openzeppelin学习笔记
  • 详细介绍:GitHub 热榜项目 - 日榜(2025-11-14)
  • .NET 虚拟单体存储库 (VMR)架构演进、同步机制与统一构建策略
  • Kubernetes 中的 node/proxy GET 权限漏洞:实现远程代码执行(RCE)
  • springboot家教平台网站vue
  • springboot家电企业维修售后服务业务员业绩管理系统x6maf
  • springboot家电维修售后管理系统ur5mr
  • springboot旅游民宿预订管理系统的设计与实现vue
  • springboot汽车租赁系统故障上报保险 门店设计
  • 【开题答辩全过程】以 酒店管理系统的设计与实现为例,包含答辩的问题和答案
  • 【开题答辩全过程】以 基于微信小程序的社团管理系统的设计与实现为例,包含答辩的问题和答案
  • 【Linux】Makefile 基础 - 教程
  • ADC--模数转换器
  • Flutter for OpenHarmony 剧本杀组队App实战26:邀请好友功能实现
  • 大数据高可用架构:CAP定理与BASE理论的完美结合
  • 强烈安利自考AI论文工具TOP10:选对工具轻松过关
  • 我用200行代码手写了一个协程库,才真正理解了线程切换
  • springboot汽车美容保养管理系统vue
  • springboot计算机组成原理虚拟仿真实验系统
  • springboot评教高校在线教师教学学术能力评价系统
  • 〔重庆理工大学〕计算机网络实验指导书【实验一 双绞线的制作与测试】
  • 【课程设计/毕业设计】基于java-springboot某城市的地铁综合服务管理系统springboot的城市轨道交通安全管理系统【附源码、数据库、万字文档】
  • Java 学习笔记 --MyBatis 增强篇
  • 个人简历网站
  • 〔重庆理工大学〕计算机网络实验报告【实验一 双绞线的制作与测试】
  • TCN-LSTM回归+特征贡献SHAP分析+新数据预测+多输出附MATLAB代码
  • TCN-BiLSTM回归+特征贡献SHAP分析+新数据预测+多输出附MATLAB代码