ARM-10-I.MX6U ADC

一、ADC 基础概念

ADC(Analog to Digital Converter):模数转换器,把连续的模拟电压信号转换成离散的数字值。

I.MX6U 内部集成了 12位 ADC,最大分辨率 4096 个刻度(0~4095),参考电压一般为 3.3V。

精度计算:


二、ADC 相关寄存器

2.1 ADC_CFG --- 配置寄存器

名称 说明
bit1:0 MODE 转换精度:00=8位,01=10位,10=12位,11=16位
bit3:2 ADIV 时钟分频:00=1分频,01=2分频,10=4分频,11=8分频
bit4 ADLSMP 采样时间:0=短采样,1=长采样
bit6:5 ADSTS 长采样时间选择
bit7 ADHSC 高速转换:0=正常,1=高速
bit9:8 REFSEL 参考电压选择:00=内部VREFH/VREFL
bit10 ADTRG 触发方式:0=软件触发,1=硬件触发
bit11 AVGE 硬件均值使能
bit13:12 AVGS 均值采样数:00=4次,01=8次,10=16次,11=32次
bit15 OVRD 覆盖使能

代码中的配置:

复制代码
base->CFG = (0x2 << 2) | (0x3 << 0);
//           ↑ ADIV=2 → 4分频
//                        ↑ MODE=3 → 12位精度(实际12位用0x2,这里0x3在某些型号为16位)

注意 :I.MX6ULL 的 ADC 最高支持 12 位,MODE 设为 0x2 才是 12 位,0x3 在部分芯片为无效值或 16 位模式,读数需用 0xFFF 掩码取低 12 位。


2.2 ADC_GC --- 通用控制寄存器

名称 说明
bit0 ADACKEN 异步时钟输出使能
bit1 DMAEN DMA 使能
bit2 ACREN 比较范围使能
bit3 ACFGT 比较功能大于使能
bit4 ACFE 比较功能使能
bit5 AVGE 硬件均值使能
bit6 ADCO 连续转换使能:0=单次,1=连续
bit7 CAL 校准启动位:写1启动校准,校准完成后硬件自动清0

代码中的配置:

复制代码
base->GC = (0x01 << 0);    // 使能异步时钟
base->GC |= (0x01 << 7);   // 启动校准
while(base->GC & (1 << 7)); // 等待校准完成(CAL自动清0)

2.3 ADC_GS --- 通用状态寄存器

名称 说明
bit0 ADACT 转换状态:1=正在转换
bit1 CALF 校准失败标志:1=校准失败,需软件清零
bit2 AWKST 异步唤醒状态

代码中的使用:

复制代码
base->GS |= (0x01 << 1);   // 先清除上次可能残留的 CALF 标志
// ... 校准 ...
if(base->GS & (1 << 1))    // 校准后检查 CALF
    return -1;              // 校准失败

2.4 ADC_HC[n] --- 转换控制寄存器(每个通道一个)

名称 说明
bit4:0 ADCH 通道选择:0~15=对应输入通道,11111(0x1F)=禁用转换
bit7 AIEN 转换完成中断使能:0=关闭,1=使能

代码中的使用:

复制代码
base->HC[0] &= ~(1 << 0);  // 初始化时先清通道位
// ...
base->HC[0] |= (0x1f << 0); // 先写 0x1F 禁用
base->HC[0] = (0x1 << 0);   // 再选通道1(GPIO1_IO01对应ADC通道1)

触发机制:软件触发模式下,向 HC[n] 写入通道号就会立刻启动一次转换,这就是"写通道号 = 触发转换"。


2.5 ADC_HS --- 状态寄存器

名称 说明
bit0 COCO0 通道0转换完成标志:1=转换完成,读 R[0] 后自动清零

代码中的使用:

复制代码
while(!(base->HS & (1 << 0))); // 等待 COCO0=1 转换完成

2.6 ADC_R[n] --- 转换结果寄存器

名称 说明
bit11:0 D 转换结果(12位模式下低12位有效)

代码中的使用:

复制代码
adc_value = base->R[0] & 0xfff; // 取低12位

重要:读取 R[0] 这个动作会自动清除 HS 中的 COCO0 标志,为下次转换做准备。


三、初始化流程(对应手册图 Figure 13-5)

bash 复制代码
Reset
  ↓
Initialize ADC
  ├─ ADC_CFG:设置精度、分频、触发方式
  ├─ ADC_GC:使能时钟,启动校准(CAL=1)
  └─ ADC_HCn:配置通道(先写0x1F禁用)
  ↓
Check COCOn=1?  ──No──→ 等待(轮询 GC.CAL 位变0)
  │ Yes
  ↓
Read ADC_Rn to Clear COCOn Bit
  ↓
Continue(初始化完成)

对应代码:

cs 复制代码
int adc_init(ADC_Type *base)
{
    // 1. 配置引脚为模拟输入(GPIO1_IO01)
    IOMUXC_SetPinMux(IOMUXC_GPIO1_IO01_GPIO1_IO01, 0);
    IOMUXC_SetPinConfig(IOMUXC_GPIO1_IO01_GPIO1_IO01, 0x10b0);

    // 2. 配置通道0:先禁用(写0x1F),等初始化完再配置
    base->HC[0] &= ~(1 << 0);

    // 3. 配置 ADC:4分频 + 12位精度
    base->CFG = (0x2 << 2) | (0x3 << 0);

    // 4. 使能异步时钟
    base->GC = (0x01 << 0);

    // 5. 清除上次残留的校准失败标志
    base->GS |= (0x01 << 1);

    // 6. 启动硬件校准
    base->GC |= (0x01 << 7);

    // 7. 等待校准完成(CAL位自动清0)
    while(base->GC & (1 << 7));

    // 8. 检查校准结果
    if(base->GS & (1 << 1))
        return -1;  // 校准失败

    return 0;  // 校准成功
}

四、读取 ADC 值

cs 复制代码
unsigned short adc_read(ADC_Type *base)
{
    unsigned short adc_value = 0;

    // 1. 先写 0x1F 禁用当前通道(清空通道选择)
    base->HC[0] |= (0x1f << 0);

    // 2. 写入目标通道号(通道1),同时触发一次软件转换
    base->HC[0] = (0x1 << 0);

    // 3. 等待转换完成(COCO0=1)
    while(!(base->HS & (1 << 0)));

    // 4. 读取结果,取低12位(读操作同时清除 COCO0)
    adc_value = base->R[0] & 0xfff;

    return adc_value;
}

五、main.c 中的电压换算

cs 复制代码
data = adc_read(ADC1);

// 换算为电压(单位:mV,参考电压3.00V)
unsigned int adc_value = data * 300 / (4096 - 1);

// 打印:整数部分 / 小数部分(保留两位)
printf("data = 0x%x  value = %d.%02d\r\n",
       data,
       adc_value / 100,   // 整数部分(单位:V的百分位)
       adc_value % 100);  // 小数部分

换算逻辑:

cs 复制代码
电压(mV) = ADC值 × 参考电压(mV) / (2^12 - 1)
         = data × 3000 / 4095

代码里用 data × 300 / 4095,结果单位是"0.01V"
打印时 /100 得整数部分,%100 得小数后两位

例:data=2048 → 2048×300/4095 ≈ 150 → 打印 1.50 V

六、引脚配置说明

ADC 输入引脚必须配置为模拟输入模式,不能配置为普通 GPIO。

bash 复制代码
IOMUXC_SetPinMux(IOMUXC_GPIO1_IO01_GPIO1_IO01, 0);
// 第二个参数 0 = SION不使能(模拟输入不需要输入通路回读)

IOMUXC_SetPinConfig(IOMUXC_GPIO1_IO01_GPIO1_IO01, 0x10b0);
// 0x10b0 = 关闭上下拉、关闭施密特触发,适合模拟信号输入

GPIO1_IO01 对应 ADC1 的通道 1(ADCH=0x01)。


七、关键寄存器速查表

寄存器 关键位 功能
ADC_CFG bit1:0 MODE 转换精度(10=12位)
ADC_CFG bit3:2 ADIV 时钟分频
ADC_CFG bit10 ADTRG 触发方式(0=软件)
ADC_GC bit7 CAL 启动校准,完成后自动清0
ADC_GC bit6 ADCO 连续转换使能
ADC_GS bit1 CALF 校准失败标志(写1清零)
ADC_HC[n] bit4:0 ADCH 通道选择(写通道号=触发转换)
ADC_HC[n] bit7 AIEN 转换完成中断使能
ADC_HS bit0 COCO0 转换完成标志(读R[0]后自动清零)
ADC_R[n] bit11:0 D 转换结果(取低12位)

相关推荐
Suifqwu19 小时前
rk3576(6)之设备树下GPIO驱动
单片机·嵌入式硬件
三佛科技-1873661339721 小时前
国产替代新选择|替代STM32/APM32型号推荐(32位MCU)
stm32·单片机·嵌入式硬件
jghhh011 天前
基于TMS320F28033的20MHz手持式双踪袖珍示波器设计与实现
stm32·嵌入式硬件·51单片机
殷忆枫1 天前
基于STM32F103C8T6的R60AFD1毫米波雷达模块驱动设计
stm32·单片机·嵌入式硬件
披着羊皮不是狼1 天前
在 QEMU 上实现 ARM 裸机程序与底层原理解析
arm开发
somi71 天前
ARM-12-I.MX6U LCD
arm开发·单片机·嵌入式硬件·自用
bubiyoushang8881 天前
基于STM32的心电采集系统设计
stm32·单片机·嵌入式硬件
笨笨饿1 天前
26_为什么工程上必须使用拉普拉斯变换
c语言·开发语言·人工智能·嵌入式硬件·机器学习·编辑器·概率论
youcans_1 天前
【STM32-MBD】(18)Clarke / Park 坐标变换链路
stm32·单片机·嵌入式硬件·matlab·代码生成
F137298015571 天前
WD5208S 非隔离降压功率开关:集成650V MOSFET,220V降12V,5V,700MA
stm32·单片机·嵌入式硬件·51单片机