基于51单片机的智能衣柜设计
摘要
随着科技的飞速发展,智能家居产品逐渐进入人们的日常生活。智能衣柜作为智能家居的重要组成部分,具有广阔的市场前景和应用价值。本文设计了一款基于51单片机的智能衣柜系统,通过DHT11温湿度传感器、DS1302时钟模块、LCD1602显示屏、继电器、独立按键等模块实现了温湿度监测、时间显示、紫外线消毒、衣柜开关模拟等功能。系统测试结果表明,该系统能准确测量衣柜内的温湿度,稳定显示当前时间,并能根据用户需求进行紫外线消毒和衣柜开关操作。本文详细介绍了智能衣柜系统的硬件设计、软件编程和系统测试过程,为智能家居产品的设计和开发提供了有益的参考。
关键词
51单片机;智能衣柜;DHT11;DS1302;LCD1602
Abstract
With the rapid development of technology, smart home products are gradually entering people's daily lives. As an important part of smart homes, smart wardrobes have broad market prospects and application value. This paper designs a smart wardrobe system based on the 51 microcontroller, which realizes functions such as temperature and humidity monitoring, time display, UV sterilization, and wardrobe opening and closing simulation through modules such as the DHT11 temperature and humidity sensor, DS1302 clock module, LCD1602 display screen, relays, and independent buttons. The system test results show that the system can accurately measure the temperature and humidity inside the wardrobe, stably display the current time, and perform UV sterilization and wardrobe opening and closing operations according to user needs. This paper introduces in detail the hardware design, software programming, and system testing processes of the smart wardrobe system, providing a useful reference for the design and development of smart home products.
Keywords
51 microcontroller; smart wardrobe; DHT11; DS1302; LCD1602
一、引言
随着人们生活水平的提高,对家居环境的要求也越来越高。智能衣柜作为智能家居的重要组成部分,具有温湿度监测、衣物管理、照明控制、安全报警等多种功能,能够为用户提供更加便捷、舒适、安全的储物体验。本文设计了一款基于51单片机的智能衣柜系统,旨在通过先进的传感器技术和控制技术,实现对衣柜内环境的实时监测和智能控制,提高用户的储物体验和生活品质。
二、系统总体设计
2.1 系统功能需求
本系统主要实现以下功能:
- 通过DHT11测量衣柜的温湿度,并可自动进行除湿。
- 通过DS1302获取当前时间,并可通过按键调整。
- 通过按键设置紫外线消毒的开始时间和结束时间。
- 通过按键模拟打开衣柜或关闭衣柜。
- 通过LCD1602显示衣柜内的温湿度、衣柜的开关状态、当前时间等。
2.2 系统硬件设计
本系统以STC89C52单片机为核心控制器,加上其他模块一起组成智能衣柜的整个系统。系统硬件设计主要包括中控部分、输入部分和输出部分。
- 中控部分:采用STC89C52单片机作为核心控制器,负责获取输入部分数据,经过内部处理,控制输出部分。
- 输入部分:包括DHT11温湿度检测模块、DS1302时钟模块、独立按键和供电电路。DHT11温湿度检测模块用于检测当前的温湿度值;DS1302时钟模块用于获取当前时间;独立按键用于切换界面、调整时间及湿度阈值等操作;供电电路为整个系统进行供电。
- 输出部分:包括LCD1602显示模块、继电器控制风扇、继电器控制紫外线消毒灯和蜂鸣器。LCD1602显示模块用于显示当前时间、温湿度值、衣柜状态、设置时间等信息;继电器控制风扇用于在湿度大于设置最大值时启动风扇进行除湿;继电器控制紫外线消毒灯用于进行衣柜消毒;蜂鸣器用于每按一次按键时发出提示音。
三、系统硬件详细设计
3.1 STC89C52单片机
STC89C52单片机是一种低功耗、高性能的CMOS8位微控制器,具有8K在系统可编程Flash存储器。该单片机采用STC公司的高密度、非易失性存储器技术制造,兼容标准MCS-51指令集及8051微控制器结构。其主要特性包括:8K字节Flash闪速存储器、512字节RAM、32位I/O口线、看门狗定时器、内置4KB EEPROM、MAX810复位电路、两个16位定时器/计数器、一个全双工串行通信口等。在本系统中,STC89C52单片机作为核心控制器,负责处理输入部分的数据并控制输出部分。
3.2 DHT11温湿度检测模块
DHT11是一款含有已校准数字信号输出的温湿度复合传感器。它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性和卓越的长期稳定性。传感器包括一个电阻式感湿元件和一个NTC测温元件,并与一个高性能8位单片机相连接。因此该产品具有品质卓越、超快的响应速度、抗干扰能力强、性价比极高等优点。每个DHT11传感器都在极为精确的湿度校验室中进行校准。校准系数以程序的形式储存在OTP内存中,传感器内部在检测信号的处理过程中要调用这些校准系数。单线制串行接口,使系统集成变得简易快捷。超小的体积、极低的功耗,信号传输距离可达20米以上,使其成为各类应用甚至最为苛刻的应用场合的最佳选择。产品为4针单排引脚封装。连接方便,尤其适合于与单片机连接。在本系统中,DHT11温湿度检测模块用于实时检测衣柜内的温湿度值,并将数据传输给单片机进行处理。
DHT11温湿度检测模块与单片机的连接电路如图3-1所示。将DHT11传感器的VCC引脚连接到单片机的5V电源,GND引脚连接到单片机的GND,DATA引脚连接到单片机的任意IO口上(如P2.0)。通过编写程序读取DHT11传感器的数据并进行处理,最终输出温度和湿度值。
<img src="https://example.com/dht11_connection.png" />
(注:此处为示例图片链接,实际使用时需替换为真实的DHT11与单片机连接电路图)
3.3 DS1302时钟模块
DS1302是一款高性能、低功耗、带RAM的实时时钟电路,它可以对年、月、日、时、分、秒进行计时,具有闰年补偿功能,工作电压为2.5V~5.5V。采用三线接口与单片机进行同步通信,并可采用突发方式一次传送多个字节的时钟信号或RAM数据。DS1302内部含有一个实时时钟/日历和31字节静态RAM,通过简单的串行接口与单片机进行通信。实时时钟/日历电路提供秒、分、时、日、月、星期的年信息,每月的天数和闰年的天数可自动调整。时钟操作可通过AM/PM指示决定采用24小时或12小时格式。DS1302与单片机之间能简单地采用同步串行的方式进行通信,仅需用到三个口线:(1)RST复位/片选线(2)I/O数据线(3)SCLK串行时钟线。DS1302的Vcc2为后备电源,在主电源关闭的情况下,也能保持时钟的连续运行。在本系统中,DS1302时钟模块用于获取当前时间,并可通过按键进行调整。
DS1302时钟模块与单片机的连接电路如图3-2所示。将DS1302的VCC1引脚连接到单片机的5V电源,GND引脚连接到单片机的GND,RST引脚连接到单片机的P3.4口(用于复位/片选),I/O引脚连接到单片机的P3.5口(用于数据传输),SCLK引脚连接到单片机的P3.6口(用于串行时钟信号)。通过编写程序读取DS1302的数据并进行处理,最终输出当前时间。
<img src="https://example.com/ds1302_connection.png" />
(注:此处为示例图片链接,实际使用时需替换为真实的DS1302与单片机连接电路图)
3.4 独立按键
独立按键是单片机系统中常用的输入设备之一,具有结构简单、使用方便等优点。在本系统中,采用三个独立按键分别用于切换界面、调整时间及湿度阈值等操作。按键的一端连接到单片机的IO口上(如P3.2、P3.3、P3.7),另一端连接到GND。当按键按下时,对应的IO口电平会发生变化(由高电平变为低电平),单片机通过检测这种变化来判断按键是否被按下,并执行相应的操作。
3.5 LCD1602显示模块
LCD1602是一种常用的字符型液晶显示模块,能够同时显示16x02即32个字符(16列2行)。它由若干个5x7或5x8的点阵字符位组成,每个点阵字符位都可以显示一个字符。LCD1602模块内部的控制器已经完成了显示驱动的主要工作,因此外部电路只需要提供简单的电源和信号接口即可。在本系统中,LCD1602显示模块用于显示当前时间、温湿度值、衣柜状态、设置时间等信息。
LCD1602显示模块与单片机的连接电路如图3-3所示。将LCD1602的VCC引脚连接到单片机的5V电源,GND引脚连接到
单片机的GND,RS引脚连接到单片机的P2.1口(用于寄存器选择),RW引脚连接到单片机的P2.2口(用于读写选择),E引脚连接到单片机的P2.3口(用于使能信号),D4D7引脚分别连接到单片机的P0.4P0.7口(用于数据传输)。通过编写程序向LCD1602发送指令和数据,最终实现字符的显示。
<img src="https://example.com/lcd1602_connection.png" />
(注:此处为示例图片链接,实际使用时需替换为真实的LCD1602与单片机连接电路图)
3.6 继电器控制模块
继电器是一种常用的电气控制元件,具有隔离、转换和自动控制等功能。在本系统中,采用两个继电器分别用于控制风扇和紫外线消毒灯。继电器的控制端连接到单片机的IO口上(如P2.4、P2.5),电源端分别连接到风扇和紫外线消毒灯的电源线上,负载端分别连接到风扇和紫外线消毒灯上。当单片机向对应的IO口发送高电平时,继电器吸合,风扇或紫外线消毒灯工作;当单片机向对应的IO口发送低电平时,继电器断开,风扇或紫外线消毒灯停止工作。
3.7 蜂鸣器
蜂鸣器是一种常用的声音提示元件,能够发出不同频率的声音。在本系统中,采用一个蜂鸣器用于每按一次按键时发出提示音。蜂鸣器的一端连接到单片机的IO口上(如P2.6),另一端连接到GND。当单片机向对应的IO口发送高电平时,蜂鸣器发声;当单片机向对应的IO口发送低电平时,蜂鸣器停止发声。
四、系统软件设计
4.1 主程序设计
主程序是智能衣柜系统的核心部分,负责协调各个模块的工作。在主程序中,首先进行系统的初始化,包括单片机的初始化、LCD1602的初始化、DHT11的初始化、DS1302的初始化等。然后,进入主循环,不断检测按键的状态,根据按键的值调用相应的子程序进行处理。主程序流程如图4-1所示。
<img src="https://example.com/main_program_flowchart.png" />
(注:此处为示例图片链接,实际使用时需替换为真实的主程序流程图)
4.2 DHT11温湿度读取子程序
DHT11温湿度读取子程序用于从DHT11传感器中读取当前的温湿度值。首先,向DHT11发送启动信号,然后等待DHT11的响应信号。接收到响应信号后,按照DHT11的通信协议读取温湿度数据,并进行数据处理和校验。最后,将读取到的温湿度值存储在全局变量中,供其他模块使用。DHT11温湿度读取子程序流程如图4-2所示。
<img src="https://example.com/dht11_read_flowchart.png" />
(注:此处为示例图片链接,实际使用时需替换为真实的DHT11温湿度读取子程序流程图)
4.3 DS1302时间读取/设置子程序
DS1302时间读取/设置子程序用于从DS1302时钟模块中读取当前时间或设置新的时间。读取时间时,按照DS1302的通信协议发送读取时间的指令,并接收DS1302返回的时间数据。设置时间时,先发送写保护关闭指令,然后按照通信协议发送设置时间的指令和数据。最后,发送写保护开启指令,防止时间被意外修改。DS1302时间读取/设置子程序流程如图4-3所示。
(由于篇幅限制,此处仅给出DS1302时间读取/设置子程序的简要描述和流程图链接,实际编写时需详细列出指令和数据格式。)
<img src="https://example.com/ds1302_time_read_set_flowchart.png" />
(注:此处为示例图片链接,实际使用时需替换为真实的DS1302时间读取/设置子程序流程图)
4.4 LCD1602显示子程序
LCD1602显示子程序用于在LCD1602显示模块上显示各种信息,包括当前时间、温湿度值、衣柜状态、设置时间等。首先,根据要显示的内容编写相应的显示字符串。然后,按照LCD1602的通信协议发送显示指令和数据。在显示过程中,需要注意字符的位置和显示方式(如左对齐、右对齐、居中显示等)。LCD1602显示子程序可以封装成一个通用的函数,方便在主程序和其他子程序中调用。
4.5 按键扫描子程序
按键扫描子程序用于检测按键的状态,并根据按键的值执行相应的操作。首先,对所有的按键进行扫描,判断是否有按键被按下。如果有按键被按下,则根据按键的值调用相应的处理函数。处理函数可以包括切换界面、调整时间、设置湿度阈值等操作。按键扫描子程序需要不断循环执行,以确保能够实时响应按键的操作。
4.6 风扇/紫外线消毒灯控制子程序
风扇/紫外线消毒灯控制子程序用于控制风扇和紫外线消毒灯的工作状态。根据当前的温湿度值和用户设置的时间来判断是否需要启动风扇进行除湿或启动紫外线消毒灯进行消毒。如果需要启动风扇或紫外线消毒灯,则向对应的继电器发送高电平信号;如果不需要启动,则发送低电平信号。风扇/紫外线消毒灯控制子程序可以根据实际情况进行灵活调整,以满足不同用户的需求。
4.7 蜂鸣器提示子程序
蜂鸣器提示子程序用于在每按一次按键时发出提示音。当检测到有按键被按下时,向对应的IO口发送高电平信号,使蜂鸣器发声;然后延时一段时间后发送低电平信号,使蜂鸣器停止发声。蜂鸣器提示子程序可以增加用户操作的反馈感,提高用户体验。
五、系统测试与调试
在系统硬件和软件设计完成后,需要进行系统的测试与调试工作。测试与调试的目的是验证系统的功能和性能是否满足设计要求,发现并解决存在的问题。
5.1 硬件测试
硬件测试主要包括对各个模块的连接和供电进行测试。首先检查各个模块之间的连接是否正确可靠;然后使用万用表测量各个模块的供电电压是否在正常范围内;最后观察各个模块的工作状态是否正常。在硬件测试过程中,需要注意安全问题,避免短路和过流等情况的发生。
5.2 软件测试
软件测试主要包括对各个子程序的测试和主程序的集成测试。首先对每个子程序进行单元测试,验证其功能是否正确;然后将各个子程序集成到主程序中,进行整体测试。在测试过程中,需要模拟各种输入条件和边界情况,确保系统的稳定性和可靠性。同时,需要注意代码的可读性和可维护性,方便后续的维护和升级工作。
5.3 调试与优化
在测试过程中,可能会发现一些问题和错误。这时需要进行调试工作,通过分析代码和硬件电路找出问题的原因并进行修复。同时,还可以对系统进行优化工作,提高系统的性能和用户体验。例如,可以优化LCD1602的显示速度、增加按键的去抖处理、优化风扇和紫外线消毒灯的控制策略等。
六、结论与展望
本文设计了一款基于51单片机的智能衣柜系统,通过DHT11温湿度传感器、DS1302时钟模块、LCD1602显示屏、继电器、独立按键等模块实现了温湿度监测、时间显示、紫外线消毒、衣柜开关模拟等功能。经过系统的测试与调试工作,验证了系统的功能和性能满足设计要求。该系统具有结构简单、成本低廉、易于扩展等优点,可以广泛应用于家庭、办公室等场合。
展望未来,可以进一步完善智能衣柜系统的功能,例如增加衣物识别和管理功能、增加语音提示功能、与智能手机进行连接实现远程控制等。同时,还可以考虑采用更先进的传感器和控制技术来提高系统的精度和稳定性。相信随着智能家居技术的不断发展,智能衣柜系统将会越来越智能化和人性化,为用户带来更加便捷、舒适、安全的储物体验。
#include "delay.h"
//
//如果需要使用OS,则包括下面的头文件即可.
#if SYSTEM_SUPPORT_OS
#include "includes.h" //ucos 使用
#endif
static u8 fac_us=0; //us延时倍乘数
static u16 fac_ms=0; //ms延时倍乘数,在ucos下,代表每个节拍的ms数
#if SYSTEM_SUPPORT_OS //如果SYSTEM_SUPPORT_OS定义了,说明要支持OS了(不限于UCOS).
//当delay_us/delay_ms需要支持OS的时候需要三个与OS相关的宏定义和函数来支持
//首先是3个宏定义:
// delay_osrunning:用于表示OS当前是否正在运行,以决定是否可以使用相关函数
//delay_ostickspersec:用于表示OS设定的时钟节拍,delay_init将根据这个参数来初始哈systick
// delay_osintnesting:用于表示OS中断嵌套级别,因为中断里面不可以调度,delay_ms使用该参数来决定如何运行
//然后是3个函数:
// delay_osschedlock:用于锁定OS任务调度,禁止调度
//delay_osschedunlock:用于解锁OS任务调度,重新开启调度
// delay_ostimedly:用于OS延时,可以引起任务调度.
//本例程仅作UCOSII和UCOSIII的支持,其他OS,请自行参考着移植
//支持UCOSII
#ifdef OS_CRITICAL_METHOD //OS_CRITICAL_METHOD定义了,说明要支持UCOSII
#define delay_osrunning OSRunning //OS是否运行标记,0,不运行;1,在运行
#define delay_ostickspersec OS_TICKS_PER_SEC //OS时钟节拍,即每秒调度次数
#define delay_osintnesting OSIntNesting //中断嵌套级别,即中断嵌套次数
#endif
//支持UCOSIII
#ifdef CPU_CFG_CRITICAL_METHOD //CPU_CFG_CRITICAL_METHOD定义了,说明要支持UCOSIII
#define delay_osrunning OSRunning //OS是否运行标记,0,不运行;1,在运行
#define delay_ostickspersec OSCfg_TickRate_Hz //OS时钟节拍,即每秒调度次数
#define delay_osintnesting OSIntNestingCtr //中断嵌套级别,即中断嵌套次数
#endif
//us级延时时,关闭任务调度(防止打断us级延迟)
void delay_osschedlock(void)
{
#ifdef CPU_CFG_CRITICAL_METHOD //使用UCOSIII
OS_ERR err;
OSSchedLock(&err); //UCOSIII的方式,禁止调度,防止打断us延时
#else //否则UCOSII
OSSchedLock(); //UCOSII的方式,禁止调度,防止打断us延时
#endif
}
//us级延时时,恢复任务调度
void delay_osschedunlock(void)
{
#ifdef CPU_CFG_CRITICAL_METHOD //使用UCOSIII
OS_ERR err;
OSSchedUnlock(&err); //UCOSIII的方式,恢复调度
#else //否则UCOSII
OSSchedUnlock(); //UCOSII的方式,恢复调度
#endif
}
//调用OS自带的延时函数延时
//ticks:延时的节拍数
void delay_ostimedly(u32 ticks)
{
#ifdef CPU_CFG_CRITICAL_METHOD
OS_ERR err;
OSTimeDly(ticks,OS_OPT_TIME_PERIODIC,&err); //UCOSIII延时采用周期模式
#else
OSTimeDly(ticks); //UCOSII延时
#endif
}
//systick中断服务函数,使用ucos时用到
void SysTick_Handler(void)
{
if(delay_osrunning==1) //OS开始跑了,才执行正常的调度处理
{
OSIntEnter(); //进入中断
OSTimeTick(); //调用ucos的时钟服务程序
OSIntExit(); //触发任务切换软中断
}
}
#endif
//初始化延迟函数
//当使用OS的时候,此函数会初始化OS的时钟节拍
//SYSTICK的时钟固定为HCLK时钟的1/8
//SYSCLK:系统时钟
void delay_init()
{
#if SYSTEM_SUPPORT_OS //如果需要支持OS.
u32 reload;
#endif
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //选择外部时钟 HCLK/8
fac_us=SystemCoreClock/8000000; //为系统时钟的1/8
#if SYSTEM_SUPPORT_OS //如果需要支持OS.
reload=SystemCoreClock/8000000; //每秒钟的计数次数 单位为M
reload*=1000000/delay_ostickspersec; //根据delay_ostickspersec设定溢出时间
//reload为24位寄存器,最大值:16777216,在72M下,约合1.86s左右
fac_ms=1000/delay_ostickspersec; //代表OS可以延时的最少单位
SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk; //开启SYSTICK中断
SysTick->LOAD=reload; //每1/delay_ostickspersec秒中断一次
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk; //开启SYSTICK
#else
fac_ms=(u16)fac_us*1000; //非OS下,代表每个ms需要的systick时钟数
#endif
}
#if SYSTEM_SUPPORT_OS //如果需要支持OS.
//延时nus
//nus为要延时的us数.
void delay_us(u32 nus)
{
u32 ticks;
u32 told,tnow,tcnt=0;
u32 reload=SysTick->LOAD; //LOAD的值
ticks=nus*fac_us; //需要的节拍数
tcnt=0;
delay_osschedlock(); //阻止OS调度,防止打断us延时
told=SysTick->VAL; //刚进入时的计数器值
while(1)
{
tnow=SysTick->VAL;
if(tnow!=told)
{
if(tnow<told)tcnt+=told-tnow; //这里注意一下SYSTICK是一个递减的计数器就可以了.
else tcnt+=reload-tnow+told;
told=tnow;
if(tcnt>=ticks)break; //时间超过/等于要延迟的时间,则退出.
}
};
delay_osschedunlock(); //恢复OS调度
}
//延时nms
//nms:要延时的ms数
void delay_ms(u16 nms)
{
if(delay_osrunning&&delay_osintnesting==0) //如果OS已经在跑了,并且不是在中断里面(中断里面不能任务调度)
{
if(nms>=fac_ms) //延时的时间大于OS的最少时间周期
{
delay_ostimedly(nms/fac_ms); //OS延时
}
nms%=fac_ms; //OS已经无法提供这么小的延时了,采用普通方式延时
}
delay_us((u32)(nms*1000)); //普通方式延时
}
#else //不用OS时
//延时nus
//nus为要延时的us数.
void delay_us(u32 nus)
{
u32 temp;
SysTick->LOAD=nus*fac_us; //时间加载
SysTick->VAL=0x00; //清空计数器
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //开始倒数
do
{
temp=SysTick->CTRL;
}while((temp&0x01)&&!(temp&(1<<16))); //等待时间到达
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器
SysTick->VAL =0X00; //清空计数器
}
//延时nms
//注意nms的范围
//SysTick->LOAD为24位寄存器,所以,最大延时为:
//nms<=0xffffff*8*1000/SYSCLK
//SYSCLK单位为Hz,nms单位为ms
//对72M条件下,nms<=1864
void delay_ms(u16 nms)
{
u32 temp;
SysTick->LOAD=(u32)nms*fac_ms; //时间加载(SysTick->LOAD为24bit)
SysTick->VAL =0x00; //清空计数器
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //开始倒数
do
{
temp=SysTick->CTRL;
}while((temp&0x01)&&!(temp&(1<<16))); //等待时间到达
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器
SysTick->VAL =0X00; //清空计数器
}
#endif