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

从LED闪烁到温度监测:用蓝桥杯CT107D板子复刻5个经典电子小项目

从LED闪烁到温度监测:用蓝桥杯CT107D板子复刻5个经典电子小项目

在电子技术学习过程中,理论与实践的结合往往是最具挑战性的一环。蓝桥杯CT107D开发板作为一款功能丰富的单片机学习平台,为电子爱好者提供了从基础到进阶的完整实践路径。本文将带你通过5个由浅入深的项目,从简单的LED控制到复杂的温湿度监测系统,全面掌握单片机开发的精髓。

1. 呼吸灯:PWM调光艺术

呼吸灯效果是嵌入式系统中最经典的入门项目之一,它通过PWM(脉宽调制)技术实现LED亮度的平滑变化。在CT107D开发板上,我们可以利用定时器来模拟PWM信号。

硬件连接示意图:

  • LED模块 → P0端口
  • 74HC138译码器 → 控制LED组选通

核心代码实现:

#include <STC15F2K60S2.H> unsigned char pwm_duty = 0; // 占空比变量 bit pwm_dir = 0; // 方向标志 void Timer0_Init() { TMOD &= 0xF0; // 设置定时器0为模式1 TMOD |= 0x01; TH0 = 0xFF; // 初始值 TL0 = 0x00; ET0 = 1; // 允许定时器0中断 EA = 1; // 开总中断 TR0 = 1; // 启动定时器0 } void Timer0_ISR() interrupt 1 { static unsigned int pwm_count = 0; TH0 = 0xFF; // 重装初值 TL0 = 0x00; pwm_count++; if(pwm_count >= 100) pwm_count = 0; if(pwm_count < pwm_duty) { P0 = 0x00; // LED亮 } else { P0 = 0xFF; // LED灭 } } void main() { Timer0_Init(); P2 = (P2 & 0x1F) | 0x80; // 选择LED锁存器 while(1) { if(pwm_dir == 0) { pwm_duty++; if(pwm_duty >= 100) pwm_dir = 1; } else { pwm_duty--; if(pwm_duty <= 0) pwm_dir = 0; } Delay_ms(10); // 控制呼吸速度 } }

技术要点解析:

  1. PWM原理:通过调节高电平在一个周期内的占比(占空比)来控制平均电压
  2. 定时器配置:使用模式1的16位定时器,产生固定频率的中断
  3. 亮度渐变:通过改变占空比变量,实现亮度的平滑过渡

提示:在实际应用中,可以通过调整定时器中断频率和占空比变化速度来获得不同的呼吸效果。较高的PWM频率(>100Hz)可以避免人眼察觉到的闪烁。

2. 可调数字时钟:DS1302实时时钟应用

数字时钟是检验时间管理能力的经典项目。DS1302是一款低功耗实时时钟芯片,具有计时准确、接口简单的特点。

硬件连接图:

  • DS1302模块
    • CE → P1.3
    • IO → P1.4
    • SCLK → P1.5
  • 数码管显示 → P0端口 + 74HC138控制

核心代码架构:

// DS1302驱动函数 void DS1302_WriteByte(unsigned char addr, unsigned char dat) { unsigned char i; CE = 0; _nop_(); SCLK = 0; _nop_(); CE = 1; _nop_(); // 写入地址 for(i=0; i<8; i++) { IO = addr & 0x01; SCLK = 1; _nop_(); SCLK = 0; _nop_(); addr >>= 1; } // 写入数据 for(i=0; i<8; i++) { IO = dat & 0x01; SCLK = 1; _nop_(); SCLK = 0; _nop_(); dat >>= 1; } CE = 0; _nop_(); } unsigned char DS1302_ReadByte(unsigned char addr) { unsigned char i, dat = 0; CE = 0; _nop_(); SCLK = 0; _nop_(); CE = 1; _nop_(); // 写入地址 for(i=0; i<8; i++) { IO = addr & 0x01; SCLK = 1; _nop_(); SCLK = 0; _nop_(); addr >>= 1; } // 读取数据 for(i=0; i<8; i++) { dat >>= 1; if(IO) dat |= 0x80; SCLK = 1; _nop_(); SCLK = 0; _nop_(); } CE = 0; _nop_(); return dat; } // 时间设置函数 void Set_Time(unsigned char hour, unsigned char min, unsigned char sec) { DS1302_WriteByte(0x8E, 0x00); // 关闭写保护 DS1302_WriteByte(0x80, sec); // 秒 DS1302_WriteByte(0x82, min); // 分 DS1302_WriteByte(0x84, hour); // 时 DS1302_WriteByte(0x8E, 0x80); // 开启写保护 } // 数码管显示函数 void Display_Time() { unsigned char time[3]; time[0] = DS1302_ReadByte(0x81); // 读秒 time[1] = DS1302_ReadByte(0x83); // 读分 time[2] = DS1302_ReadByte(0x85); // 读时 // 显示时分秒(BCD码转换) Show_SMG(0, time[2]>>4); // 时的十位 Show_SMG(1, time[2]&0x0F); // 时的个位 Show_SMG(2, 16); // 横线 Show_SMG(3, time[1]>>4); // 分的十位 Show_SMG(4, time[1]&0x0F); // 分的个位 Show_SMG(5, 16); // 横线 Show_SMG(6, time[0]>>4); // 秒的十位 Show_SMG(7, time[0]&0x0F); // 秒的个位 }

时间管理技巧:

  • DS1302使用BCD码存储时间数据,需要进行转换才能正确显示
  • 芯片内部有写保护寄存器,修改时间前需要先关闭写保护
  • 数码管动态扫描频率建议保持在50Hz以上以避免闪烁

3. 简易数字电压表:PCF8591模数转换实践

PCF8591是一款集成了ADC和DAC功能的芯片,非常适合用于模拟信号的采集和输出。

硬件连接示意图:

  • PCF8591模块
    • SDA → P2.1
    • SCL → P2.0
  • 电位器 → AIN0
  • 数码管显示 → P0端口

I2C通信协议实现:

// I2C起始信号 void I2C_Start() { SDA = 1; _nop_(); SCL = 1; _nop_(); SDA = 0; _nop_(); SCL = 0; _nop_(); } // I2C停止信号 void I2C_Stop() { SDA = 0; _nop_(); SCL = 1; _nop_(); SDA = 1; _nop_(); } // I2C发送字节 bit I2C_SendByte(unsigned char dat) { unsigned char i; bit ack; for(i=0; i<8; i++) { SDA = (dat & 0x80) ? 1 : 0; SCL = 1; _nop_(); SCL = 0; _nop_(); dat <<= 1; } SDA = 1; _nop_(); SCL = 1; _nop_(); ack = SDA; SCL = 0; _nop_(); return ack; } // PCF8591读取ADC值 unsigned char PCF8591_ReadADC(unsigned char channel) { unsigned char val; I2C_Start(); I2C_SendByte(0x90); // 器件地址+写 I2C_SendByte(0x40|channel); // 控制字 I2C_Start(); I2C_SendByte(0x91); // 器件地址+读 val = I2C_ReceiveByte(); I2C_SendAck(1); I2C_Stop(); return val; } // 电压值显示函数 void Display_Voltage(unsigned char adc_val) { unsigned int voltage; // 将ADC值转换为电压(mV),假设参考电压为5V voltage = (unsigned int)adc_val * 5000 / 255; // 显示电压值 Show_SMG(0, voltage/1000); // 整数部分 Show_SMG(1, (voltage/100)%10); // 第一位小数 Show_SMG(2, (voltage/10)%10); // 第二位小数 Show_SMG(3, 16); // V符号 }

ADC采集优化技巧:

  1. 多次采样取平均可以减少噪声影响
  2. 参考电压的稳定性直接影响测量精度
  3. I2C通信速率不宜过高,建议在100kHz左右
  4. 显示刷新率控制在5-10Hz为宜,避免频繁刷新导致显示闪烁

4. 超声波测距仪:HC-SR04模块应用

超声波测距是非接触式距离测量的常用方法,HC-SR04模块性价比高、使用简单。

硬件连接示意图:

  • 超声波模块
    • Trig → P1.0
    • Echo → P1.1
  • 数码管显示 → P0端口

测距核心算法:

// 超声波测距函数 unsigned int Ultrasonic_Measure() { unsigned int time_cnt = 0; float distance; // 发送10us的高电平触发信号 Trig = 1; Delay_us(10); Trig = 0; // 等待回波信号变高 while(Echo == 0); // 开始计时 TR0 = 1; TH0 = TL0 = 0; // 等待回波信号变低 while(Echo == 1); // 停止计时 TR0 = 0; // 计算高电平持续时间(us) time_cnt = (TH0 << 8) | TL0; // 计算距离(cm),声速按340m/s计算 distance = time_cnt * 0.017; // 时间(us)*340(m/s)/2/10000 return (unsigned int)distance; } // 定时器0初始化 void Timer0_Init() { TMOD &= 0xF0; // 设置定时器0为模式1 TMOD |= 0x01; TH0 = 0; TL0 = 0; } // 显示函数 void Display_Distance(unsigned int dis) { if(dis > 999) { Show_SMG(0, dis/1000); // 千位 Show_SMG(1, (dis/100)%10); // 百位 Show_SMG(2, (dis/10)%10); // 十位 Show_SMG(3, dis%10); // 个位 } else if(dis > 99) { Show_SMG(0, 17); // 空格 Show_SMG(1, dis/100); // 百位 Show_SMG(2, (dis/10)%10); // 十位 Show_SMG(3, dis%10); // 个位 } else if(dis > 9) { Show_SMG(0, 17); // 空格 Show_SMG(1, 17); // 空格 Show_SMG(2, dis/10); // 十位 Show_SMG(3, dis%10); // 个位 } else { Show_SMG(0, 17); // 空格 Show_SMG(1, 17); // 空格 Show_SMG(2, 17); // 空格 Show_SMG(3, dis); // 个位 } }

测距优化建议:

  • 测量间隔建议在60ms以上,避免超声波信号相互干扰
  • 对于近距离测量,可以增加多次测量取平均值的处理
  • 温度补偿:声速随温度变化,精确测量时可加入温度传感器进行补偿
  • 异常值过滤:设置合理的距离范围,过滤掉明显不合理的测量结果

5. 温湿度监测与存储系统:DS18B20+AT24C02综合应用

完整的监测系统需要包含传感器数据采集、处理和存储功能。DS18B20数字温度传感器和AT24C02 EEPROM的组合非常适合这种应用场景。

系统架构图:

  • DS18B20温度传感器 → P1.6
  • AT24C02 EEPROM → I2C接口
  • 数码管显示 → P0端口

温度采集与存储实现:

// DS18B20温度读取函数 float DS18B20_ReadTemp() { unsigned char low, high; unsigned int temp; float temperature; DS18B20_Init(); // 初始化 DS18B20_WriteByte(0xCC); // 跳过ROM DS18B20_WriteByte(0x44); // 开始温度转换 Delay_ms(750); // 等待转换完成 DS18B20_Init(); // 再次初始化 DS18B20_WriteByte(0xCC); // 跳过ROM DS18B20_WriteByte(0xBE); // 读取暂存器 low = DS18B20_ReadByte(); // 读取低字节 high = DS18B20_ReadByte(); // 读取高字节 temp = (high << 8) | low; temperature = temp * 0.0625; // 转换温度值 return temperature; } // AT24C02数据存储函数 void AT24C02_Write(unsigned char addr, unsigned char dat) { I2C_Start(); I2C_SendByte(0xA0); // 器件地址+写 I2C_SendByte(addr); // 存储地址 I2C_SendByte(dat); // 存储数据 I2C_Stop(); Delay_ms(10); // 写入周期等待 } // 温度数据记录函数 void Record_Temperature(float temp) { static unsigned char record_addr = 0; unsigned char temp_int, temp_frac; // 分离整数和小数部分 temp_int = (unsigned char)temp; temp_frac = (unsigned char)((temp - temp_int) * 100); // 存储到EEPROM AT24C02_Write(record_addr, temp_int); AT24C02_Write(record_addr+1, temp_frac); // 更新存储地址 record_addr += 2; if(record_addr >= 254) record_addr = 0; } // 温度显示函数 void Display_Temperature(float temp) { unsigned char temp_int, temp_frac; temp_int = (unsigned char)temp; temp_frac = (unsigned char)((temp - temp_int) * 10); Show_SMG(0, temp_int/10); // 十位 Show_SMG(1, temp_int%10); // 个位 Show_SMG(2, 16); // 小数点 Show_SMG(3, temp_frac); // 小数位 Show_SMG(4, 12); // C符号 }

系统优化建议:

  1. 温度采集间隔:根据应用场景设置合理的采集频率,一般5-10秒一次即可
  2. 数据存储策略:EEPROM有写入次数限制,避免过于频繁的写入操作
  3. 异常处理:增加传感器检测和异常数据处理机制
  4. 低功耗设计:在不采集时可以进入休眠模式以节省电能

通过这五个项目的实践,不仅能够掌握CT107D开发板的各种外设使用方法,还能建立起完整的嵌入式系统开发思维。每个项目都可以进一步扩展功能,比如增加无线通信模块实现远程监控,或者加入更多的传感器构建综合监测系统。

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

相关文章:

  • 别再调硬件接口了!用广播模式为东大PDA写扫码App更简单(Xamarin教程)
  • Wav2Lip推理效果总翻车?手把手教你调优pads、nosmooth和resize_factor参数
  • Magpie终极优化指南:让低配电脑也能流畅放大窗口的5个简单技巧
  • 快马平台一键生成ensp项目:三步完成小型企业网络原型设计与仿真
  • 2026株洲GEO公司推荐指南评测 - GrowthUME
  • 保姆级教程:用Python+OpenCV调参SGBM,让你的双目视觉项目效果立竿见影
  • 数学!真好玩 - qqqaaazzz
  • 从B站m4s文件到完整MP4:手把手教你用Python脚本自动化合成音视频(FFmpeg/MoviePy双方案)
  • OSINT开源情报:从核心技能到实战调查的全流程指南
  • 辽宁大学 —— 信息学院 —— 博导履历 —— 华春生
  • AI Agent安全入门:使用opena2a进行静态扫描与漏洞防护
  • 别再死记硬背了!用这5个PyTorch实战项目,把面试题考点变成你的肌肉记忆
  • 5分钟搞定!鸣潮自动剧情跳过与多账号管理的终极指南
  • 初创团队如何利用 Taotoken 快速试验不同大模型能力
  • 从VMM到UVM:一个芯片验证工程师的十年方法学演进史
  • 给ESP32S3 NES模拟器换“皮肤”:手把手教你修改调色板解决SPI屏颜色错乱
  • 开源Vanlife改装模板:从3D设计到电路实现的模块化DIY指南
  • 手机号码定位神器:零成本实现精准地理位置查询的终极指南
  • QMC音频解密终极指南:5分钟解锁你的加密音乐库
  • 文件系统-5-相关工具-dd命令 - Hello
  • BEV视角下,TopoNet、MapTR、VectorMapNet三大模型实战横评:谁才是车道线检测的‘最优解’?
  • 百大购物卡用不上?超60%的人选择线上回收,最快1分钟到账 - 可可收
  • 从零开始:5分钟掌握微信聊天记录永久保存的完整方法
  • 2026年青岛除甲醛企业大揭秘,有哪些值得信赖的选择? - GrowthUME
  • caj2pdf:破解学术文献格式壁垒的开源技术方案
  • 英语阅读_Welcome to our workshop corner
  • 2026年3月有实力的回转式整列机源头厂家推荐,整列机长期运行稳定可靠 - 品牌推荐师
  • 3个高效步骤:快速实现CSDN博客内容的完整备份
  • NoFences:3分钟解决Windows桌面杂乱问题,免费开源分区工具终极指南
  • 终极指南:3步掌握ModOrganizer2游戏模组管理技巧 [特殊字符]