蓝桥杯CT107D单片机实战:5分钟搞定PCF8591 ADC读取滑动变阻器电压(附完整代码)

张开发
2026/4/19 13:17:48 15 分钟阅读

分享文章

蓝桥杯CT107D单片机实战:5分钟搞定PCF8591 ADC读取滑动变阻器电压(附完整代码)
蓝桥杯CT107D单片机实战5分钟实现PCF8591 ADC读取与数码管动态显示在蓝桥杯单片机竞赛中PCF8591模数转换器的应用一直是高频考点。许多初学者面对I2C通信协议和ADC转换时容易陷入接线混乱、代码调试失败的困境。本文将用最直接的方式带你快速实现滑动变阻器电压读取与数码管动态显示的全流程。1. 硬件连接与核心原理1.1 PCF8591在CT107D开发板上的物理连接CT107D开发板已经将PCF8591芯片与STC15单片机通过I2C总线连接妥当。关键引脚对应关系如下芯片引脚开发板连接目标作用说明AIN3滑动变阻器Rb2模拟信号输入SDAP2^1I2C数据线SCLP2^0I2C时钟线注意实际比赛中常有选手误将SDA/SCL接反导致通信失败。请务必确认P2^0和P2^1的对应关系。1.2 ADC转换的数学原理PCF8591的8位ADC将0-5V电压线性转换为0-255的数字量。转换公式为V_actual (ADC_value * 5.0) / 255例如当ADC读数为127时实际电压约为2.49V读值为255时对应满量程5V2. 代码架构解析2.1 核心函数实现完整的工程包含三个关键文件├── main.c # 主逻辑与显示控制 ├── iic.c # I2C底层驱动 └── iic.h # 协议头文件ADC读取的核心操作流程发送设备地址(0x90)和通道选择命令(0x43)重新启动I2C并发送读地址(0x91)读取ADC数据字节停止I2C通信对应的代码实现unsigned char adc_pcf8591(void) { unsigned char temp; IIC_Start(); IIC_SendByte(0x91); // 读地址 IIC_WaitAck(); temp IIC_RecByte(); IIC_Ack(0); IIC_Stop(); return temp; }2.2 数码管显示优化技巧开发板使用74HC138译码器驱动8位数码管。显示函数需要注意动态扫描频率应保持在50Hz以上每位数码管点亮时间≤5ms显示数据前需要先消隐防止鬼影电压值显示建议采用以下格式// 示例显示2.5VADC值128 case 1: P0 shuzi1[2]; break; // 整数位带小数点 case 2: P0 shuzi[5]; break; // 小数位3. 常见问题排查指南3.1 硬件连接检查清单遇到无数据返回时按此顺序排查确认开发板供电正常5V LED亮起用万用表测量Rb2滑动变阻器两端电压是否随旋钮变化检查I2C上拉电阻开发板通常已内置4.7kΩ上拉示波器观察SCL/SDA波形应有清晰的时钟脉冲3.2 软件调试技巧在Keil中可通过以下方法快速定位问题// 在IIC_WaitAck()后添加调试语句 if(!IIC_WaitAck()) { P0 0x00; // 让所有LED亮起表示应答失败 while(1); }典型错误代码对照表现象可能原因解决方案数码管全暗138译码器使能端未配置检查P2^5-P2^7输出显示值不变化ADC通道选择错误确认发送0x43而非0x41数据跳动严重未进行软件滤波增加5次采样取平均4. 进阶应用扩展4.1 多通道轮询采集修改通道选择命令即可读取其他传感器// 光敏电阻通道 IIC_SendByte(0x41); // 热敏电阻通道需外接 IIC_SendByte(0x42);4.2 精度提升方案通过过采样实现10位有效分辨率#define OVERSAMPLE_TIMES 16 unsigned int adc_oversample(void) { unsigned long sum 0; for(int i0; iOVERSAMPLE_TIMES; i){ init_pcf8591(); sum adc_pcf8591(); delay(1); } return (sum OVERSAMPLE_TIMES/2) / OVERSAMPLE_TIMES; }实际测试发现当Rb2旋转到中间位置时原始方案可能有±3的跳动而采用过采样后波动范围缩小到±1以内。

更多文章