蓝桥杯单片机备赛:用STC15F2K60S2和PCF8591做个简易光照计(附完整代码)
2026/4/24 10:19:13 网站建设 项目流程

蓝桥杯单片机备赛实战:基于STC15F2K60S2的光照测量系统开发指南

在电子设计竞赛中,光照测量系统是一个经典且实用的项目。对于参加蓝桥杯单片机赛项的选手来说,掌握如何将光敏传感器、ADC转换和数码管显示这些模块有机整合,不仅能帮助你在比赛中获得好成绩,更能提升实际工程开发能力。本文将从一个竞赛评委的角度,分享如何构建一个专业级的光照测量系统。

1. 系统架构设计与评分要点

蓝桥杯电子类竞赛评分通常关注三个核心维度:功能完整性、代码规范性和创新性。一个优秀的光照测量系统应该具备清晰的模块划分:

  • 传感器层:光敏电阻信号采集
  • 数据处理层:PCF8591 ADC转换与数值处理
  • 显示层:数码管动态显示
  • 控制层:STC15F2K60S2主控调度

竞赛小贴士:评委通常会检查代码的模块化程度,建议将不同功能封装成独立.c/.h文件

下表展示了典型评分标准分布:

评分项权重考察要点
功能完整性40%测量精度、显示稳定性
代码规范性30%注释质量、模块化设计
系统稳定性20%抗干扰能力、响应速度
创新性10%算法优化、附加功能

2. 硬件电路设计与关键元件选型

2.1 光敏电阻接口设计

光敏电阻的线性度直接影响测量精度。推荐使用分压电路设计:

Vcc ──┬── [R1固定电阻] ──┬── ADC输入 │ │ └── [光敏电阻] ──┴── GND

典型参数配置:

  • R1选择10kΩ(与光敏电阻暗电阻匹配)
  • 添加0.1μF滤波电容
  • PCF8591参考电压Vref=5V

2.2 PCF8591配置技巧

PCF8591的I2C地址为0x90,四个模拟输入通道中:

  • AIN0(0x00):通常接电位器
  • AIN1(0x01):推荐用于光敏电阻
  • AIN2(0x02):可用于温度传感器
  • AIN3(0x03):保留备用
// 读取指定通道AD值 unsigned char PCF8591_Read(unsigned char channel) { unsigned char val; IIC_Start(); IIC_SendByte(0x90); // 器件地址+写 IIC_WaitAck(); IIC_SendByte(channel); // 控制字节 IIC_WaitAck(); IIC_Stop(); IIC_Start(); IIC_SendByte(0x91); // 器件地址+读 IIC_WaitAck(); val = IIC_RecByte(); IIC_Stop(); return val; }

3. 软件架构优化与竞赛级代码编写

3.1 模块化工程结构

推荐采用以下文件结构:

project/ ├── main.c // 主循环和中断 ├── hardware/ │ ├── pcf8591.c // ADC驱动 │ ├── digital.c // 数码管驱动 │ └── i2c.c // I2C底层 ├── algorithm/ │ └── filter.c // 数据处理 └── inc/ // 头文件目录

3.2 数码管显示优化

动态扫描数码管时需注意:

  • 刷新率保持在50-100Hz(每位数码管1-2ms)
  • 消隐处理防止鬼影
  • 亮度均匀性调整
// 数码管显示缓冲 unsigned char disp_buf[8] = {0}; // 定时器中断服务程序 void Timer0_ISR() interrupt 1 { static unsigned char pos = 0; // 位选消隐 HC138_Set(SEG_PORT, 0xFF); HC138_Set(DIG_PORT, 1<<pos); // 显示当前位 HC138_Set(SEG_PORT, seg_table[disp_buf[pos]]); if(++pos >= 8) pos = 0; }

3.3 数据滤波算法

原始AD值存在波动,推荐采用滑动平均滤波:

#define FILTER_LEN 8 unsigned char filter_buf[FILTER_LEN]; unsigned char filter_index = 0; unsigned char Moving_Average_Filter(unsigned char new_val) { static unsigned int sum = 0; sum -= filter_buf[filter_index]; sum += new_val; filter_buf[filter_index] = new_val; if(++filter_index >= FILTER_LEN) { filter_index = 0; } return (unsigned char)(sum / FILTER_LEN); }

4. 竞赛调试技巧与常见问题

4.1 快速调试方法

  1. 分模块验证

    • 先用固定值测试数码管显示
    • 用可调电阻模拟光敏电阻
    • 通过串口打印原始AD值
  2. 关键信号测量点

    • PCF8591的SCL/SDA波形
    • 数码管段选/位选信号
    • 光敏电阻分压点电压

4.2 常见扣分点及避免方法

  • 初始化不完整:确保所有外设在上电时处于确定状态
  • 中断冲突:避免在中断服务程序中执行耗时操作
  • 显示闪烁:检查定时器配置和扫描频率
  • 测量跳变:增加软件滤波,硬件上添加去耦电容

调试建议:准备不同光照条件(强光/弱光)测试系统响应

5. 功能扩展与创新思路

在基础功能之外,可以考虑以下加分项:

  1. 光照等级指示

    • 用LED显示光照强度区间
    • 添加蜂鸣器报警功能
  2. 数据记录

    • 利用片内EEPROM存储历史数据
    • 实现最大值/最小值记录
  3. 通信接口

    • 通过串口上传数据到PC
    • 添加蓝牙/WiFi模块
// EEPROM数据存储示例 void Save_Light_Data(unsigned char light) { static unsigned char addr = 0; IAP_Erase(0x2000 + addr); // 擦除扇区 IAP_Write(0x2000 + addr, light); addr = (addr + 1) % 256; // 循环存储 }

在实际比赛中,我曾遇到一个有趣的问题:当现场灯光频繁变化时,原始算法会导致数码管显示不断跳动。后来通过增加滞后比较算法,只有当光照变化超过5%时才更新显示,既保持了响应性又避免了视觉疲劳。这个小技巧帮助我们的团队获得了当届比赛的最佳稳定性奖。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询