源码:点击获取源码
一、项目背景
本项目是单片机课程设计的实践成果。随着智能家居概念的普及,窗帘自动化控制已成为智能家居系统的重要组成部分。在浴室等私密空间,窗帘的智能控制不仅能提升生活便利性,还能有效保护用户隐私。
传统窗帘需要手动开关,在潮湿的浴室环境中操作不便。本项目设计了一款基于光照强度检测的智能窗帘控制系统,可根据环境光线自动调节窗帘开合,同时也支持手动控制,适用于浴室、卧室等多种场景。
二、项目简介
项目功能概述
本项目实现了一款智能窗帘控制系统,主要具备以下功能:
- 光照检测:实时采集环境光照强度,并在LCD显示屏上显示
- 自动控制:根据光照强度自动控制窗帘开合,光线强时自动开窗,光线弱时自动关窗
- 手动控制:支持手动按键控制窗帘的正转(打开)、反转(关闭)和停止
- 模式切换:可在自动模式和手动模式间自由切换
- 状态指示:LED指示灯显示当前工作模式,LCD屏幕显示光照值和运行状态
系统实现目标
- 光照强度检测范围:0-100
- 自动模式阈值:光照值 > 50 时开窗帘,光照值 ≤ 50 时关窗帘
- 响应时间:实时响应,无延迟
- 人机交互:LCD1602显示屏实时显示光照值和工作状态
三、硬件设计
使用的单片机型号
本系统采用经典的 STC89C52 / AT89C51 系列51单片机作为主控制器。该单片机具有以下特点:
- 8KB Flash程序存储器
- 256字节RAM
- 32个通用I/O口
- 3个16位定时器/计数器
- 6个中断源
- 价格低廉、资料丰富、适合初学者
外设模块说明
| 模块名称 | 型号/规格 | 功能说明 |
|---|---|---|
| 光照传感器 | 光敏电阻 + ADC0832 | 检测环境光照强度 |
| 显示模块 | LCD1602液晶显示屏 | 显示光照值和系统状态 |
| 驱动模块 | ULN2003 + 步进电机 | 驱动窗帘开合 |
| 按键模块 | 独立按键 | 手动控制和模式切换 |
| 指示模块 | LED指示灯 | 指示当前工作模式 |
四、软件设计
开发环境
- IDE:Keil uVision 4/5
- 编程语言:C语言
- 仿真工具:Proteus 8.x
- 下载工具:STC-ISP(STC单片机)
系统架构
系统软件采用模块化设计,主要分为以下几个模块:
┌─────────────────────────────────────────┐
│ 主程序 (main.c) │
├─────────────────────────────────────────┤
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ 按键扫描 │ │ 模式判断 │ │ 电机控制 │ │
│ └─────────┘ └─────────┘ └─────────┘ │
├─────────────────────────────────────────┤
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ LCD驱动 │ │ ADC驱动 │ │ 延时函数 │ │
│ │(LCD1602.c)│ │(adc0832.c)│ │(delay.c) │ │
│ └─────────┘ └─────────┘ └─────────┘ │
└─────────────────────────────────────────┘
主要流程
系统主循环流程如下:
- 初始化:LCD1602初始化、定时器T0初始化
- 模式检测:检测模式切换按键,判断当前工作模式
- 光照采集:通过ADC0832读取光照传感器的模拟值
- 数据显示:将光照值显示在LCD1602上
- 模式处理 :
- 手动模式:扫描按键,执行相应控制
- 自动模式:根据光照值自动判断窗帘动作
- 电机驱动:通过定时器中断驱动步进电机
五、核心功能实现
1. 光照数据采集
系统使用ADC0832芯片将光敏电阻的模拟电压转换为数字信号:
c
uchar adc0832()
{
uint i;
uchar dat;
dat=0x00;
cs=1;
clk=0;
cs=0;
dio=1;
clk=1;
_nop_();
_nop_();
clk=0;
// ... 时序控制读取8位数据
for(i=0;i<8;i++)
{
dat<<=1;
if(dio==1)
dat=dat|0x01;
else
dat=dat|0x00;
clk=1;
_nop_();
_nop_();
clk=0;
_nop_();
_nop_();
}
cs=1;
return dat;
}
ADC采集后,将0-255的数字量转换为0-100的光照百分比:
c
youliang = adc0832()/2.55; // 转换为百分比
write_num3(1,7,youliang); // LCD显示
2. 按键扫描与消抖
采用软件消抖方式处理按键信号:
c
void key()
{
if(k1==0) // 正转按键
{
delayxms(5); // 延时消抖
while(k1==0); // 等待按键释放
flag1 = 0; flag = 1;
write_zifu(1,15,'Z'); // 显示正转状态
}
if(k2==0) // 反转按键
{
delayxms(5);
while(k2==0);
flag1 = 1; flag = 1;
write_zifu(1,15,'F'); // 显示反转状态
}
if(k3==0) // 停止按键
{
delayxms(5);
while(k3==0);
flag = 0;
}
}
3. 自动控制逻辑
自动模式根据光照强度判断窗帘动作:
c
if(mode == 0) // 自动模式
{
led = 0; // LED亮,指示自动模式
key1(); // 扫描自动模式按键
// 光照强度 > 50,开窗帘
if(youliang > 50 && flag2 == 0)
{
flag = 1; flag1 = 0;
write_zifu(1,15,'Z');
}
// 光照强度 <= 50,关窗帘
if(youliang <= 50 && flag3 == 0)
{
flag = 1; flag1 = 1;
write_zifu(1,15,'F');
}
}
4. 步进电机驱动
使用定时器T0中断产生步进电机的驱动脉冲:
c
// 步进电机相序表
uchar code tab5[]={0xfe,0xfc,0xfd,0xf9,0xfb,0xf3,0xf7,0xf6};
// 定时器T0中断服务函数
void T0_time() interrupt 1
{
TR0 = 0;
TH0=(65535-50000)/256; // 重装定时初值
TL0=(65535-50000)%256;
if(i > 7) i = 0;
if(flag1 == 0)
P1 = tab5[i]; // 正转
else
P1 = tab5[7-i]; // 反转
i += 1;
TR0 = 1;
}
5. LCD1602显示
LCD1602驱动主要包括初始化、写命令、写数据和字符串显示等功能:
c
// LCD1602初始化
void chushihua()
{
delayxms(20);
xiemingling(0x38); // 16×2显示,5×7点阵,8位数据接口
xiemingling(0x0c); // 开显示,不显示光标
xiemingling(0x06); // 写一个字符后地址指针加1
xiemingling(0x01); // 显示清零,数据指针清零
xiemingling(0x80); // 设置数据指针位置
}
// 字符串显示
void write_string(uchar hang, uchar add, uchar *p)
{
if(hang==1)
xiemingling(0x80+add);
else
xiemingling(0x80+0x40+add);
while(1)
{
if(*p == '\0') break;
xieshuju(*p);
p++;
}
}
源码:点击获取源码