找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3353|回复: 2
收起左侧

基于51单片机的智能家居程序+电路设计

[复制链接]
ID:566620 发表于 2020-6-8 13:35 | 显示全部楼层 |阅读模式
智能家居基于51单片机控制, 同时外接DS1302DS18B20以及LCD液晶屏等,对智能家居智进行简易的控制。
该设计运用到的芯片:STC89C58+DS18B20+DHT11+DS1302+LCD12864+红外人体感应器+无线遥控
功能:
1.数字可调万年历
2.显示空气中温度和湿度
3.对环境温度和湿度可以自动控制
4.测量水的温度
5.无线控制
6.防盗报警
7.低功耗模式
8.开机图片
9.EEPROM数据保存
原理图设计:
图片2.png
图片1.png

单片机源程序如下:
  1. /***************************************************************/
  2. /*                  智能家居控制系统
  3.                       设计:刘东宇
  4.                                
  5.                                            2013.04                        
  6. 芯片:STC89C58+DS18B20+DHT11+DS1302+LCD12864+红外人体感应器+无线遥控
  7. 功能:1.数字可调万年历
  8.       2.显示空气中温度和湿度
  9.           3.对环境温度和湿度可以自动控制
  10.           4.测量水的温度
  11.           5.无线控制
  12.           6.防盗报警
  13.           7.低功耗模式
  14.           8.开机图片
  15.           9.EEPROM数据保存                                                                */
  16. /***************************************************************/

  17. #include<reg52.h>
  18. #include<absacc.h>
  19. #include<intrins.h>
  20. #include"LCD12864.h"
  21. #include"DS18B20.h"
  22. #include"DS1302.h"
  23. #include"delay_ms.h"
  24. #include"key.h"
  25. #include"DHT11.h"
  26. #include"start_logo.h"
  27. #include"picture.h"
  28. #include"Flash_ROM.h"
  29. /********************函数申明********************/
  30. void init();                                        //初始化程序
  31. void sleep_sign_init();                                //睡眠(报警)模式初始化
  32. void init_time_DHT11_DS18B20();                    //初始化定时器T0和T1
  33. void open_logo();                           //开机图片
  34. void kay_scan();                                            //kay_scan 按键扫描程序
  35. void display_time();                                    //display_time时间扫描(LCD12864显示)
  36. void alarm();                                                //温湿度超值判断
  37. void sleep_sign();                          //睡眠(报警)模式和正常模式切换函数
  38. void sos_display();                         //当声光报警时LCD12864显示“报警!”  
  39. /************位变量定义****************/
  40. sbit lcd_lig=P2^4;                          //LCD12864背光控制
  41. sbit relay1=P1^0;                          //继电器1
  42. sbit relay2=P1^1;                          //继电器2
  43. sbit voi_lig_sigo=P1^2;                  //声光报警控制位
  44. sbit key_sigo=P1^6;                          //睡眠(报警)模式进入按键
  45. /************变量定义****************/
  46. unsigned char code shu5[]={"0123456789"};
  47. unsigned char code shu6[]={"年月日:"};
  48. unsigned int k,T;
  49. bit Interrupt_flag=1;                              //该标志位可以有效防止报警触发后影响其他程序
  50. bit sos=0;                                    //LCD12864显示报警标志位

  51. void main()
  52. {   
  53.     init();                                                  //初始化程序
  54.         lcd_lig=0;                                  //开LCD背光
  55.         open_logo();                                  //开机LOGO
  56.         sleep_sign_init();                      //睡眠(报警)模式初始化
  57.         init_lcd12864();                          //初始化LCD12864       
  58.     init_time_DHT11_DS18B20();          //初始化定时器T0和T1
  59.         DS18B20_caution();            //DS18B20温度报警设置
  60.         while(1)
  61.         {       
  62.                    kay_scan();                                  //kay_scan 按键扫描程序       
  63.                  display_time();                          //display_time 时间显示扫描(LCD12864显示)
  64.                 alarm();                              //温湿度超值判断
  65.                 sleep_sign();             //睡眠(报警)模式和正常模式切换函数
  66.                 sos_display();                          //当声光报警时LCD12864显示“报警!”
  67.         }
  68. }

  69. /************************************************/
  70. /****************程序初始化**********************/
  71. /************************************************/
  72. void init()
  73. {
  74.   IAP_ReadCode(0x8000,&set_up_sd,1);                                  //读湿度阀值
  75.   IAP_ReadCode(0x800f,&set_up_wd,1);                                  //读温度阀值

  76.   relay1=1;                        //继电器1(湿度控制)
  77.   relay2=1;                        //继电器2(温度控制)

  78.   IP=0X0A;                                  //中断优先级设定,将定时器T0和T1设置为高级

  79.   sd_shi=0;
  80.   sd_ge=0;
  81.   wd_shi1=0;
  82.   wd_ge1=0;
  83.   dsq_0=0;                         //定时器T0
  84.    
  85. /***********DS1302初始化****************/
  86.    ds_io=0;
  87.    ds_rst=0;
  88.    ds_sclk=0;                    //DS1302初始化  
  89.    ds_xieshu(0x8e,0x00);    //控制
  90. }

  91. /*****************************************************/
  92. /**************睡眠(报警)模式初始化*****************/
  93. /*****************************************************/
  94. void sleep_sign_init()                  //睡眠(报警)模式初始化
  95. {
  96.    voi_lig_sigo=1;                          //初始化声光报警控制位
  97.    key2=1;                                          //初始化按键key2(睡眠报警模式进入键)
  98.    lcd_lig=0;                                  //LCD12864背光控制位

  99.    TCON=0X55;                       //INT0设置为下降沿触发,INT0设置为下降沿触发
  100.    EX0=1;                               //开外部中断INT0
  101.    EX1=0;                                           //关外部中断INT1
  102.    EA=1;                                           //开总中断
  103. }

  104. /**************************************/
  105. /********初始化计时器T0和T1************/
  106. /**************************************/
  107. void init_time_DHT11_DS18B20()         //初始化定时器T0和T1
  108. {
  109.            TMOD=0X11;                                         //定时器T0和T1工作于方式1

  110.         TH0=(65535-50000)/256;                 //给定时器T0装初值
  111.         TL0=(65535-50000)%256;
  112.         TR0=1;                                                 //开定时器T0计数
  113.         ET0=1;                                                 //开定时器T0中断

  114.         TH1=(65535-50000)/256;                  //给定时器T1装初值
  115.         TL1=(65535-50000)%256;
  116.         TR1=1;                                                  //开定时器T1计数
  117.         ET1=1;                                                  //开定时器T1中断
  118. }

  119. /************************************************/
  120. /****************  开机图片  ********************/
  121. /************************************************/
  122. void open_logo()
  123. {
  124.      display_bmp_logo(bmp_1);                        //写入图片1
  125.          delay(10000);
  126.          display_bmp_logo(bmp_2);                        //写入图片2
  127.          delay(10000);
  128.          display_bmp_logo(bmp_3);                        //写入图片3
  129.          delay(10000);
  130.          display_bmp_logo(bmp_4);                        //写入图片4
  131.          delay(10000);
  132.          display_bmp_logo(bmp_5);                        //写入图片5
  133.          delay(8000);
  134.          display_bmp_logo(bmp_6);                        //写入图片6
  135.          delay(8000);         
  136.          display_bmp_logo(bmp_7);                        //写入图片7
  137.          delay(8000);         
  138. }

  139. /************************************************/
  140. /****************温湿度报警检测******************/
  141. /************************************************/
  142. void alarm()                                            //温湿度超值判断
  143. {
  144.                 if(sign_sd>=set_up_sd)                    //湿度判断
  145.                     relay1=0;                        //继电器1(降湿度控制)
  146.             else
  147.                     relay1=1;                       
  148.                 if(sign_wd>=set_up_wd)                    //温度判断
  149.                     relay2=0;                        //继电器2(降温度控制)
  150.                 else
  151.                     relay2=1;       
  152. }

  153. /***************************************************/
  154. /*********************按键扫描程序******************/
  155. /***************************************************/
  156. void kay_scan()                                     //kay_scan按键扫描程序
  157. {
  158.              if(key1==0)                             
  159.            {
  160.              delay(20);                                  //按键消抖
  161.                  if(key1==0)
  162.                 {
  163.                     TR0=0;                                  //关温度和湿度扫描
  164.                     TR1=0;                                  //关水温扫描
  165.                        
  166.                     i=0;
  167.                     i++;
  168.                         miao=BCD_Decimal(ds_dushu(0x81));                //将现在显示的数值赋给要进行调整的变量
  169.                         fen=BCD_Decimal(ds_dushu(0x83));                //这样在调时间的时候就不会出现从0开始调整
  170.                         shi=BCD_Decimal(ds_dushu(0x85));                //这样就可以在原来的数值上进行调整
  171.                         xq=BCD_Decimal(ds_dushu(0x8b));
  172.                         ri=BCD_Decimal(ds_dushu(0x87));
  173.                         yue=BCD_Decimal(ds_dushu(0x89));
  174.                         nian=BCD_Decimal(ds_dushu(0x8d));
  175.                         shidu=set_up_sd;                                    //将湿度当前值赋给要调节的值
  176.                         wendu=set_up_wd;                                          //将温度当前值赋给要调节的值
  177.                         if(i>=9)                                                                //可以直接将9改成1
  178.                           i=1;
  179.                         delay(20);
  180.                     while(key1==0);                                                         //松手检测
  181.                         delay(20);
  182.                         while(key1==0);
  183.                         while(i)                                                                 //当i大于0时进入按键扫描死循环,当i=0时跳出该循环
  184.                     key();                                                     //扫描按键
  185.                 }               
  186.           }
  187. }

  188. /*****************************************************/
  189. /**************LCD12864 display时间扫描***************/
  190. /*****************************************************/
  191. void display_time()                               //display_time时间扫描(LCD12864显示)
  192. {
  193.            qushu_time(ds_dushu(0X81));        //秒
  194.            delay(1);
  195.            zhiling(0x88+6);
  196.            delay(1);
  197.            shuju(shu5[shi]);
  198.            delay(1);
  199.            shuju(shu5[ge]);
  200.            delay(1);
  201.            shuju(' ');
  202.            shuju(' ');
  203.            delay(1);
  204.        
  205.            qushu_time(ds_dushu(0X83));         //分
  206.            delay(1);
  207.            zhiling(0x88+4);
  208.            delay(1);
  209.            shuju(shu5[shi]);
  210.            delay(1);
  211.            shuju(shu5[ge]);
  212.            delay(1);
  213.            shuju(':');
  214.            shuju(' ');
  215.            delay(1);

  216.            qushu_time(ds_dushu(0X85));          //时
  217.            delay(1);
  218.            zhiling(0x88);
  219.            delay(1);
  220.            shuju(0xca);
  221.            shuju(0xb1);
  222.            delay(1);
  223.            shuju(0xbc);
  224.            shuju(0xe4);
  225.            delay(1);
  226.            shuju(shu5[shi]);
  227.            delay(1);
  228.            shuju(shu5[ge]);
  229.            delay(1);
  230.            shuju(':');
  231.            shuju(' ');
  232.            delay(1);

  233.            qushu_time(ds_dushu(0X8b));         //星期
  234.            delay(1);
  235.            zhiling(0x90);
  236.            delay(1);
  237.            shuju(0xd0);
  238.            shuju(0xc7);
  239.            delay(1);
  240.            shuju(0xc6);
  241.            shuju(0xda);
  242.            delay(1);
  243.            shuju(shu5[ge]);
  244.            shuju(' ');
  245.            delay(1);                     

  246.            qushu_time(ds_dushu(0X87));         // 日
  247.            delay(1);
  248.            zhiling(0x80+5);
  249.            delay(1);
  250.            shuju(shu5[shi]);
  251.            delay(1);
  252.            shuju(shu5[ge]);
  253.            delay(1);
  254.            shuju(0xc8);                                 //日       
  255.            shuju(0xd5);                                 //日
  256.            delay(1);       
  257.            shuju(' ');                                 //       
  258.            shuju(' ');                                 //
  259.            delay(1);       

  260.            qushu_time(ds_dushu(0X89));         //月
  261.            delay(1);
  262.            zhiling(0x80+3);
  263.            delay(1);
  264.            shuju(shu5[shi]);
  265.            delay(10);
  266.            shuju(shu5[ge]);
  267.            delay(1);
  268.            shuju(0xd4);                                 //月       
  269.            shuju(0xc2);                                 //月
  270.            delay(1);
  271.           
  272.            qushu_time(ds_dushu(0X8d));        //年
  273.            delay(1);
  274.            zhiling(0x80);
  275.            delay(1);
  276.            shuju('2');                                 //2
  277.            shuju('0');                                 //0
  278.            delay(1);
  279.            shuju(shu5[shi]);
  280.            delay(1);
  281.            shuju(shu5[ge]);
  282.            delay(1);
  283.            shuju(0xc4);                                 //年
  284.            shuju(0xea);                                 //年
  285.            delay(1);
  286. }

  287. /*****************************************************/
  288. /*******进入低功耗模式(报警模式)的按键检测**********/
  289. /*****************************************************/
  290. void sleep_sign()
  291. {
  292.    if(Interrupt_flag)
  293.          {
  294.        if(!key_sigo)
  295.            {
  296.                 delay(5);
  297.                 if(!key_sigo)
  298.                  {                          
  299.                    lcd_lig=1;
  300.                    key2=1;                                   //初始化按键key2(睡眠报警模式进入键)
  301.                    voi_lig_sigo=1;                   //初始化声光报警控制位
  302.                    relay1=1;                   //继电器1(湿度控制)
  303.            relay2=1;                   //继电器2(温度控制)       
  304.                    zhiling(0x08);               //LCD12864进入睡眠模式
  305.                    P0=0XFF;                                      //初始化所有IO口,防止干扰出现
  306.                    P1=0XFF;
  307.                    P2=0XFF;
  308.                    P3=0XFF;
  309.                    delay(10);
  310.                    EX1=1;                                      //打开人体感应报警中断
  311.                    PCON=0X02;                       //51单片机进入掉电模
  312.                  }
  313.            }
  314.          }
  315. }

  316. /************************************************/
  317. /*******当声光报警时LCD12864显示“报警!”**********/
  318. /************************************************/
  319. void sos_display()                                                //当声光报警时LCD12864显示“报警!”
  320. {
  321.     while(sos)                                                        //判断是否报警
  322.         {
  323.           display_bmp_logo(bmp_8);                        //写入图片8
  324.           if(!sos)
  325.           init_lcd12864();                                //初始化LCD12864       
  326.         }
  327. }

  328. /***************************************************************/
  329. /*kay按键中断,进入报警(休眠)模式和退出该模式(也是唤醒中断)*/
  330. /***************************************************************/
  331. void sleep_int0() interrupt 0        //kay按键中断,进入报警(休眠)模式和退出该模式(也是唤醒中断)
  332. {
  333.         Interrupt_flag=1;
  334.                 voi_lig_sigo=1;                             //关闭报警
  335.               zhiling(0x0c);                         //将LCD12864从睡眠模式唤醒
  336.                 lcd_lig=0;                                 //打开LCD12864背光               
  337.                 EX1=0;                                                  //关闭人体感应报警中断
  338.                 TR0=1;                                         //开温度和湿度扫描
  339.                 TR1=1;                                         //开水温扫描
  340.                 sos=0;                                                 //LCD12864取消显示“报警!”
  341. }

  342. /*****************************************************/
  343. /****人体感应模式中断(报警中断,也是唤醒中断)*******/
  344. /*****************************************************/
  345. void voi_lig_int1() interrupt 2             //人体感应模式中断(报警中断,也是唤醒中断)
  346. {
  347.         Interrupt_flag=0;
  348.                voi_lig_sigo=0;                             //开起报警
  349.                 zhiling(0x0c);                         //将LCD12864从睡眠模式唤醒
  350.                 lcd_lig=0;;                                 //打开LCD12864背光
  351.                 EX1=0;                                                 //关闭人体感应报警中断
  352.                 TR0=0;                                         //开温度和湿度扫描
  353.                 TR1=0;                                         //开水温扫描
  354.                 sos=1;                                                 //LCD12864显示“报警!”
  355. }

  356. /**************************************/
  357. /********计时器T0中断函数DHT11*********/
  358. /**************************************/
  359. void time0_DHT11() interrupt 1          //定时器T0中断,DHT11数据读取程序
  360. {
  361.         TH0=(65535-50000)/256;
  362.         TL0=(65535-50000)%256;
  363.           dsq_0++;
  364.         if(dsq_0==20)
  365.         {
  366.        TR1=0;                                           //关定时器T1
  367.            ET1=0;          

  368.            dsq_0=0;
  369.            w_s=return_wendu_shidu();
  370.            qushu_DHT11(w_s);                  //读取温度湿度
  371.            delay(1);

  372.            TR1=1;                                           //开定时器T1
  373.            ET1=1;
  374.         }
  375. }

  376. /**************************************/
  377. /********计时器T1中断函数DS18B20*******/
  378. /**************************************/
  379. void time1_DS18B20() interrupt 3  //定时器T1中断函数DS18B20,DHT11数据显示程序
  380. {                                                              //T1中断函数(中断里面程序的运行时间要在50ms以内,此处中断程序运行为8.753ms)
  381.         TH0=(65535-50000)/256;
  382.         TL0=(65535-50000)%256;
  383.         k++;
  384.         if(k==20)
  385.         {
  386.            TR0=0;                                                  //关定时器T0
  387.            ET0=0;
  388.           
  389.                 k=0;
  390.                 T=return_wendu_DS18B20();          //读取温度
  391.             qushu_DS18B20(T);                          //分离温度数值
  392.             
  393.           /*****************************************/
  394.           /*  display水的温度*/
  395.           /******************************************/  
  396.             delay(10);
  397.                 zhiling(0x90+3);
  398.                 delay(1);
  399.                 shuju(0xcb);                                 //水
  400.             shuju(0xae);                                 //
  401.             delay(1);
  402.                 shuju(0xce);                                 //温
  403.             shuju(0xc2);                                 //
  404.             delay(1);
  405.                 shuju(shu5[wd_shi]);           //温度十位
  406.                 delay(1);
  407.                 shuju(shu5[wd_ge]);               //温度个位
  408.                 delay(1);
  409.                 shuju('.');                               //小数点
  410.                 delay(1);
  411.                 shuju(shu5[wd_xiao1]);           //温度小数0.1位
  412.                 delay(1);
  413.                 shuju(0xa1);                   //显示℃(本来为温度小数0.01位 )
  414.                 shuju(0xe6);                   //显示℃(本来为温度小数0.01位 )

  415.           /*****************************************/
  416.           /*  display环境的温度和湿度,注:本来下面的
  417.              这段display应该是放在定时器T0中断函数中
  418.                  但是那样会对显示产生印象,所以选择同时写入,
  419.                  也介于LCD12864屏幕的特点,第二行的地址和第
  420.                  四行地址是连在一起的*/
  421.           /******************************************/
  422.             zhiling(0x98);
  423.                 delay(1);                 
  424.                 shuju(0xca);                                 //湿
  425.             shuju(0xaa);                                 //
  426.             delay(1);
  427.                 shuju(0xb6);                                 //度
  428.             shuju(0xc8);                                 //
  429.             delay(1);
  430.             shuju(shu5[sd_shi]);              //湿度十位
  431.             delay(1);
  432.             shuju(shu5[sd_ge]);                  //湿度个位
  433.             delay(1);
  434.             shuju(0xa3);                                 //%
  435.             shuju(0xa5);                                 //
  436.             delay(1);
  437.                 shuju(0xce);                                 //温
  438.             shuju(0xc2);                                 //
  439.             delay(1);
  440.                 shuju(0xb6);                                 //度
  441.             shuju(0xc8);                                 //
  442.             delay(1);
  443.             shuju(shu5[wd_shi1]);               //温度十位
  444.             delay(1);
  445.             shuju(shu5[wd_ge1]);               //温度个位
  446.             delay(1);
  447.             shuju(0xa1);                       //显示℃
  448.             shuju(0xe6);                       //显示℃
  449.                
  450.                 TR0=1;                                               //开定时器T0
  451.             ET0=1;       
  452.          }               
  453. }
复制代码

所有资料51hei提供下载:
原理图.zip (36.87 KB, 下载次数: 73)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:570917 发表于 2020-6-11 20:00 | 显示全部楼层
感谢楼主分享
回复

使用道具 举报

ID:772623 发表于 2020-6-12 14:27 | 显示全部楼层
感谢楼主分享
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表