找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 9085|回复: 8
收起左侧

懒人专用智能房间控制器设计(单片机源码+蓝牙APP+原理图PCB)

  [复制链接]
ID:238191 发表于 2018-9-2 14:51 | 显示全部楼层 |阅读模式
作者:落叶风的作品
先看下硬件设计,使用的是单片机STC12C5A60S2,共有8路输入,其中4路是隔离的,低电平为开,输出也是8路,4个继电器,4个可控硅,为了简化可控硅的控制电路,采用5V的隔离电源隔开,有6个开关,开关1-5分别对应的4个可控硅及1个继电器输出,开关6是用于显示翻页及设置用,短按为翻页,长按为进入当前页的设置,再短按为改变设置项目,再长按为保存设置,开关5当处于设置时,就为调整参数,如不处于设置状态时,为继电器1控制。继电器2设置有一组定时开关功能,是采用触发方式的。显示用0.96寸的OLED显示器,温度湿度用DHT11模块。带有无线遥控功能,控制开关1-4,由于是测试板,所以输入输出元件没有装齐,只装部份进行测试,但单片机及手机软件并没偷工减料,所想到的都写上去了,但由于没实际环境中使用过,可能有BUG。
0.jpg
必须为开源者落叶风大神点赞,这技术绝对牛哄哄。
捕获.PNG
电路原理图如下:
0.png

制作出来的pcb实物图如下:
0.jpg

手机软件方面,是第一次写手机软件,自己有用中文编程软件易语言写过小软件,所以看了几天易安卓的教程,就写这手机软件,由于还不熟悉这编程软件,特别是它的数组操作搞不清楚,所以手机软件源代码上基本上是变量以文本型为主,软件的基本功能齐全,有显示控制窗口口、设置窗口及定时设置窗,能直接操作控制单片机的开关及参数的修改。
当手机软件正常开启后,会把手机当前时间发送个授时命令给单片机,根据单片机设置情况,进行授时操作。

OLED显示屏用来显示一些数据,和进行相关设置显示。
0.png
蓝牙转串口模块,是HC-06从机蓝牙模块,已用命令把它的波特率改为19200。采用引线引出来,方便测试。
0.png

315无线模块
0.png

单片机源程序如下:
  1. //蓝牙房间控制器
  2. //编写时间为2015-6-2
  3. //时钟用22.1M,cpu用STC12C5A60

  4. #include <STC12C5A60S2.h>
  5. #include <intrins.h>
  6. unsigned char oldkey,keyval,pagevol,bbtemp;
  7. unsigned int keyjixu ,jisu,tempxidu;
  8. bit BBkongvol,readtimekong,time05s,dingkong,timeauto,rscRSkong;
  9. unsigned char t_sec,t_min,t_hour,t_1224ji;
  10. unsigned char timetao,settao,RSzhuantai2,recRSjisu;
  11. unsigned char dingon_hour,dingon_min,dingoff_hour,dingoff_min;
  12. unsigned char recRSvol[6];
  13. extern void OLED_Init(void);
  14. extern void OLED_Clear(void);
  15. extern void OLED_ShowCHinese(unsigned char x,unsigned char y,unsigned char no);
  16. extern void OLED_ShowString(unsigned char x,unsigned char y, unsigned char *p);
  17. extern void OLED_ShowChar(unsigned char x,unsigned char y,unsigned char chr);
  18. extern void OLED_32X16(unsigned char x,unsigned char y,unsigned char c);
  19. //外部引用DS1302子程序
  20. extern void write_time(unsigned char temp1,temp2);
  21. extern unsigned char read_time(unsigned char hangmu);
  22. extern void DS1302ini();
  23. sbit KEY1=P1^0;
  24. sbit KEY2=P1^1;
  25. sbit KEY3=P1^4;
  26. sbit KEY4=P1^5;
  27. sbit KEY5=P1^6;
  28. sbit KEY6=P1^7;
  29. sbit BB=P4^7;
  30. sbit OUT1=P2^7;
  31. sbit OUT2=P2^6;
  32. sbit OUT3=P2^5;
  33. sbit OUT4=P2^4;
  34. sbit OUT5=P2^3;
  35. sbit OUT6=P2^2;
  36. sbit OUT7=P2^1;
  37. sbit OUT8=P2^0;
  38. sbit DHT11DA=P3^6;
  39. void delay(unsigned int t) //长延时程序,延时t毫秒,STC 1T单片机11.0592M晶振I值为648,22.1I值为1298,12MI值为705。
  40. {
  41.          unsigned int i;
  42.          while(t--)
  43.            {
  44.                 for(i=1298;i>0;i--);
  45.            }
  46. }
  47.   
  48. void delay10us() //延时10us,STC 1T单片机11.0592M晶振J值为23,22。1MJ值为51。
  49. {

  50.    unsigned char j;
  51.    for(j=51;j>0;j--);
  52. }

  53. //======================EEPROW偏程==============================
  54. //写字节时,可以将原有数据中的1改为0,无法将0改为1,只能使用擦除命令将0改为1
  55. //应注意,擦除命令会将整个扇区擦除
  56. //由于擦除会将整个扇区擦除,为了方便写,所以这里用第二扇区存第一屏的状态,
  57. //第三扇区存定时1的5个时间,每个时间有启用、开时间、关时间、星期(8b)
  58. //第四扇区存定时6-10,第5扇区存温度值,
  59. // 第二扇区地址0x0200-0x03ff,0x0400-0x05ff,0x0600-0x07ff,0x0800-0x09ff.
  60. void IAPIDLE()
  61. {
  62.     IAP_CMD = 0;      //关闭令,保护
  63.     IAP_CONTR = 0;    //关EEPROM,保护
  64.     IAP_TRIG = 0;
  65.     IAP_ADDRL = 0; //设置读取地址的低字节,地址改变才需要设置
  66.     IAP_ADDRH = 0X80; //设置读取地址的高字节,地址改变才需要设置
  67. }
  68. unsigned char readEEP(unsigned int adddata)
  69. {        //读取
  70.         unsigned char eerdata;
  71.         IAP_CONTR=0X83;//设置等待时间,1MHz以下取7,2M以下取6,3M取5,6M取4,12M取3,20M取2,24M取1,30M取0,前导1表示许档IAP
  72.         IAP_CMD = 1;      //读取值1,写取2,擦除取3,擦除时按所在字节整个扇区撺除
  73.         IAP_ADDRL = adddata;    //设置读取地址的低字节,地址改变才需要设置
  74.     IAP_ADDRH = adddata>>8; //设置读取地址的高字节,地址改变才需要设置
  75.         IAP_TRIG = 0x5A;  //先送5A
  76.     IAP_TRIG = 0xA5;  //先送5A再送A5立即触发
  77.         _nop_();
  78.         eerdata=IAP_DATA;
  79.         IAPIDLE();
  80.         return eerdata;
  81. }
  82. void writeEEP(unsigned int adddata, unsigned char eerdata)
  83. {//写入
  84.   IAP_CONTR=0X83;//设置等待时间,
  85.   IAP_CMD = 2;      //读取值1,写取2,擦除取3,擦除时按所在字节整个扇区撺除
  86.   IAP_ADDRL = adddata;    //设置读取地址的低字节,地址改变才需要设置
  87.   IAP_ADDRH = adddata>>8; //设置读取地址的高字节,地址改变才需要设置
  88.   IAP_DATA=        eerdata;//传入数据
  89.   IAP_TRIG = 0x5A;  //先送5A
  90.   IAP_TRIG = 0xA5;  //先送5A再送A5立即触发
  91.   _nop_();
  92.   IAPIDLE();
  93. }
  94. void eraseEEP(unsigned int adddata)
  95. { //擦除
  96.    IAP_CONTR=0X83;//设置等待时间,
  97.   IAP_CMD = 3;      //读取值1,写取2,擦除取3,擦除时按所在字节整个扇区撺除
  98.   IAP_ADDRL = adddata;    //设置读取地址的低字节,地址改变才需要设置
  99.   IAP_ADDRH = adddata>>8; //设置读取地址的高字节,地址改变才需要设置
  100.   IAP_TRIG = 0x5A;  //先送5A
  101.   IAP_TRIG = 0xA5;  //先送5A再送A5立即触发
  102.   _nop_();
  103.   IAPIDLE();
  104. }
  105. void writeDAT()
  106. {
  107.         eraseEEP(0x0200);
  108. writeEEP(0x0200, dingkong);//定时状态
  109. writeEEP(0x0201, dingon_hour); // 开时
  110. writeEEP(0x0202, dingon_min);//开分
  111. writeEEP(0x0203, dingoff_hour);//关时
  112. writeEEP(0x0204, dingoff_min);//关分
  113. writeEEP(0x0205, BBkongvol);//按键不发声
  114. writeEEP(0x0206, timeauto);//自动校时
  115. }
  116. void timedisp()   //时间提取。这里只读时分秒及星期,时采用24小时制。
  117. {
  118.   unsigned char        i,j,times,timeg;
  119.           i =read_time(0x84);//读时,这里还要判断是24小时制还是12小时制。
  120.      if(i>=0x80)
  121.                                   {           //12小时
  122.                                              //只是小时的数值是最后5位为小时值,所以时的取法先置高3位为0,再除法及求余法。
  123.                                          
  124.                                          times=(i&0x1f)/16;//取高4位的数值给十分。
  125.                                      timeg=i%16;//取低4位数值,把高4位置0。
  126.                                      t_hour=times*10+timeg;
  127.                                          j=i<<2;
  128.                                          if(j>=0x80)
  129.                                          {
  130.                        t_1224ji=1;//12小时制,0为24小时制。
  131.                        if(t_hour!=12){t_hour=t_hour+12;}//转为24小时,方便计算。
  132.                                          }
  133.                                          else
  134.                                          {
  135.                                          t_1224ji=1;        //2为上午。
  136.                      if(t_hour==12)t_hour=0;//转为24小时,方便计算。
  137.                                          }
  138.                                   }
  139.                                   else
  140.                                   {                //24小时
  141.                                          times=i/16;//取高4位的数值给十分。
  142.                                     timeg=i%16;//取低4位数值,把高4位置0。
  143.                                         t_hour=times*10+timeg;
  144.                                         t_1224ji=0;//24小时制

  145.                                   }

  146.   i=read_time(0x82);//读分
  147.   times=i/16;
  148.   timeg=i%16;
  149.   t_min=times*10+timeg;
  150.   i =read_time(0x80);//读秒
  151.   times=i/16;
  152.   timeg=i%16;
  153.   t_sec=times*10+timeg;//算出当前秒数。

  154. }
  155. void disppage0(bit xaxin)
  156. {//当为0时,全屏更新,为1只刷新部份
  157.         unsigned int kaka;
  158.         
  159.         if(xaxin==0)
  160.         {
  161.         OLED_Clear();
  162. //        蓝牙房间控制
  163.         OLED_ShowCHinese(16,0,0);
  164.         OLED_ShowCHinese(32,0,1);
  165.         OLED_ShowCHinese(48,0,2);
  166.         OLED_ShowCHinese(64,0,3);
  167.         OLED_ShowCHinese(80,0,4);
  168.         OLED_ShowCHinese(96,0,5);
  169.         }
  170. //18:55:23 36C 75%
  171.         if(timetao==1&&time05s!=0)
  172.         {
  173.                 OLED_ShowChar(0,2,13);
  174.         OLED_ShowChar(8,2,13);
  175.         }
  176.         else
  177.         {
  178.   OLED_ShowChar(0,2,t_hour/10);
  179.         OLED_ShowChar(8,2,t_hour%10);
  180.         }
  181.         if(time05s!=0&&timetao==0)
  182.         {
  183.         OLED_ShowChar(16,2,13);
  184.                 OLED_ShowChar(40,2,13);
  185.         }
  186.         else
  187.         {
  188.                 OLED_ShowChar(16,2,10);
  189.                 OLED_ShowChar(40,2,10);
  190.         }
  191.         if(timetao==2&&time05s!=0)
  192.         {
  193.                 OLED_ShowChar(24,2,13);
  194.           OLED_ShowChar(32,2,13);
  195.         }
  196.         else
  197.         {
  198.         OLED_ShowChar(24,2,t_min/10);
  199.         OLED_ShowChar(32,2,t_min%10);
  200.         }
  201.         if(timetao==3&&time05s!=0)
  202.         {
  203.                 OLED_ShowChar(48,2,13);
  204.          OLED_ShowChar(56,2,13);
  205.         }
  206.         else
  207.         {
  208.         OLED_ShowChar(48,2,t_sec/10);
  209.         OLED_ShowChar(56,2,t_sec%10);
  210.         }
  211.         kaka=tempxidu%256;
  212.         OLED_ShowChar(72,2,kaka/10);
  213.         OLED_ShowChar(80,2,kaka%10);
  214.         OLED_ShowChar(88,2,11);
  215.         kaka=tempxidu/256;
  216.         OLED_ShowChar(104,2,kaka/10);
  217.         OLED_ShowChar(112,2,kaka%10);
  218.         OLED_ShowChar(120,2,12);
  219. //开关状态        
  220. //读P0值,低电平为开,
  221.         if((P0&0x01)==0)
  222.         {        
  223.          OLED_ShowCHinese(0,4,7);
  224.         }
  225.         else
  226.         {
  227.                 OLED_ShowCHinese(0,4,15);
  228.         }
  229.         if((P0&0x02)==0)
  230.         {
  231. OLED_ShowCHinese(16,4,8);
  232.         }
  233.         else
  234.         {
  235.                 OLED_ShowCHinese(16,4,16);
  236.         }
  237.         if((P0&0x04)==0)
  238.         {
  239. OLED_ShowCHinese(32,4,9);
  240.         }
  241.         else
  242.         {
  243.                 OLED_ShowCHinese(32,4,17);
  244.         }
  245.         if((P0&0x08)==0)
  246.         {
  247. OLED_ShowCHinese(48,4,10);
  248.         }
  249.         else
  250.         {
  251.                  OLED_ShowCHinese(48,4,18);
  252.         }
  253.         if((P0&0x10)==0)
  254.         {
  255. OLED_ShowCHinese(64,4,11);
  256.         }
  257.         else
  258.         {
  259.                 OLED_ShowCHinese(64,4,19);
  260.         }
  261.         if((P0&0x20)==0)
  262.         {
  263.                 OLED_ShowCHinese(80,4,12);
  264.         }
  265.         else
  266.         {
  267. OLED_ShowCHinese(80,4,20);
  268.         }
  269.         if((P0&0x40)==0)
  270.         {
  271. OLED_ShowCHinese(96,4,13);
  272.         }
  273.         else
  274.         {
  275.                  OLED_ShowCHinese(96,4,21);
  276.         }
  277.         if((P0&0x80)==0)
  278.         {
  279. OLED_ShowCHinese(112,4,14);
  280.         }
  281.         else
  282.         {
  283.                 OLED_ShowCHinese(112,4,22);
  284.         }
  285. //灯及插座工作状态
  286. if(OUT1==0)
  287. {//低电平为开
  288. OLED_ShowCHinese(0,6,27);
  289. }
  290. else
  291. {
  292.          OLED_ShowCHinese(0,6,23);
  293. }
  294. if(OUT2==0)
  295. {//低电平为开
  296. OLED_ShowCHinese(16,6,28);
  297. }
  298. else
  299. {
  300.          OLED_ShowCHinese(16,6,24);
  301. }
  302. if(OUT3==0)
  303. {//低电平为开
  304. OLED_ShowCHinese(32,6,29);
  305. }
  306. else
  307. {
  308.          OLED_ShowCHinese(32,6,25);
  309. }
  310. if(OUT4==0)
  311. {//低电平为开
  312. OLED_ShowCHinese(48,6,30);
  313. }
  314. else
  315. {
  316.          OLED_ShowCHinese(48,6,26);
  317. }
  318. if(OUT5==0)
  319. {//低电平为开
  320. OLED_ShowCHinese(64,6,35);
  321. }
  322. else
  323. {
  324.          OLED_ShowCHinese(64,6,31);
  325. }
  326. if(OUT6==0)
  327. {//低电平为开
  328. OLED_ShowCHinese(80,6,36);
  329. }
  330. else
  331. {
  332.          OLED_ShowCHinese(80,6,32);
  333. }
  334. if(OUT7==0)
  335. {//低电平为开
  336.   OLED_ShowCHinese(96,6,37);
  337. }
  338. else
  339. {
  340.          OLED_ShowCHinese(96,6,33);
  341. }
  342. if(OUT8==0)
  343. {//低电平为开
  344. OLED_ShowCHinese(112,6,38);
  345. }
  346. else
  347. {
  348.          OLED_ShowCHinese(112,6,34);
  349. }
  350. }
  351. void disppage1(bit xaxin)
  352. {//当为0时,全屏更新,为1只刷新部份
  353.         if(xaxin==0)
  354.         {
  355.         OLED_Clear();
  356.         //插座2定时设置
  357.         OLED_ShowCHinese(0,0,41);
  358.         OLED_ShowCHinese(16,0,42);
  359.         OLED_ShowChar(32,0,2);
  360.         OLED_ShowCHinese(40,0,43);
  361.         OLED_ShowCHinese(56,0,44);
  362.         OLED_ShowCHinese(72,0,45);
  363.         OLED_ShowCHinese(88,0,46);
  364.    }
  365.         //选中  22:10-23:55
  366.          if(settao==1&&time05s!=0)
  367.          {
  368.           OLED_ShowCHinese(0,2,6);
  369.          }
  370.          else
  371.          {
  372.                  if(dingkong==0)
  373.                  {//当为0时不定时
  374.                  OLED_ShowCHinese(0,2,40);
  375.                  }
  376.                  else
  377.                  {
  378.                          OLED_ShowCHinese(0,2,39);
  379.                  }
  380.          }
  381.           if(settao==2&&time05s!=0)
  382.                 {
  383.            OLED_ShowChar(16,2,13);
  384.            OLED_ShowChar(24,2,13);
  385.                 }
  386.                 else
  387.                 {
  388.                  OLED_ShowChar(16,2,dingon_hour/10);
  389.            OLED_ShowChar(24,2,dingon_hour%10);
  390.                 }
  391.         OLED_ShowChar(32,2,10);
  392.         if(settao==3&&time05s!=0)
  393.         {
  394.   OLED_ShowChar(40,2,13);
  395.         OLED_ShowChar(48,2,13);
  396.         }
  397.   else
  398.   {        
  399.         OLED_ShowChar(40,2,dingon_min/10);
  400.         OLED_ShowChar(48,2,dingon_min%10);
  401.   }
  402.         OLED_ShowChar(56,2,14);
  403.         if(settao==4&&time05s!=0)
  404.         {
  405.   OLED_ShowChar(64,2,13);
  406.         OLED_ShowChar(72,2,13);
  407.         }
  408.   else
  409.   {        
  410.         OLED_ShowChar(64,2,dingoff_hour/10);
  411.         OLED_ShowChar(72,2,dingoff_hour%10);
  412.         }
  413.         OLED_ShowChar(80,2,10);
  414.         if(settao==5&&time05s!=0)
  415.         {
  416.   OLED_ShowChar(88,2,13);
  417.         OLED_ShowChar(96,2,13);
  418.         }
  419.   else
  420.   {        
  421.         OLED_ShowChar(88,2,dingoff_min/10);
  422.         OLED_ShowChar(96,2,dingoff_min%10);
  423.         }
  424.         
  425. //不选中 按键发声
  426. if(settao==6&&time05s!=0)
  427.         {         
  428. OLED_ShowCHinese(0,4,6);
  429.         }
  430.         else
  431.         {
  432.                 if(BBkongvol==0)
  433.                 {
  434.                 OLED_ShowCHinese(0,4,40);
  435.                 }
  436.                 else
  437.                 {
  438.                         OLED_ShowCHinese(0,4,39);
  439.                 }
  440.         }
  441.          if(xaxin==0)
  442.          {
  443.         OLED_ShowCHinese(16,4,47);
  444. OLED_ShowCHinese(32,4,48);
  445. OLED_ShowCHinese(48,4,52);
  446. OLED_ShowCHinese(64,4,53);
  447. //OLED_ShowCHinese(80,4,53);
  448.          }
  449. //不选中 自动效时
  450. if(settao==7&&time05s!=0)
  451.         {         
  452. OLED_ShowCHinese(0,6,6);
  453.         }
  454.         else
  455.         {
  456.                 if(timeauto==0)
  457.                 {
  458.                 OLED_ShowCHinese(0,6,40);
  459.                 }
  460.                 else
  461.                 {
  462.                         OLED_ShowCHinese(0,6,39);
  463.                 }
  464.         }
  465.          if(xaxin==0)
  466.          {
  467.         OLED_ShowCHinese(16,6,49);
  468. OLED_ShowCHinese(32,6,50);
  469. OLED_ShowCHinese(48,6,54);
  470. OLED_ShowCHinese(64,6,55);
  471.          }
  472. }

  473. //***********************键盘扫描子程序。******************
  474. //*********************************************************
  475. unsigned char keyboard()//键盘扫描
  476. {
  477.       unsigned char keyboardj;
  478.      keyboardj=0;
  479.     if(KEY1==0)
  480.           {
  481.         delay(10);
  482.                   if(KEY1==0)
  483.                   {
  484.                           keyboardj=1;
  485.                   }
  486.       }
  487.     if(KEY2==0)
  488.            {
  489.         delay(10);
  490.                   if(KEY2==0)
  491.                   {
  492.                           keyboardj=2;
  493.                   }
  494.       }
  495.          if(KEY3==0)
  496.            {
  497.         delay(10);
  498.                   if(KEY3==0)
  499.                   {
  500.                           keyboardj=3;
  501.                   }
  502.       }
  503.            if(KEY4==0)
  504.           {
  505.         delay(10);
  506.                   if(KEY4==0)
  507.                   {
  508.                           keyboardj=4;
  509.                   }
  510.       }
  511.     if(KEY5==0)
  512.            {
  513.         delay(10);
  514.                   if(KEY5==0)
  515.                   {
  516.                           keyboardj=5;
  517.                   }
  518.       }
  519.          if(KEY6==0)
  520.            {
  521.         delay(10);
  522.                   if(KEY6==0)
  523.                   {
  524.                           keyboardj=6;
  525.                   }
  526.       }
  527.    return  keyboardj;
  528. }
  529. //************键盘控制子程序***************
  530. //K2短按为开电源,关机显----,正常显铬铁实际温度,长按为调铬铁温度,最后个C闪,表示调温,再长按为存储并退出调温。
  531. //K3K1分别为向上向下,短按为慢速增加减少,长按为快速。调节范围为200-480度。
  532. //******************************************
  533. void keydisphong()//主要功能是
  534. {
  535.    unsigned char keyyy;
  536.    keyyy=keyboard();
  537.   if (keyyy!=oldkey)
  538.         {
  539.                 if(keyyy==0)//
  540.       {        
  541.                                 if(keyjixu>0)
  542.                                 {
  543.                                         if(keyjixu<80)
  544.                                         {
  545.                                                 
  546.                                                 if(oldkey==6)
  547.                                                 {
  548.                                                         keyval=6;
  549.                                                 }
  550.                                                 if(oldkey==5)
  551.                                                 {
  552.                                                         keyval=5;
  553.                                                 }
  554.                                         }
  555.                                         else
  556.                                         {
  557.                                                 //keyval=11;
  558.                                                 keyjixu=0;
  559.                                         }
  560.                                 }
  561.                                 else
  562.                                 {
  563.                                         keyval=0;
  564.                                   keyjixu=0;
  565.                                 }
  566.                         }
  567.                 if(keyyy==1)
  568.                 {
  569.                         if(OUT1==0)
  570.                         {
  571.                                 OUT1=1;
  572.                         }
  573.                         else
  574.                         {
  575.                                 OUT1=0;
  576.                         }
  577.                         
  578.                 }
  579.                 if(keyyy==2)
  580.                 {
  581.                         if(OUT2==0)
  582.                         {
  583.                                 OUT2=1;
  584.                         }
  585.                         else
  586.                         {
  587.                                 OUT2=0;
  588.                         }
  589.                 }
  590.                 if(keyyy==3)
  591.                 {
  592.                         if(OUT3==0)
  593.                         {
  594.                                 OUT3=1;
  595.                         }
  596.                         else
  597.                         {
  598.                                 OUT3=0;
  599.                         }
  600.                 }
  601.                 if(keyyy==4)
  602.                 {
  603.                         if(OUT4==0)
  604.                         {
  605.                                 OUT4=1;
  606.                         }
  607.                         else
  608.                         {
  609.                                 OUT4=0;
  610.                         }
  611.                 }
  612.                 if(keyyy!=0)
  613.                 {        
  614.                         //刷新
  615.                         if(pagevol==0&&keyval!=6)disppage0(1);
  616.                         if(BBkongvol==1)
  617.                         {//当BB可以发声,就
  618.                           BB=1;//发响声。
  619.                     bbtemp=15;//
  620.                         }
  621.                 }
  622.         }
  623.   oldkey=keyyy;
  624.    if(keyyy==5)//
  625.       {
  626.                                 keyjixu++;
  627.                                 if(keyjixu>=80)
  628.                                 {
  629.                                         if((keyjixu%6)==0)
  630.                                         {
  631.                                         keyval=15;
  632.                                         }
  633.                                 }
  634.                         }        
  635.         if(keyyy==6)//
  636.       {
  637.                                 keyjixu++;
  638.                                 if(keyjixu==80)keyval=16;
  639.                         }
  640.                  
  641.          //键盘处理完成。
  642. //以下为功能子程序        
  643. if(keyval==5)
  644.                 {
  645.                  keyval=0;//这步必须的,清键值。
  646.                         keyjixu=0;//清计数值,这两步是必要的。        
  647.     if(timetao==0&&settao==0)
  648.                         {
  649.                         //当不处于调整时,就控电器5
  650.                         if(OUT5==0)
  651.                         {
  652.                                 OUT5=1;
  653.                         }
  654.                         else
  655.                         {
  656.                                 OUT5=0;
  657.                         }
  658.                  }
  659.                  else
  660.                  {
  661.                         if(pagevol==0)
  662.                         {
  663.                                 if(timetao==1)
  664.                                 {//调时
  665.                                         t_hour++;
  666.                                         if(t_hour>23)t_hour=0;
  667.                                         OLED_ShowChar(0,2,t_hour/10);
  668.                 OLED_ShowChar(8,2,t_hour%10);
  669.                                 }
  670.                                 if(timetao==2)
  671.                                 {//调分
  672.                                         t_min++;
  673.                                         if(t_min>59)t_min=0;
  674.                                         OLED_ShowChar(24,2,t_min/10);
  675.                 OLED_ShowChar(32,2,t_min%10);
  676.                                 }
  677.                                 if(timetao==3)
  678.                                 {//调秒
  679.                                         t_sec++;
  680.                                         if(t_sec>59)t_sec=0;
  681.                                         OLED_ShowChar(48,2,t_sec/10);
  682.                 OLED_ShowChar(56,2,t_sec%10);
  683.                                 }
  684.                                 
  685.                         }
  686.                         else
  687.                         {
  688.                                 if(settao==1)
  689.                                 {//调定时
  690.                                         if(dingkong==0)
  691.                                         {
  692.                                                 dingkong=1;
  693.                                         }
  694.                                         else
  695.                                         {
  696.                                                 dingkong=0;
  697.                                         }
  698.                                 }
  699.                                 if(settao==2)
  700.                                 {//调开时
  701.                                         dingon_hour++;
  702.                                         if(dingon_hour>23)dingon_hour=0;
  703.                                         OLED_ShowChar(16,2,dingon_hour/10);
  704.                OLED_ShowChar(24,2,dingon_hour%10);
  705.                                 }
  706.                                 if(settao==3)
  707.                                 {//调开分
  708.                                         dingon_min++;
  709.                                         if(dingon_min>59)dingon_min=0;
  710.                                         OLED_ShowChar(40,2,dingon_min/10);
  711.                 OLED_ShowChar(48,2,dingon_min%10);
  712.                                 }
  713.                                 if(settao==4)
  714.                                 {//调关时
  715.                                         dingoff_hour++;
  716.                                         if(dingoff_hour>23)dingoff_hour=0;
  717.                                         OLED_ShowChar(64,2,dingoff_hour/10);
  718.                OLED_ShowChar(72,2,dingoff_hour%10);
  719.                                 }
  720.                                 if(settao==5)
  721.                                 {//调关分
  722.                                         dingoff_min++;
  723.                                         if(dingoff_min>59)dingoff_min=0;
  724.                                         OLED_ShowChar(88,2,dingoff_min/10);
  725.                 OLED_ShowChar(96,2,dingoff_min%10);
  726.                                 }
  727.                                 if(settao==6)
  728.                                 {//调发声
  729.                                         if(BBkongvol==0)
  730.                                         {
  731.                                                 BBkongvol=1;
  732.                                         }
  733.                                         else
  734.                                         {
  735.                                                 BBkongvol=0;
  736.                                         }
  737.                                 }
  738.                                 if(settao==7)
  739.                                 {//调自动校时
  740.                                         if(timeauto==0)
  741.                                         {
  742.                                                 timeauto=1;
  743.                                         }
  744.                                         else
  745.                                         {
  746.                                                 timeauto=0;
  747.                                         }
  748.                                 }
  749.                         }
  750.                         
  751.                  }
  752.                 }                        
  753.                 if(keyval==6)
  754.                 {
  755.                  keyval=0;//这步必须的,清键值。
  756.                         keyjixu=0;//清计数值,这两步是必要的。
  757.                         if(timetao==0&&settao==0)
  758.                         {
  759.                         if(pagevol==0)
  760.                         {
  761.                                 pagevol=1;
  762.                                 disppage1(0);
  763.                         }
  764.                         else
  765.                         {
  766.                                 pagevol=0;
  767.                                 disppage0(0);
  768.                         }
  769.                  }
  770.                  else
  771.                  {
  772.                          if(pagevol==0)
  773.                          {
  774.                                  timetao++;
  775.                                  if(timetao==4)
  776.                                  {
  777.                                          timetao=1;
  778.                                          
  779.                                  }
  780.                    }
  781.                          else
  782.                          {
  783.                                  settao++;
  784.                                  if(settao==8)
  785.                                  {
  786.                                          settao=1;
  787.                                        
  788.                                  }
  789.                          }
  790.                  }
  791.                 }        
  792.                         if(keyval==15)
  793.                 {
  794.                  keyval=0;//这步必须的,清键值。
  795.                         //keyjixu=0;//清计数值,这两步是必要的。
  796.                         if(pagevol==0)
  797.                         {
  798.                                 if(timetao==1)
  799.                                 {//调时
  800.                                         t_hour++;
  801.                                         if(t_hour>23)t_hour=0;
  802.                                         OLED_ShowChar(0,2,t_hour/10);
  803.                 OLED_ShowChar(8,2,t_hour%10);
  804.                                 }
  805.                                 if(timetao==2)
  806.                                 {//调分
  807.                                         t_min++;
  808.                                         if(t_min>59)t_min=0;
  809.                                         OLED_ShowChar(24,2,t_min/10);
  810.                 OLED_ShowChar(32,2,t_min%10);
  811.                                 }
  812.                                 if(timetao==3)
  813.                                 {//调秒
  814.                                         t_sec++;
  815.                                         if(t_sec>59)t_sec=0;
  816.                                         OLED_ShowChar(48,2,t_sec/10);
  817.                 OLED_ShowChar(56,2,t_sec%10);
  818.                                 }
  819.                                 
  820.                         }
  821.                         else
  822.                         {
  823.                                 if(settao==2)
  824.                                 {//调开时
  825.                                         dingon_hour++;
  826.                                         if(dingon_hour>23)dingon_hour=0;
  827.                                         OLED_ShowChar(16,2,dingon_hour/10);
  828.                OLED_ShowChar(24,2,dingon_hour%10);
  829.                                 }
  830.                                 if(settao==3)
  831.                                 {//调开分
  832.                                         dingon_min++;
  833.                                         if(dingon_min>59)dingon_min=0;
  834.                                         OLED_ShowChar(40,2,dingon_min/10);
  835.                 OLED_ShowChar(48,2,dingon_min%10);
  836.                                 }
  837.                                 if(settao==4)
  838.                                 {//调关时
  839.                                         dingoff_hour++;
  840.                                         if(dingoff_hour>23)dingoff_hour=0;
  841.                                         OLED_ShowChar(64,2,dingoff_hour/10);
  842.                OLED_ShowChar(72,2,dingoff_hour%10);
  843.                                 }
  844.                                 if(settao==5)
  845.                                 {//调关分
  846.                                         dingoff_min++;
  847.                                         if(dingoff_min>59)dingoff_min=0;
  848.                                         OLED_ShowChar(88,2,dingoff_min/10);
  849.                 OLED_ShowChar(96,2,dingoff_min%10);
  850.                                 }
  851.                                 
  852.                         }
  853.                 }
  854.                 if(keyval==16)
  855.                 {//长按进入设置及退出设置
  856.                  keyval=0;//这步必须的,清键值。
  857.                         //keyjixu=0;//清计数值,这两步是必要的。
  858.                         if(pagevol==0)
  859.                         {
  860.                                 if(timetao==0)
  861.                                 {
  862.                            timetao=1;
  863.                                 }
  864.                                 else
  865.                                 {//保存数据
  866.                                         timetao=0;
  867.                                         write_time(0X84,(t_hour/10)*16+t_hour%10);//时
  868.                                         write_time(0X82,(t_min/10)*16+t_min%10);//写分
  869.                                         write_time(0X80,(t_sec/10)*16+t_sec%10);//写秒
  870.                                 }
  871.                         }
  872.                         else
  873.                         {
  874.                                 if(settao==0)
  875.                                 {
  876.                          settao=1;
  877.                                 }
  878.                                 else
  879.                                 {//保存数据
  880.                                         settao=0;
  881.                                         writeDAT();
  882.                                 }
  883.                         }
  884.                 }
  885.                
  886. }

  887. void dingtimekong()
  888. {//定时控制,采用触发式。每0.5S比较一次
  889.         if(dingkong==1)
  890.         {
  891.            if(dingon_hour==t_hour&&dingon_min==t_min)OUT6=0;
  892.                  if(dingoff_hour==t_hour&&dingoff_min==t_min)OUT6=1;
  893.         }
  894. }

  895. unsigned char DHT11readbit()
  896. {
  897.   unsigned char i,temp,dataDHT,caoxi;
  898.   for(i=0;i<8;i++)           
  899.         {
  900.          //数据时序先低电平50us,再高电平,当26-28us为0、70us为1。        
  901.          caoxi=2;
  902.          while((!DHT11DA)&&caoxi++);//检测50us低电平是否过去。
  903.          delay10us();delay10us();delay10us();//延时30us,再判断,如还是高电平就数据为1,如低电平为0。         
  904.          temp=0;   //先置0
  905.          if(DHT11DA)temp=1;        //超过30us还是高电平的就置1。         
  906.          caoxi=2;
  907.          while((DHT11DA)&&caoxi++);//如还是高电平就等它为低电平,如超时就跳出循环.         
  908.          //超时则跳出for循环                  
  909.          if(caoxi==1)break;
  910.                    //合成数据
  911.           dataDHT<<=1;
  912.           dataDHT|=temp;           
  913.    }
  914.    return(dataDHT);
  915. }
  916. unsigned int DHT11read() //由于返回的温度及湿度只有2个8b,所以用个16b的来存贮,前8位为湿度,后8位为温度。
  917. {
  918.   unsigned char temp1,temp2,temp3,temp4,temp5,caoxi;
  919.   unsigned int DHTdata ;
  920.   //主机拉低大于18ms
  921.   DHT11DA=0;
  922.   delay(20);
  923.   DHT11DA=1;
  924.   //主机放开总线,由上拉电阻拉高 主机延时20us-40us.
  925.   delay10us();delay10us();delay10us();delay10us();
  926.   //判断从机是否有低电平响应信号 如不响应则跳出,响应则向下读数。
  927.   if(DHT11DA==0)
  928.     {
  929.           caoxi=2;//初始化超时值,对于22M晶振为175us,主要是防止DHT不动作引起程序进入死循环,超时就跳出来。
  930.           while((!DHT11DA)&&caoxi++);
  931.          //判断从机是否发出 80us 的高电平,如发出则进入数据接收状态
  932.           caoxi=2;
  933.           while((DHT11DA)&&caoxi++);         
  934.          //数据接收状态                           
  935.           temp1=DHT11readbit();         
  936.           temp2=DHT11readbit();         
  937.           temp3=DHT11readbit();         
  938.           temp4=DHT11readbit();         
  939.           temp5=DHT11readbit();
  940.          //数据校验
  941.           DHT11DA=1;
  942.           if(temp5=(temp1+temp2+temp3+temp4)) //如校对正确就组合数据,并返回。
  943.             {
  944.                  DHTdata=temp1*256+temp3;
  945.                 }
  946.                 else
  947.                 {
  948.                  DHTdata=0;//当数据不正确时,就送0值,当然这一步看情况来决定是否用它。
  949.                 }
  950.         }
  951.    return(DHTdata); //返回数据

  952. }
  953. void rs2232tx(unsigned char txdata)//串口2发送程序
  954. {         
  955. S2BUF=txdata;//把数据传给串口寄存器SBUF。
  956. while(!(S2CON & 0x02));//检测是否发完。
  957. //S2TI=0;//重置初值。
  958.         S2CON=S2CON & 0xfd;
  959. }
  960. void senddata()
  961. {//串口数据发送,命令格式EF,EE,P0(低7位开关状态),P2(低7位输出状态),P0P2第8位(主要是防止与引导码冲突),温度,湿度,定时状态,开时,开分,关时,关分,FF 不进行校验数据。
  962.         //为方便手机编程,传送的数据用BCD码
  963.         unsigned char kkkkk,hhhh;
  964.         rs2232tx(0xef);
  965.         rs2232tx(0xee);
  966.         rs2232tx(P0&0x7f);
  967.         rs2232tx(P2&0x7f);
  968.         kkkkk=0;
  969.         if((P0&0x80)!=0)
  970.         {
  971.                 kkkkk=kkkkk+2;
  972.         }
  973.         if((P2&0x80)!=0)
  974.         {
  975.                 kkkkk=kkkkk+1;
  976.         }
  977.         rs2232tx(kkkkk);
  978.         kkkkk=tempxidu%256;
  979.         hhhh=(kkkkk/10)*16+kkkkk%10;
  980.         rs2232tx(hhhh);
  981.         kkkkk=tempxidu/256;
  982.         hhhh=(kkkkk/10)*16+kkkkk%10;
  983.         rs2232tx(hhhh);
  984.         rs2232tx(dingkong);
  985.         kkkkk=dingon_hour;
  986.         hhhh=(kkkkk/10)*16+kkkkk%10;
  987.         rs2232tx(hhhh);
  988.         kkkkk=dingon_min;
  989.         hhhh=(kkkkk/10)*16+kkkkk%10;
  990.         rs2232tx(hhhh);
  991.         kkkkk=dingoff_hour;
  992.         hhhh=(kkkkk/10)*16+kkkkk%10;
  993.         rs2232tx(hhhh);
  994.         kkkkk=dingoff_min;
  995.         hhhh=(kkkkk/10)*16+kkkkk%10;
  996.         rs2232tx(hhhh);
  997.         rs2232tx(0xff);
  998. }
  999. void rscRSkongji()
  1000. {//串口数据接收后处理子程序
  1001.         //开关控制 命令 01 受控值,00,00,00,00
  1002.         //校时控制 命令 02  时 分 秒 00 00
  1003.         //定时控制 命令 03 受控值 开时 开分 关时 关分
  1004.         if(rscRSkong==1)
  1005.         {//收到处理的数据
  1006.                
  1007.                 switch(recRSvol[0])
  1008.                 {
  1009.                         case 1:     
  1010.                                 if((recRSvol[1]&0x01)!=0)
  1011.                                 {//当手机开关1按下
  1012.                                         if(OUT1==0)
  1013.                                         {
  1014.                                         OUT1=1;
  1015.                                   }
  1016.                                         else
  1017.                                         {
  1018.                                                 OUT1=0;
  1019.                                         }
  1020.                                 }
  1021.                                 if((recRSvol[1]&0x02)!=0)
  1022.                                 {//当手机开关1按下
  1023.                                         if(OUT2==0)
  1024.                                         {
  1025.                                         OUT2=1;
  1026.                                   }
  1027.                                         else
  1028.                                         {
  1029.                                                 OUT2=0;
  1030.                                         }
  1031.                                 }
  1032.        if((recRSvol[1]&0x04)!=0)
  1033.                                 {//当手机开关1按下
  1034.                                         if(OUT3==0)
  1035.                                         {
  1036.                                         OUT3=1;
  1037.                                   }
  1038.                                         else
  1039.                                         {
  1040.                                                 OUT3=0;
  1041.                                         }
  1042.                                 }
  1043.        if((recRSvol[1]&0x08)!=0)
  1044.                                 {//当手机开关1按下
  1045.                                         if(OUT4==0)
  1046.                                         {
  1047.                                         OUT4=1;
  1048.                                   }
  1049.                                         else
  1050.                                         {
  1051.                                                 OUT4=0;
  1052.                                         }
  1053.                                 }
  1054.        if((recRSvol[1]&0x10)!=0)
  1055.                                 {//当手机开关1按下
  1056.                                         if(OUT5==0)
  1057.                                         {
  1058.                                         OUT5=1;
  1059.                                   }
  1060.                                         else
  1061.                                         {
  1062.                                                 OUT5=0;
  1063.                                         }
  1064.                                 }
  1065.        if((recRSvol[1]&0x20)!=0)
  1066.                                 {//当手机开关1按下
  1067.                                         if(OUT6==0)
  1068.                                         {
  1069.                                         OUT6=1;
  1070.                                   }
  1071.                                         else
  1072.                                         {
  1073.                                                 OUT6=0;
  1074.                                         }
  1075.                                 }
  1076.       if((recRSvol[1]&0x40)!=0)
  1077.                                 {//当手机开关1按下
  1078.                                         if(OUT7==0)
  1079.                                         {
  1080.                                         OUT7=1;
  1081.                                   }
  1082.                                         else
  1083.                                         {
  1084.                                                 OUT7=0;
  1085.                                         }
  1086.                                 }
  1087.        if((recRSvol[1]&0x80)!=0)
  1088.                                 {//当手机开关1按下
  1089.                                         if(OUT8==0)
  1090.                                         {
  1091.                                         OUT8=1;
  1092.                                   }
  1093.                                         else
  1094.                                         {
  1095.                                                 OUT8=0;
  1096.                                         }
  1097.                                 }                                
  1098.                                 break;
  1099.                         case 2:
  1100.                                 //手机自动校时,当手机建立连接时,如需自动校时,就启用。这是在串口中断程序内执行。
  1101.                                 if(timeauto==1)
  1102.                                 {
  1103.           write_time(0X84,(recRSvol[1]/10)*16+recRSvol[1]%10);//时
  1104.                                         write_time(0X82,(recRSvol[2]/10)*16+recRSvol[2]%10);//写分
  1105.                                         write_time(0X80,(recRSvol[3]/10)*16+recRSvol[3]%10);//写秒                                                
  1106.                                 }
  1107.                                 break;
  1108.                         case 3: //需BCD码转16进
  1109.                                  dingkong=recRSvol[1];
  1110.                            dingon_hour=(recRSvol[2]/16)*10+recRSvol[2]%16;
  1111.                            dingon_min=(recRSvol[3]/16)*10+recRSvol[3]%16;
  1112.                            dingoff_hour=(recRSvol[4]/16)*10+recRSvol[4]%16;
  1113.                            dingoff_min=(recRSvol[5]/16)*10+recRSvol[5]%16;
  1114.                             writeDAT();
  1115.                                 break;
  1116.                          default:   break;
  1117.                 }
  1118.                
  1119.                 rscRSkong=0;
  1120.         }
  1121.         
  1122. }
  1123. void sysintEEP()
  1124. {
  1125.         dingkong=readEEP(0x0200);//定时状态
  1126.         dingon_hour=readEEP(0x0201); // 开时
  1127.         
  1128. ……………………

  1129. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
0.png 0.png

所有资料51hei提供下载:
蓝牙手机控制的懒人专用智能房间控制器设计资料.rar (1.11 MB, 下载次数: 244)

评分

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

查看全部评分

回复

使用道具 举报

ID:89072 发表于 2018-9-2 18:44 | 显示全部楼层
很实用,wifi模块还没搞明白,谢谢楼主
回复

使用道具 举报

ID:104477 发表于 2018-9-8 19:29 来自手机 | 显示全部楼层
蓝牙有源码吗
回复

使用道具 举报

ID:459616 发表于 2019-1-1 22:37 | 显示全部楼层
谢谢楼主,学习了
回复

使用道具 举报

ID:238191 发表于 2019-7-27 15:41 | 显示全部楼层

文件里有APP的
回复

使用道具 举报

ID:400515 发表于 2019-10-24 16:03 | 显示全部楼层
来学习了
回复

使用道具 举报

ID:440637 发表于 2019-11-13 17:07 | 显示全部楼层
有APP吗?
回复

使用道具 举报

ID:250820 发表于 2020-3-4 21:56 | 显示全部楼层

谢谢楼主,学习了
回复

使用道具 举报

ID:517951 发表于 2020-11-15 16:29 | 显示全部楼层
不错,值得学习。51hei有你更精彩!!
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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