赞
踩
功能:
0.本系统采用STC89C52作为单片机
1.LCD1602液晶实时显示当前温度/湿度/光强/晾衣架状态
2.支持手动/自动两种模式
3.自动模式下,当温度>10/湿度<90/光强>80同时满足时,晾衣架将自动晾晒
4.采用DC002作为电源接口可直接输入5V给整个系统供电
原理图:
PCB :
主程序:
/************************************************************* 智能晾衣架 补充说明: ***************************************************************/ #include <reg52.h> //头文件 #include "stdio.h" #include "delay.h" #include "lcd1602.h" #include "28BYJ48.h" #include "tlc0832.h" #include "dht11.h" #include "infrared.h" #define uchar unsigned char //宏定义 #define uint unsigned int /*******************引脚定义*********************/ sbit KEY_MODE = P2^0; //自动/手动 sbit KEY_OUT = P2^1; //晾晒 sbit KEY_IN = P2^2; //回收 /*******************变量定义*********************/ bit modeFlag = 0; //模式标记。=0手动,=1自动 uint light; //光强 uint humidity; //湿度 uint temp; //温度 uint motorCnt = 0; //记录晾衣架位置 uchar motorFlag = 2; //标记当前控制状态,=0已经晾晒,=1过程中,=2已经回收 bit motorDir = 0; //方向 bit dispFlag = 0; bit g_irFlag = 0; //红外接收标志,收到一帧正确数据后置1 unsigned char g_irCode[4]; uchar dis0[5]; /************************* 宏定义 *************************/ #define AUTO 0 #define MANUAL 1 /************************* 函数声明 *************************/ void Timer0_Init(void); //初始化定时器0 /******************************************************** 函数名称:void mian() 函数作用:主函数 参数说明: ********************************************************/ void main() { IR_INPUT = 1; modeFlag = MANUAL; Timer0_Init(); //初始化定时器0 IR_Init(); LCD_Init(); //初始化液晶 DelayMs(200); //延时有助于稳定 LCD_Clear(); //清屏 LCD_DispStr(0, 0, "Temp: 0.0 C"); //显示温度 LCD_DispOneChar(10, 0, 0xdf); //温度的点 LCD_DispStr(0, 1, "HM: 0% LG: 0%"); while (1) //死循环 { if (dispFlag == 1) { dispFlag = 0; DHT11_ReadData(); //读取温湿度值 humidity = U8RH_data_H; temp = U8T_data_H; light = 100 - 100 * ReadADC(AIN0_GND) / 255; //读取光强 sprintf(dis0, "%3d", temp); LCD_DispStr(5, 0, dis0); sprintf(dis0, "%3d", humidity); LCD_DispStr(3, 1, dis0); sprintf(dis0, "%3d", light); LCD_DispStr(12, 1, dis0); } if (KEY_MODE == 0) { DelayMs(50); if (KEY_MODE == 0) { modeFlag = ~modeFlag; } while (KEY_MODE == 0) ; } else if (g_irFlag == 1 && g_irCode[2] == IRCodeMap[8][0]) { modeFlag = ~modeFlag; g_irFlag = 0; } if (modeFlag == AUTO) { LCD_DispOneChar(13, 0, 'A'); if (motorFlag == 2) //已经回收状态 { LCD_DispOneChar(15, 0, 'C'); if (temp > 10 && humidity < 90 && light > 80) //当温度湿度和光强满足条件时,晾晒衣服 { motorFlag = 1; motorDir = 1; motorCnt = 0; } } else if (motorFlag == 0) //已经晾晒状态 { LCD_DispOneChar(15, 0, 'O'); if (temp > 10 && humidity < 90 && light > 80) //当温度湿度和光强满足条件时,晾晒衣服 { ; } else { motorFlag = 1; motorDir = 0; motorCnt = 128; } } } else { LCD_DispOneChar(13, 0, 'M'); if (motorFlag == 2) //已经回收状态 { LCD_DispOneChar(15, 0, 'C'); if (KEY_OUT == 0) //当温度湿度和光强满足条件时,晾晒衣服 { DelayMs(50); if (KEY_OUT == 0) { motorFlag = 1; motorDir = 1; motorCnt = 0; } while (KEY_OUT == 0) ; } else if (g_irFlag == 1 && g_irCode[2] == IRCodeMap[7][0]) { motorFlag = 1; motorDir = 1; motorCnt = 0; g_irFlag = 0; } } else if (motorFlag == 0) //已经晾晒状态 { LCD_DispOneChar(15, 0, 'O'); if (KEY_IN == 0) //当温度湿度和光强满足条件时,晾晒衣服 { DelayMs(50); if (KEY_IN == 0) { motorFlag = 1; motorDir = 0; motorCnt = 128; } while (KEY_IN == 0) ; } else if (g_irFlag == 1 && g_irCode[2] == IRCodeMap[6][0]) { motorFlag = 1; motorDir = 0; motorCnt = 128; g_irFlag = 0; } } } if (motorFlag == 1) { LCD_DispOneChar(15, 0, 'D'); if (motorDir == 1) { motorCnt++; motor_z(); if (motorCnt == 128) { motorFlag = 0; } } else { motorCnt--; motor_f(); if (motorCnt == 0) { motorFlag = 2; } } } } } /*------------------------------------------------ 定时器初始化子程序 ------------------------------------------------*/ void Timer0_Init(void) { TMOD |= 0x01; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响 TH0 = (65536 - 18432) / 256; //重新赋值 20ms TL0 = (65536 - 18432) % 256; EA = 1; //总中断打开 ET0 = 1; //定时器中断打开 TR0 = 1; //定时器开关打开 } /*------------------------------------------------ 定时器中断子程序 ------------------------------------------------*/ void Timer0_Interrupt(void) interrupt 1 { static unsigned char time20ms = 0; TH0 = (65536 - 18432) / 256; //重新赋值 20ms TL0 = (65536 - 18432) % 256; time20ms++; if (time20ms > 50) { time20ms = 0; dispFlag = 1; //显示标志位置1 } } /************************************************************************************************** *************************************红外解码定时器程序******************************************** **************************************************************************************************/ //外部中断解码程序_外部中断1 void Ext1_Interrupt(void) interrupt 2 { unsigned char i, j; unsigned char byt; unsigned int time; time = IR_GetLowTime(); if ((time < 7833) || (time > 8755)) { IE1 = 0; return; } //找到启始码 time = IR_GetHighTime(); if ((time < 3686) || (time > 4608)) //时间判定范围为4.0~5.0ms, { //超过此范围则说明为误码,直接退出 IE1 = 0; return; } //接收并判定后续的4 字节数据 for (i = 0; i < 4; i++) //循环接收4 个字节 { for (j = 0; j < 8; j++) //循环接收判定每字节的8 个bit { //接收判定每bit 的560us 低电平 time = IR_GetLowTime(); if ((time < 313) || (time > 718)) //时间判定范围为340~780us, { //超过此范围则说明为误码,直接退出 IE1 = 0; return; } //接收每bit 高电平时间,判定该bit 的值 time = IR_GetHighTime(); if ((time > 313) && (time < 718)) //时间判定范围为340~780us, { //在此范围内说明该bit 值为0 byt >>= 1; //因低位在先,所以数据右移,高位为0 } else if ((time > 1345) && (time < 1751)) //时间判定范围为1460~1900us, { //在此范围内说明该bit 值为1 byt >>= 1; //因低位在先,所以数据右移, byt |= 0x80; //高位置1 } else //不在上述范围内则说明为误码,直接退出 { IE1 = 0; return; } } g_irCode[i] = byt; //接收完一个字节后保存到缓冲区 } g_irFlag = 1; //接收完毕后设置标志 IE1 = 0; //退出前清零INT1 中断标志 } /************************************************************************************************** *************************************************************************************************** **************************************************************************************************/
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。