项目说明
该设计是一个简易的基于51单片机的智能楼道照明设计,功能说明:
- 按键按下在自动和手动模式中切换。
- 自动模式下,检测到人体,并且当前光照阈值低于设定阈值,灯点亮,如果检测不到人体,楼道灯熄灭。
- 手动模式下,按键可以直接选择点亮灯还是关闭灯。
开源链接见文章结尾。
V1.1 (2025_07_05更新)
更新内容
1、在V1.0基础上优化了LCD显示延时,使得LCD的显示更加迅速。 2、如果有问题,大家可以继续提出。大家就不要去下资源绑定里面的内容了,那个不能实时更新。
LCD显示优化
在实际仿真使用的时候LCD刷新会比较慢,使用实物的时候可以用原来的代码,仿真的时候可以把延时注释了,使用下面的函数,开头要加个1ms的延时,因为没有忙检测。
void LcdWriteCom(uint8_t com) //写入命令
{
Lcd1602_Delay1ms(1);
LCD1602_E = 0; //使能
LCD1602_RS = 0; //选择发送命令
LCD1602_RW = 0; //选择写入
LCD1602_DATAPINS = com; //放入命令
// Lcd1602_Delay1ms(1); //等待数据稳定
LCD1602_E = 1; //写入时序
// Lcd1602_Delay1ms(5); //保持时间
LCD1602_E = 0;
}
void LcdWriteData(uint8_t dat) //写入数据
{
Lcd1602_Delay1ms(1);
LCD1602_E = 0; //使能清零
LCD1602_RS = 1; //选择输入数据
LCD1602_RW = 0; //选择写入
LCD1602_DATAPINS = dat; //写入数据
// Lcd1602_Delay1ms(1);
LCD1602_E = 1; //写入时序
// Lcd1602_Delay1ms(5); //保持时间
LCD1602_E = 0;
}
V1.0 基础内容
设计说明
该设计是一个简易的基于51单片机的智能楼道照明设计,功能说明:
- 按键按下在自动和手动模式中切换。
- 自动模式下,检测到人体,并且当前光照阈值低于设定阈值,灯点亮,如果检测不到人体,楼道灯熄灭。
- 手动模式下,按键可以直接选择点亮灯还是关闭灯。
硬件设计
电路使用LCD1602来显示当前的执行状态,使用光敏电阻和普通电阻分压,然后使用PCF8591读取ADC的电压值,使用I2C通信获取和控制PCF8591。按键0用来切换现在是自动模式还是手动模式,按键1用来在手动模式下开关灯。使用一个SWITCH开关模拟人体传感器。
软件设计
软件的整体设计思路是采用一个5MS定时器来做控制和信号读取的任务,包含按键扫描,根据按键值控制当前的状态,以及ADC的读取,根据ADC值和人体传感器的值确定当前开关灯的状态,在While循环中不断地刷新显示屏的值。
#include "main.h"
#include "delay.h"
#include "i2c.h"
#include "pcf8591.h"
#include "LCD1602.h"
#include "key.h"
// 变量定义
sbit LED = P2^0; // 楼道灯
sbit MAN = P2^1; // 人体红外传感器 有人的时候信号为0
uint8_t key_value = 0; // 按键按下的值
uint8_t adcx = 0; // 当前的ADC检测到的值
uint8_t run_mode = 0; // 运行模式 0 :自动模式 1:手动模式
// 函数声明
void Timer0_Init(void); //5毫秒@11.0592MHz
void main()
{
IIC_init();
LcdInit();
Timer0_Init();
EA = 1; //打开所有中断
while(1)
{
LcdShowStr(0,0,"RUN Mode:");
LcdShowNumInt(9,0,run_mode,1,0);
delay_ms(5);
}
}
// 5ms定时器中断,5MS执行一次
void Timer0Routine(void) interrupt 1
{
static int count = 0;
// 5ms 定时值重置
TL0 = 0x00; //设置定时初始值
TH0 = 0xEE; //设置定时初始值
// 按键扫描并获得值
key_value = KeyScan();
// 按键0按下切换工作模式
if(key_value == KEY0_PRES)
{
if(run_mode == 0) // 假如是自动模式,就切换到手动模式
run_mode = 1;
else if(run_mode == 1) // 假如是手动模式,就切换到自动模式
run_mode = 0;
}
// 按键1按下,如果在手动模式就开关灯
else if(key_value == KEY1_PRES)
{
if(run_mode == 1)
{
LED = !LED;
}
}
// 如果在自动模式,读取光敏电阻分压的值,然后根据读到得阈值和是否检测到人开关灯
if(run_mode == 0)
{
// 读取光敏电阻和电阻分压值
adcx = pcf_analog_read(0);
if(adcx > 128 && MAN == 0)
LED = 0;
else
LED = 1;
}
}
void Timer0_Init(void) //5毫秒@11.0592MHz
{
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式
TL0 = 0x00; //设置定时初始值
TH0 = 0xEE; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0 = 1; //打开定时器中断
}
调试效果
1、自动模式下,检测到人和光照强度大于一定值。
2、自动模式下,检测到人和光照强度小于一定值。
3、手动模式下,按键控制开关,人体不起作用
项目开源链接
关注VX公众号 少年潜行 回复 A001楼道照明 在对应文中获得网盘链接 免费开源。有问题请VX公众号后台回复,博客不一定能及时查看。