1. ADC 是什么?
ADC(Analog-to-Digital Converter,模数转换器)的作用是:把连续变化的模拟电压转换成 MCU 能处理的数字值。
常见应用:读取电位器、光敏电阻、热敏电阻、电池电压等模拟信号。
2. ADC 转换过程
一次模数转换通常包括:
采样 → 保持 → 量化 → 编码 → 数字值
-
采样:在某个时刻获取模拟电压。
-
保持:在转换期间让电压保持稳定。
-
量化:把连续电压映射到有限个等级。
-
编码:输出对应的二进制数字。
3. 三个关键参数
| 参数 | 含义 |
|---|---|
| 分辨率 | ADC 可区分的最小电压变化。12 位 ADC 有 2^12 = 4096 个等级。 |
| 参考电压 | ADC 的测量基准。例如参考电压为 3.3V,通常可测量 0V 到 3.3V。 |
| 转换速率 | 每秒可完成的转换次数,单位常为 SPS。 |
以 12 位、3.3V 参考电压为例,每个等级约为:
3.3V / 4096 ≈ 0.806mV
注意:分辨率不等于精度。分辨率表示划分得有多细,精度表示测量值离真实值有多近。
4. RT-Thread ADC 设备模型
RT-Thread 使用统一接口屏蔽不同芯片 ADC 寄存器和驱动的差异:
应用程序
↓
ADC 设备管理接口
↓
ADC 设备驱动框架
↓
芯片 ADC 驱动
↓
硬件 ADC
驱动层需要适配 ADC 的使能、转换、获取分辨率和参考电压等操作,并注册为 adc0、adc1 等设备。
5. 常用 API
| 接口 | 作用 |
|---|---|
rt_device_find() |
根据名称查找 ADC 设备 |
rt_adc_enable() |
使能指定 ADC 通道 |
rt_adc_read() |
读取指定通道的原始采样值 |
rt_adc_disable() |
关闭指定 ADC 通道 |
6. 标准使用流程
查找 ADC 设备 → 使能通道 → 读取采样值 → 换算电压 → 关闭通道
示例:读取 adc1 的第 5 通道,并换算为毫伏。
#define ADC_DEV_NAME "adc1"
#define ADC_CHANNEL 5
#define ADC_BITS 12
#define VREF_MV 3300
rt_adc_device_t adc_dev;
rt_uint32_t raw_value;
rt_uint32_t voltage_mv;
adc_dev = (rt_adc_device_t)rt_device_find(ADC_DEV_NAME);
if (adc_dev != RT_NULL)
{
rt_adc_enable(adc_dev, ADC_CHANNEL);
raw_value = rt_adc_read(adc_dev, ADC_CHANNEL);
voltage_mv = raw_value * VREF_MV / (1U << ADC_BITS);
rt_kprintf("voltage: %d mV\n", voltage_mv);
rt_adc_disable(adc_dev, ADC_CHANNEL);
}
代码解析: rt_device_find() 查找名为 adc1 的 ADC 控制器,返回 RT_NULL 说明设备不存在;rt_adc_enable() 打开第 5 通道;rt_adc_read() 得到原始转换值。示例假设 ADC 为 12 位、参考电压为 3300mV,因此用 raw_value * 3300 / 4096 换算为毫伏。读取结束后调用 rt_adc_disable() 关闭通道。实际项目中应根据芯片和板卡的真实分辨率、参考电压修改宏定义。
电压换算公式:
实际电压 = 采样值 × 参考电压 / 2^分辨率位数
总结
ADC 用于把"电压"变成"数字"。在 RT-Thread 中,应用层只需掌握:
find → enable → read → convert → disable
这种统一的 ADC 设备接口,使同一套应用代码更容易迁移到不同的 MCU 平台。