源码:点击获取源码
一、项目背景
本项目是单片机课程设计作品,旨在模拟城市路灯的智能化管理场景。传统的路灯控制方式通常依赖人工开关或简单的定时控制,存在能源浪费、维护困难等问题。随着智慧城市概念的提出,智能路灯系统成为城市基础设施建设的重要组成部分。
智能路灯系统可根据环境光照强度、时间段、行人车辆通行情况自动调节路灯状态,有效节约能源,同时具备故障检测与报警功能,便于维护人员及时发现并处理问题。本项目正是基于这一实际需求而设计。
二、项目简介
本项目基于51单片机设计了一套智能路灯控制系统,集成了实时时钟、光照检测、人体感应、故障报警等功能模块。系统主要实现以下目标:
- 时间显示:通过LCD1602实时显示当前日期和时间
- 智能照明:根据工作时段和环境光照自动控制路灯开关
- 人车感应:检测行人或车辆通过时自动点亮路灯并延时熄灭
- 参数设置:支持按键设置系统时间、工作时间范围、光照阈值
- 故障检测:实时监测路灯工作状态,异常时触发声光报警
三、软件设计
3.1 开发环境
- 开发工具:Keil uVision
- 仿真工具:Proteus 8
- PCB设计:Altium Designer
- 目标芯片:STC89C52 / AT89C51系列单片机
- 编程语言:C语言
3.2 系统架构
系统按功能模块划分为以下几个部分:
| 模块 | 功能描述 |
|---|---|
| 主控模块 | 系统主循环、状态判断、逻辑控制 |
| 时钟模块 | DS1302实时时钟读写、时间转换 |
| 显示模块 | LCD1602驱动、界面显示 |
| 采集模块 | ADC0832光照采集、LED状态检测 |
| 感应模块 | 红外传感器人车检测 |
| 按键模块 | 参数设置交互 |
| 报警模块 | 蜂鸣器声光报警 |
3.3 主要流程
系统主程序采用无限循环结构,主要流程如下:
系统初始化(LCD、定时器、DS1302)
↓
进入主循环
↓
读取DS1302时间 → 检测按键输入 → 读取光照ADC值
↓
执行工作状态判断逻辑
↓
更新LCD显示 → 控制LED和报警输出
↓
返回循环顶部
四、硬件方案
4.1 核心器件选型
| 器件 | 型号 | 作用 |
|---|---|---|
| 单片机 | STC89C52 | 主控芯片,负责逻辑运算和控制 |
| 时钟芯片 | DS1302 | 提供实时时钟功能,掉电保持时间 |
| 显示器 | LCD1602 | 显示日期时间、光照强度等信息 |
| ADC芯片 | ADC0832 | 模数转换,采集光照和LED状态信号 |
| 红外传感器 | - | 检测行人或车辆通行 |
| 蜂鸣器 | - | 故障报警提示 |
4.2 引脚分配
主要控制引脚定义如下:
c
// 按键输入
sbit key_1 = P1^0; // 设置时间按键
sbit key_2 = P1^1; // 增加/确认按键
sbit key_3 = P1^2; // 减少/设置光照阈值按键
sbit key_4 = P1^3; // 确认/退出按键
// 输出控制
sbit led_1 = P1^4; // 路灯控制
sbit Beep = P2^3; // 蜂鸣器报警
// ADC0832接口
sbit AD_clk = P3^4; // 时钟信号
sbit AD_do = P3^5; // 数据输出
sbit AD_di = P3^5; // 数据输入(复用)
sbit AD_cs = P3^6; // 片选信号
// 红外传感器
sbit red_sr = P3^7; // 人车检测信号
五、核心功能实现
5.1 时间采集与管理
系统采用DS1302实时时钟芯片提供精确的时间基准。DS1302通过三线接口(SCLK、IO、CE)与单片机通信,支持年、月、日、时、分、秒的读写操作。
时间读取函数:
c
void Ds1302ReadTime()
{
unsigned char n;
for (n=0; n<7; n++) // 读取7个字节的时间信号
{
Time_1[n] = Ds1302Read(READ_RTC_ADDR[n]);
}
}
BCD码转换:
DS1302以BCD码格式存储时间数据,需要转换为十进制数用于显示和判断:
c
void Read_time()
{
hour = (Time_1[2]/16)*10 + (Time_1[2]&0x0f); // 时
min = (Time_1[1]/16)*10 + (Time_1[1]&0x0f); // 分
sec = (Time_1[0]/16)*10 + (Time_1[0]&0x0f); // 秒
}
5.2 光照强度采集
系统使用ADC0832芯片采集光照传感器的模拟信号,转换为8位数字量(0-255)。通道0用于光照强度采集,通道1用于LED工作状态检测。
ADC采集函数:
c
uchar AD(bit Channel)
{
unsigned char i;
unsigned char ad0, ad1;
AD_cs = 0; // 片选有效
AD_clk = 0;
AD_di = 1;
AD_clk = 1; // 启动信号
// 通道选择配置
AD_clk = 0;
AD_di = 1; // 选择单通道模式
AD_clk = 1;
AD_clk = 0;
AD_di = Channel; // 选择通道号
// 读取8位ADC数据
for(i=8; i>0; i--)
{
AD_clk = 1;
ad0 <<= 1;
AD_clk = 0;
if(AD_do) ad0 |= 0x01;
}
AD_cs = 1;
return ad1;
}
5.3 智能照明控制逻辑
系统照明控制分为三种工作模式,根据当前时间和环境条件自动切换:
模式一:工作时间段内(默认16:00-次日05:00)
傍晚时段路灯自动点亮,凌晨0点后进入节能模式,仅当检测到人或车辆时点亮路灯,延时10秒后熄灭。
c
if(hour >= work_time_Start) // 当前时间大于开始时间
{
led_1 = 1; // 点亮LED
// 检测LED工作状态
Data = AD(1);
if(Data < 50) // 未检测到LED电流
Beep = 1; // 故障报警
}
else if(hour < work_time_End) // 凌晨时段
{
if(red_sr) // 检测到人车
{
time = 0;
light_flag = 1; // 启动延时计时
}
if(light_flag)
{
led_1 = 1; // 点亮LED
EA = 1; // 开启定时器中断
if(time > 10) // 10秒计时结束
{
light_flag = 0; // 清除标志
led_1 = 0; // 熄灭LED
}
}
}
模式二:非工作时间段
此时段路灯根据光照强度判断是否开启,当环境光照低于设定阈值时自动点亮。
c
else // 非工作时间段
{
if(light < light_limit) // 光照低于阈值
{
led_1 = 1; // 点亮LED
}
else
{
led_1 = 0; // 熄灭LED
}
}
5.4 人车感应延时控制
系统利用定时器T0实现延时控制功能,当红外传感器检测到行人或车辆时,启动定时器计时,路灯点亮10秒后自动熄灭。
定时器初始化:
c
void InitTimer0(void)
{
TMOD = 0x01; // 定时器0模式1
TH0 = 0x0D8; // 定时10ms
TL0 = 0x0F0;
ET0 = 1; // 允许定时器0中断
TR0 = 1; // 启动定时器
}
定时器中断服务:
c
void Timer0Interrupt(void) interrupt 1
{
static uchar count;
TH0 = 0x0D8;
TL0 = 0x0F0;
count++;
if(count >= 100) // 100次中断 = 1秒
{
time++; // 秒计数
count = 0;
}
}
5.5 按键参数设置
系统提供三个设置界面,通过按键组合可调整以下参数:
- 系统时间:年、月、日、时、分、秒
- 工作时间范围:开始时间和结束时间
- 光照阈值:触发点灯的光照强度界限
设置流程采用光标闪烁提示,通过增加/减少键调整数值,确认键保存设置。
c
void set_work_time()
{
if(key_2 == 0) // 进入设置
{
while(key_2 == 0); // 等待释放
LcdWriteCom(0x01); // 清屏
// 显示设置界面
LcdWriteCom(0x80);
LcdWriteData('S');
LcdWriteData('E');
LcdWriteData('T');
// ... 设置循环逻辑
}
}
六、项目总结
6.1 项目收获
通过本项目的设计与实现,深入学习和实践了以下知识:
- 单片机外围模块驱动:掌握了DS1302时钟芯片、ADC0832模数转换芯片、LCD1602显示模块的驱动方法
- 中断与定时器应用:熟练运用定时器中断实现延时控制和计时功能
- 模块化程序设计:学会将系统功能分解为独立模块,提高代码可读性和可维护性
- 软硬件联调技巧:通过Proteus仿真与实际电路验证,积累调试经验
源码:点击获取源码