找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3245|回复: 2
打印 上一主题 下一主题
收起左侧

单片机蓝牙智能窗帘程序

  [复制链接]
跳转到指定楼层
楼主


单片机源程序如下:
  1. #include <reg52.h>          //调用单片机头文件
  2. #define uchar unsigned char  //无符号字符型 宏定义 变量范围0~255
  3. #define uint  unsigned int  //无符号整型 宏定义 变量范围0~65535
  4. bit flag_200ms ;
  5. uchar menu_1,menu_2,a_a;
  6. uchar flag_kaig_moshi=0;//开关模式
  7. uchar flag_zd_sd;    //自动 手动 模式
  8. uchar k_shi=1,k_fen=2; //定时开窗
  9. uchar g_shi=3,g_fen=4; //定时关窗
  10. sbit beep = P2^7;     //蜂鸣器IO口定义
  11. sbit dq   = P1^6;   //18b20 IO口的定义
  12. uint temperature ;    //温度变量
  13. uint t_high = 50;                  //高温报警值
  14. sbit DO=P3^0;  //DO定义,连接ADC0832DO脚
  15. sbit SCL=P3^1;  //SCL定义,连接ADC0832SCL脚
  16. sbit CS=P3^3;  //CS定义,连接ADC0832CS脚
  17. uchar guanxian,guanxian_set = 50;     //光线
  18. uchar flag_z_f;        //正反标志位  0为顺时钟 1为逆时史上转
  19. unsigned char code zheng[4]={0xf8,0xf4,0xf2,0xf1};//正转表格
  20. unsigned char code fan[4]={0xf1,0xf2,0xf4,0xf8};//反转表格
  21. uint bjdj_value;   //步进电机的量
  22. uchar bjdj_zidong;   //步进电机的量 自动
  23. uchar key_can;  //按键值
  24. bit flag_lj_en;   //按键连加使能
  25. uchar code table_num[]="0123456789abcdefg";
  26. sbit rs=P1^0;  //寄存器选择信号 H:数据寄存器   L:指令寄存器
  27. sbit rw=P1^1;  //寄存器选择信号 H:数据寄存器   L:指令寄存器
  28. sbit e =P1^2;  //片选信号   下降沿触发
  29. sbit clk = P1^3;   //ds1302时钟线定义
  30. sbit io =  P1^4;   //数据线
  31. sbit rst = P1^5;   //复位线
  32.       //秒  分   时   日   月  年   星期  
  33. uchar code write_add[]={0x80,0x82,0x84,0x86,0x88,0x8c,0x8a};   //写地址
  34. uchar code read_add[] ={0x81,0x83,0x85,0x87,0x89,0x8d,0x8b};   //读地址
  35. uchar code init_ds[]  ={0x58,0x00,0x00,0x01,0x01,0x13,0x1};   
  36. uchar miao,fen,shi,ri,yue,week,nian;
  37. uchar i;
  38. sbit hw_P32=P3^2;    //红外遥控IO口的定义
  39. bit flag_jiema_en = 0; //红外解码成功标志位
  40. uchar hw_table[4];    //红外解码数据缓冲区

  41. /***********100us的延时函数***12M晶振**************/
  42. void delay_100us(uchar z)
  43. {    //12M
  44.    uchar x,y;
  45.    for(x=0;x<z;x++)
  46.      for(y=0;y<10;y++);
  47. }

  48. /*************写一个数据到对应的地址里***************/
  49. void write_ds1302(uchar add,uchar dat)
  50. {  
  51. rst = 1;    //把复位线拿高
  52. for(i=0;i<8;i++)
  53. {         //低位在前
  54.   clk = 0;   //时钟线拿低开始写数据
  55.   io = add & 0x01;     
  56.   add >>= 1;   //把地址右移一位
  57.   clk = 1;   //时钟线拿高
  58. }
  59. for(i=0;i<8;i++)
  60. {
  61.   clk = 0;   //时钟线拿低开始写数据
  62.   io = dat & 0x01;
  63.   dat >>= 1;   //把数据右移一位
  64.   clk = 1;   //时钟线拿高
  65. }
  66. rst = 0;    //复位线合低
  67. clk = 0;
  68. io = 0;
  69. }
  70. /*************从对应的地址读一个数据出来***************/
  71. uchar read_ds1302(uchar add)
  72. {
  73. uchar value,i;
  74. rst = 1;    //把复位线拿高
  75. for(i=0;i<8;i++)
  76. {         //低位在前
  77.   clk = 0;   //时钟线拿低开始写数据
  78.   io = add & 0x01;     
  79.   add >>= 1;   //把地址右移一位
  80.   clk = 1;   //时钟线拿高
  81. }  
  82. for(i=0;i<8;i++)
  83. {
  84.   clk = 0;   //时钟线拿低开始读数据
  85.   value >>= 1;
  86.   if(io == 1)
  87.    value |= 0x80;
  88.   clk = 1;   //时钟线拿高
  89. }
  90. rst = 0;    //复位线合低
  91. clk = 0;
  92. io = 0;
  93. return value;   //返回读出来的数据
  94. }

  95. /*************把要的时间 年月日 都读出来***************/
  96. void read_time()
  97. {
  98. miao = read_ds1302(read_add[0]); //读秒
  99. fen  = read_ds1302(read_add[1]); //读分
  100. shi  = read_ds1302(read_add[2]); //读时
  101. ri   = read_ds1302(read_add[3]); //读日
  102. yue  = read_ds1302(read_add[4]); //读月
  103. nian = read_ds1302(read_add[5]); //读年
  104. week = read_ds1302(read_add[6]); //读星期
  105. }
  106. /*************把要写的时间 年月日 都写入ds1302里***************/
  107. void write_time()
  108. {
  109. write_ds1302(0x8e,0x00);   //打开写保护
  110. write_ds1302(write_add[0],miao); //写秒
  111. write_ds1302(write_add[1],fen);  //写分
  112. write_ds1302(write_add[2],shi);  //写时
  113. write_ds1302(write_add[3],ri);  //写日
  114. write_ds1302(write_add[4],yue);  //写月
  115. write_ds1302(write_add[5],nian); //写星期
  116. write_ds1302(write_add[6],week); //写年
  117. write_ds1302(0x8e,0x80);   //关闭写保护
  118. }

  119. /**********************设置ds1302时间函数**********************/
  120. void set_ds1302time(uchar num,uchar *shi,uchar dat)  //调时
  121. {
  122.    if(num == 1)
  123.     {
  124.      *shi+=0x01;
  125.   if((*shi & 0x0f) >= 0x0a)
  126.    *shi = (*shi & 0xf0) + 0x10;
  127.   if(*shi >= dat)
  128.    *shi = 0;
  129.     }
  130.     else
  131.     {
  132.   if(*shi == 0x00)
  133.    *shi = dat;
  134.   if((*shi & 0x0f) == 0x00)
  135.    *shi = (*shi | 0x0a) - 0x10;
  136.   *shi -=0x01 ;
  137.     }  
  138. }


  139. /******************1ms 延时函数*******************/
  140. void delay_1ms(uint q)
  141. {
  142. uint i,j;
  143. for(i=0;i<q;i++)
  144.   for(j=0;j<120;j++);
  145. }

  146. /***********************延时函数************************/
  147. void delay_uint(uint q)
  148. {
  149. while(q--);
  150. }

  151. /***********************lcd1602写命令函数************************/
  152. void write_com(uchar com)
  153. {
  154. e=0;
  155. rs=0;
  156. rw=0;
  157. P0=com;
  158. delay_uint(3);
  159. e=1;
  160. delay_uint(25);
  161. e=0;
  162. }
  163. /***********************lcd1602写数据函数************************/
  164. void write_data(uchar dat)
  165. {
  166. e=0;
  167. rs=1;
  168. rw=0;
  169. P0=dat;
  170. delay_uint(3);
  171. e=1;
  172. delay_uint(25);
  173. e=0;
  174. }
  175. /***********************lcd1602初始化设置************************/
  176. void init_1602()  //lcd1602初始化设置
  177. {
  178. write_com(0x38); //
  179. write_com(0x0c);
  180. write_com(0x06);
  181. }
  182. /***********************lcd1602上显示两位十进制数************************/
  183. void write_sfm1(uchar hang,uchar add,uchar date)
  184. {
  185. if(hang==1)   
  186.   write_com(0x80+add);
  187. else
  188.   write_com(0x80+0x40+add);
  189. write_data(table_num[date % 10]);
  190. }
  191. /***********************lcd1602上显示两位十进制数************************/
  192. void write_sfm2(uchar hang,uchar add,uchar date)
  193. {
  194. if(hang==1)   
  195.   write_com(0x80+add);
  196. else
  197.   write_com(0x80+0x40+add);
  198. write_data(table_num[date / 10 % 10]);
  199. write_data(table_num[date % 10]);
  200. }

  201. /***********************lcd1602上显示两位十进制数************************/
  202. void write_sfm2_18B20(uchar hang,uchar add,uint date)
  203. {
  204. if(hang==1)   
  205.   write_com(0x80+add);
  206. else
  207.   write_com(0x80+0x40+add);
  208. write_data(0x30+date/10%10);
  209. write_data(0x30+date%10);
  210. }

  211. /***********************lcd1602上显示两位十进制数************************/
  212. void write_sfm2_ds1302(uchar hang,uchar add,uchar date)
  213. {
  214. if(hang==1)   
  215.   write_com(0x80+add);
  216. else
  217.   write_com(0x80+0x40+add);   
  218. write_data(table_num[date/16]);
  219. write_data(table_num[date%16]);
  220. }
  221. /***********************lcd1602上显示这字符函数************************/
  222. void write_string(uchar hang,uchar add,uchar *p)
  223. {
  224. if(hang==1)   
  225.   write_com(0x80+add);
  226. else
  227.   write_com(0x80+0x40+add);
  228.   while(1)               
  229.   {
  230.    if(*p == '\0')  break;
  231.    write_data(*p);
  232.    p++;
  233.   }
  234. }
  235. /*****************控制光标函数********************/
  236. void write_guanbiao(uchar hang,uchar add,uchar date)
  237. {  
  238. if(hang==1)   
  239.   write_com(0x80+add);
  240. else
  241.   write_com(0x80+0x40+add);
  242. if(date == 1)
  243.   write_com(0x0f);     //显示光标并且闪烁
  244. else
  245.   write_com(0x0c);   //关闭光标
  246. }
  247. /***********************lcd1602上显示特定的字符************************/
  248. void write_zifu(uchar hang,uchar add,uchar date)
  249. {
  250. if(hang==1)   
  251.   write_com(0x80+add);
  252. else
  253.   write_com(0x80+0x40+add);
  254. write_data(date);
  255. }


  256. /****************开机液晶显示函数 初始化液晶的内容********************************/
  257. void init_1602_dis_csf()  //初始化液晶
  258. {
  259. write_string(1,0," zd 00:00:00 00%");  
  260. write_string(2,0,"1 2000-00-00 00 ");
  261. write_zifu(2,15,0xdf);  //显示度
  262. if(flag_zd_sd == 0)     //手动
  263.   write_string(1,0," sd");  
  264. if(flag_zd_sd == 1)     //定时模式
  265.   write_string(1,0," ds");  
  266. if(flag_zd_sd == 2)     //光线控制
  267.   write_string(1,0," gx");   
  268. }

  269. void bujindj()  //步进电机函数
  270. {
  271. static uchar i;
  272. if(flag_z_f != 0)
  273. {
  274.   if(flag_z_f == 1)    //开
  275.   {
  276.    if(bjdj_value >= 254)
  277.    {
  278.     flag_z_f = 0;
  279.     bjdj_value = 254;
  280.    }else
  281.     bjdj_value ++;
  282.   }
  283.   if(flag_z_f == 2)    //关
  284.   {   
  285.    if(bjdj_value <= 1)
  286.    {
  287.     flag_z_f = 0;
  288.     bjdj_value = 1;
  289.    }else  
  290.     bjdj_value --;
  291.   }
  292.   for(i=0;i<4;i++)          //4相
  293.   {
  294.    if(flag_z_f == 1)   //开
  295.     P2=zheng[i];// & (P2 | 0xf0);        //
  296.    else if(flag_z_f == 2)//关
  297.     P2=fan[i];// & (P2 | 0xf0);         //
  298.    delay_uint(500);        //改变这个参数可以调整电机转速
  299.   }
  300. }
  301. }

  302. /***************读数模转换数据****************/
  303. //请先了解ADC0832模数转换的串行协议,再来读本函数,主要是对应时序图来理解,本函数是模拟0832的串行协议进行的
  304.       //  1  0  0 通道
  305.       //  1  1  1 通道
  306. unsigned char ad0832read(bit SGL,bit ODD)
  307. {
  308. unsigned char i=0,value=0,value1=0;  
  309.   SCL=0;
  310.   DO=1;
  311.   CS=0;  //开始
  312.   SCL=0;  //第一个上升沿
  313.   SCL=1;
  314.   DO=SGL;
  315.   SCL=0;   //第二个上升沿
  316.   SCL=1;
  317.   DO=ODD;
  318.   SCL=0;     //第三个上升沿
  319.   SCL=1;     //第三个下降沿
  320.   DO=1;
  321.   for(i=0;i<8;i++)
  322.   {
  323.    SCL=1;
  324.    SCL=0; //开始从第四个下降沿接收数据
  325.    value>>=1;
  326.    if(DO)
  327.     value++;      
  328.   }
  329.   for(i=0;i<8;i++)
  330.   {   //接收校验数据
  331.    value1>>=1;
  332.    if(DO)
  333.     value1+=0x80;
  334.    SCL=1;
  335.    SCL=0;
  336.   }
  337.   CS=1;
  338.   SCL=1;
  339.   if(value==value1)  //与校验数据比较,正确就返回数据,否则返回0
  340.    return value;
  341. return 0;
  342. }

  343. /***********************18b20初始化函数*****************************/
  344. void init_18b20()
  345. {
  346. bit q;
  347. dq = 1;    //把总线拿高
  348. delay_uint(1);     //15us
  349. dq = 0;    //给复位脉冲
  350. delay_uint(80);  //750us
  351. dq = 1;    //把总线拿高 等待
  352. delay_uint(10);  //110us
  353. q = dq;    //读取18b20初始化信号
  354. delay_uint(20);  //200us
  355. dq = 1;    //把总线拿高 释放总线
  356. }
  357. /*************写18b20内的数据***************/
  358. void write_18b20(uchar dat)
  359. {
  360. uchar i;
  361. for(i=0;i<8;i++)
  362. {      //写数据是低位开始
  363.   dq = 0;    //把总线拿低写时间隙开始
  364.   dq = dat & 0x01; //向18b20总线写数据了
  365.   delay_uint(5);  // 60us
  366.   dq = 1;    //释放总线
  367.   dat >>= 1;
  368. }
  369. }
  370. /*************读取18b20内的数据***************/
  371. uchar read_18b20()
  372. {
  373. uchar i,value;
  374. for(i=0;i<8;i++)
  375. {
  376.   dq = 0;    //把总线拿低读时间隙开始
  377.   value >>= 1;  //读数据是低位开始
  378.   dq = 1;    //释放总线
  379.   if(dq == 1)   //开始读写数据
  380.    value |= 0x80;
  381.   delay_uint(5);  //60us 读一个时间隙最少要保持60us的时间
  382. }
  383. return value;   //返回数据
  384. }
  385. /*************读取温度的值 读出来的是***************/
  386. uint read_temp()
  387. {
  388. uint value;
  389. uchar low;      //在读取温度的时候如果中断的太频繁了,就应该把中断给关了,否则会影响到18b20的时序
  390. init_18b20();     //初始化18b20
  391. write_18b20(0xcc);    //跳过64位ROM
  392. write_18b20(0x44);    //启动一次温度转换命令
  393. init_18b20();     //初始化18b20

  394. write_18b20(0xcc);    //跳过64位ROM
  395. write_18b20(0xbe);    //发出读取暂存器命令

  396. low = read_18b20();    //读温度低字节
  397. value = read_18b20();  //读温度高字节
  398. value <<= 8;     //把温度的高位左移8位
  399. value |= low;     //把读出的温度低位放到value的低八位中
  400. value *= 0.0625;        //转换到温度值 小数
  401. return value;     //返回读出的温度 带小数
  402. }

  403. /*************时钟显示***************/
  404. void init_1602_ds1302()
  405. {
  406. write_sfm2_ds1302(1,4,shi);     //显示时
  407. write_sfm2_ds1302(1,7,fen);     //显示分
  408. write_sfm2_ds1302(1,10,miao);    //显示秒
  409. write_sfm1(2,0,week) ;
  410. write_sfm2_ds1302(2,4,nian);   //显示年
  411. write_sfm2_ds1302(2,7,yue);    //显示月
  412. write_sfm2_ds1302(2,10,ri);    //显示日   
  413. }            
  414. /*************定时器0初始化程序***************/
  415. void init_time0()   
  416. {
  417. EA   = 1;     //开总中断
  418. TMOD = 0X01;   //定时器0、工作方式1
  419. ET0  = 1;    //开定时器0中断
  420. TR0  = 1;    //允许定时器0定时
  421. }
  422. /********************独立按键程序*****************/
  423. void key()  //独立按键程序
  424. {
  425. static uchar key_new;
  426. key_can = 20;                   //按键值还原
  427. P3 |= 0xf0;                     //对应的按键IO口输出为1
  428. if((P3 & 0xf0) != 0xf0)  //按键按下
  429. {
  430.   delay_1ms(1);       //按键消抖动
  431.   if(((P3 & 0xf0) != 0xf0) && (key_new == 1))
  432.   {      //确认是按键按下
  433.    key_new = 0;
  434.    switch(P3 & 0xf0)
  435.    {
  436.     case 0x80: key_can = 1; break;   //得到按键值
  437.     case 0x40: key_can = 2; break;   //得到按键值
  438.     case 0xb0: key_can = 3; break;   //得到按键值
  439.     case 0x70: key_can = 4; break;   //得到按键值
  440.    }
  441.    flag_lj_en = 1;
  442.    beep = 0;
  443.    delay_1ms(80);
  444.    beep = 1;
  445.   }   
  446. }
  447. else
  448. {
  449.   key_new = 1;
  450.   flag_lj_en = 0;
  451. }
  452. }

  453. /**********************设置函数************************/
  454. void key_with()
  455. {
  456. if(menu_1 == 0)
  457.   if(key_can == 2) //设置手动还是自动模式
  458.   {
  459.    flag_zd_sd ++;
  460.    if(flag_zd_sd >= 3)
  461.     flag_zd_sd = 0;
  462.    if(flag_zd_sd == 0)     //手动
  463.     write_string(1,0," sd");  
  464.    if(flag_zd_sd == 1)     //定时模式
  465.     write_string(1,0," ds");  
  466.    if(flag_zd_sd == 2)     //光线控制
  467.     write_string(1,0," gx");  
  468.    flag_kaig_moshi = 0;
  469.   }      
  470. if(key_can == 1) //设置键
  471. {
  472.   menu_1++;
  473.   if(menu_1 == 1)   //设置时间
  474.   {
  475.    menu_2 = 1;
  476.    write_string(1,0,"  :  :    W:  ");   
  477.    write_string(2,0," 20  -  -       ");
  478.   }
  479.   if(menu_1 == 2)   //设置开关窗帘时间
  480.   {
  481.    menu_2 = 1;
  482.    write_string(1,0," kai 00:00      ");
  483.       write_string(2,0,"guan 00:00      ");
  484.   }
  485.   if(menu_1 == 3)   //设置报警光线报警
  486.   {
  487.    menu_2 = 1;
  488.    write_string(1,0,"  Set Guanxian  ");
  489.    write_string(2,0,"     00%       ");
  490.   }
  491.   if(menu_1 == 4)   //设置报警温度
  492.   {
  493.    menu_2 = 1;
  494.    write_string(1,0,"   Set Wendu   ");
  495.       write_string(2,0,"     00       ");
  496.    write_zifu(2,9,0xdf);  //显示度
  497.   }
  498.   if(menu_1 == 5)   //手动把窗帘归0
  499.   {
  500.    menu_2 = 1;
  501.    write_string(1,0," tiaoshi dianji ");
  502.       write_string(2,0,"       0         ");
  503.    write_guanbiao(2,6,0);
  504.   }
  505.   if(menu_1 > 2)    //回到正常显示
  506.   {
  507.    menu_1 = 0;
  508.    write_guanbiao(1,2,0);  //关闭光标
  509.    init_1602_dis_csf();      //初始化液晶显示  
  510.   }
  511. }
  512. if(key_can == 2) //选择键
  513. {
  514.   flag_200ms = 1;
  515.   if(menu_1 == 1)    //设置时间
  516.   {
  517.    menu_2 ++;
  518.    if(menu_2 > 5)
  519.     menu_2 = 1;
  520.   }
  521.   if(menu_1 == 2)   //设置开关的时间
  522.   {
  523.    menu_2 ++;
  524.    if(menu_2 > 4)
  525.     menu_2 = 1;   
  526.   }
  527. }
  528. if(menu_1 == 1)
  529. {
  530.   if(menu_2 == 1)    //设置时
  531.   {
  532.    if(key_can == 3) //加
  533.    {
  534.     shi+=0x01;
  535.     if((shi & 0x0f) >= 0x0a)
  536.      shi = (shi & 0xf0) + 0x10;
  537.     if(shi >= 0x24)
  538.      shi = 0;
  539.    }  
  540.    if(key_can == 4) //减
  541.    {
  542.     if(shi == 0x00)
  543.      shi = 0x24;
  544.     if((shi & 0x0f) == 0x00)
  545.      shi = (shi | 0x0a) - 0x10;
  546.     shi -- ;
  547.    }      
  548.   }
  549.   if(menu_2 == 2)    //设置分
  550.   {
  551.    if(key_can == 3) //加
  552.    {
  553.     fen+=0x01;
  554.     if((fen & 0x0f) >= 0x0a)
  555.      fen = (fen & 0xf0) + 0x10;
  556.     if(fen >= 0x60)
  557.      fen = 0;
  558.    }  
  559.    if(key_can == 4) //减   
  560.    {
  561.     if(fen == 0x00)
  562.      fen = 0x5a;
  563.     if((fen & 0x0f) == 0x00)
  564.      fen = (fen | 0x0a) - 0x10;
  565.     fen -- ;
  566.    }
  567.   }
  568.   if(menu_2 == 3)    //设置秒
  569.   {
  570.    if(key_can == 3) //加
  571.    {
  572.     miao+=0x01;
  573.     if((miao & 0x0f) >= 0x0a)
  574.      miao = (miao & 0xf0) + 0x10;
  575.     if(miao >= 0x60)
  576.      miao = 0;
  577.    }
  578.    if(key_can == 4) //减   
  579.    {
  580.     if(miao == 0x00)
  581.      miao = 0x5a;
  582.     if((miao & 0x0f) == 0x00)
  583.      miao = (miao | 0x0a) - 0x10;
  584.     miao -- ;   
  585.    }
  586.   }
  587.   if(menu_2 == 4)    //设置星期
  588.   {
  589.    if(key_can == 3) //加
  590.    {
  591.        week+=0x01;
  592.     if((week & 0x0f) >= 0x0a)
  593.      week = (week & 0xf0) + 0x10;
  594.     if(week >= 0x08)
  595.      week = 1;
  596.    }  
  597.    if(key_can == 4) //减   
  598.    {
  599.     if(week == 0x01)
  600.      week = 0x08;
  601.     if((week & 0x0f) == 0x00)
  602.      week = (week | 0x0a) - 0x10;
  603.     week -- ;
  604.    }
  605.   }
  606.   if(menu_2 == 5)    //设置年
  607.   {
  608.    if(key_can == 3) //加
  609.    {
  610.        nian+=0x01;
  611.     if((nian & 0x0f) >= 0x0a)
  612.      nian = (nian & 0xf0) + 0x10;
  613.     if(nian >= 0x9a)
  614.      nian = 1;
  615.    }  
  616.    if(key_can == 4) //减   
  617.    {
  618.     if(nian == 0x01)
  619.      nian = 0x9a;
  620.     if((nian & 0x0f) == 0x00)
  621.      nian = (nian | 0x0a) - 0x10;
  622.     nian -- ;  
  623.    }
  624.   }
  625.   if(menu_2 == 6)    //设置月
  626.   {
  627.    if(key_can == 3) //加
  628.    {
  629.        yue+=0x01;
  630.     if((yue & 0x0f) >= 0x0a)
  631.      yue = (yue & 0xf0) + 0x10;
  632.     if(yue >= 0x13)
  633.      yue = 1;
  634.    }  
  635.    if(key_can == 4) //减   
  636.    {
  637.     if(yue == 0x01)
  638.      yue = 0x13;
  639.     if((yue & 0x0f) == 0x00)
  640.      yue = (yue | 0x0a) - 0x10;
  641.     yue -- ;     
  642.    }
  643.   }
  644.   if(menu_2 == 7)    //设置日
  645.   {
  646.    if(key_can == 3) //加
  647.    {
  648.       ri+=0x01;
  649.    if((ri & 0x0f) >= 0x0a)
  650.     ri = (ri & 0xf0) + 0x10;
  651.    if(ri >= 0x32)
  652.     ri = 0;   
  653.    }  
  654.    if(key_can == 4) //减   
  655.    {
  656.     if(ri == 0x01)
  657.      ri = 0x32;
  658.     if((ri & 0x0f) == 0x00)
  659.      ri = (ri | 0x0a) - 0x10;
  660.     ri -- ;   
  661.    }
  662.   }
  663.   write_sfm2_ds1302(1,2,shi);    //显示时
  664.   write_sfm2_ds1302(1,5,fen);    //显示分
  665.   write_sfm2_ds1302(1,8,miao);    //显示秒
  666.   write_sfm1(1,14,week);    //显示星期     
  667.   write_sfm2_ds1302(2,3,nian);    //显示年
  668.   write_sfm2_ds1302(2,6,yue);    //显示月
  669.   write_sfm2_ds1302(2,9,ri);    //显示日
  670.   switch(menu_2)    // 光标显示
  671.   {
  672.    case 1:  write_guanbiao(1,2,1);  break;
  673.    case 2:  write_guanbiao(1,5,1);  break;
  674.    case 3:  write_guanbiao(1,8,1);  break;
  675.    case 4:  write_guanbiao(1,14,1);  break;
  676.    case 5:  write_guanbiao(2,3,1);  break;
  677.    case 6:  write_guanbiao(2,6,1);  break;
  678.    case 7:  write_guanbiao(2,9,1);  break;
  679.   }
  680.   write_time();    //把时间写进去
  681. }
  682. /***************设置开关窗帘时间*********************/
  683. if(menu_1 == 2)
  684. {
  685.   if(menu_2 == 1)    //设置开窗帘时间时
  686.   {
  687.    if(key_can == 3) //加
  688.     set_ds1302time(1,&k_shi,0x24);  
  689.    if(key_can == 4) //减  
  690.     set_ds1302time(0,&k_shi,0x24);
  691.   }
  692.   if(menu_2 == 2)    //设置开窗帘时间分
  693.   {
  694.    if(key_can == 3) //加
  695.     set_ds1302time(1,&k_fen,0x60);  
  696.    if(key_can == 4) //减  
  697.     set_ds1302time(0,&k_fen,0x60);
  698.   }
  699.   if(menu_2 == 3)    //设置关窗帘时间时
  700.   {
  701.    if(key_can == 3) //加
  702.     set_ds1302time(1,&g_shi,0x24);  
  703.    if(key_can == 4) //减  
  704.     set_ds1302time(0,&g_shi,0x24);
  705.   }
  706.   if(menu_2 == 4)    //设置关窗帘时间分
  707.   {
  708.    if(key_can == 3) //加
  709.     set_ds1302time(1,&g_fen,0x60);  
  710.    if(key_can == 4) //减  
  711.     set_ds1302time(0,&g_fen,0x60);
  712.   }
  713.   write_sfm2_ds1302(1,5,k_shi);   //显示开时
  714.   write_sfm2_ds1302(1,8,k_fen);   //显示开分
  715.   write_sfm2_ds1302(2,5,g_shi);   //显示关时
  716.   write_sfm2_ds1302(2,8,g_fen);   //显示关分
  717.   switch(menu_2)    // 光标显示
  718.   {
  719.    case 1:  write_guanbiao(1,5,1);  break;
  720.    case 2:  write_guanbiao(1,8,1);  break;
  721.    case 3:  write_guanbiao(2,5,1);  break;
  722.    case 4:  write_guanbiao(2,8,1);  break;
  723.   }
  724. }
  725. if(menu_1 == 3)   //设置光线等级
  726. {
  727.   if(key_can == 3) //加
  728.   {
  729.    guanxian_set ++;
  730.    if(guanxian_set >= 99)
  731.     guanxian_set = 99;   
  732.   }
  733.   if(key_can == 4) //减  
  734.   {
  735.    if(guanxian_set != 0)
  736.     guanxian_set --;
  737.   }
  738.   write_sfm2(2,7,guanxian_set);
  739.   write_guanbiao(2,6,1);
  740. }
  741. if(menu_1 == 4)   //设置温度等级
  742. {
  743.   if(key_can == 3) //加
  744.   {
  745.    t_high ++;
  746.    if(t_high >= 99)
  747.     t_high = 99;   
  748.   }
  749.   if(key_can == 4) //减  
  750.   {
  751.    if(t_high != 0)
  752.     t_high --;
  753.   }
  754.   write_sfm2(2,7,t_high);
  755.   write_guanbiao(2,6,1);
  756. }
  757. }
  758. /*************手动开关窗帘***************/
  759. void shoudong_kaiguan()   //手动开关窗帘
  760. {
  761. static uchar h_value,l_value;
  762. if(flag_zd_sd == 0)   //手动模式
  763. {
  764.   if(menu_1 == 0)
  765.   {
  766.    if(key_can == 3)
  767.    {
  768.     h_value ++;
  769.     flag_z_f = 1;     //手动开窗
  770.     l_value = 0;
  771.     if(h_value >= 2)
  772.     {
  773.      h_value = 0;
  774.      flag_z_f = 0;     //停止开窗
  775.     }
  776.    }
  777.    if(key_can == 4)
  778.    {
  779.     flag_z_f = 2;     //手动关窗
  780.     l_value ++;
  781.     h_value = 0;
  782.     if(l_value >= 2)
  783.     {
  784.      l_value = 0;
  785.      flag_z_f = 0;     //停止关窗
  786.     }
  787.    }
  788.   }
  789. }
  790. if(flag_zd_sd == 2)   //光线控制模式
  791. {
  792.   if(guanxian <= guanxian_set)
  793.    flag_z_f = 1;     //手动开窗
  794.   else
  795.    flag_z_f = 2;     //手动关窗
  796. }
  797. }

  798.                
  799. /*********************智能窗帘处理函数***********************/
  800. void zinengchuanglian_dis()   //智能窗帘处理函数
  801. {

  802. if(flag_zd_sd == 1)   //定时模式
  803. {
  804.   if((miao == 0) && (fen == k_fen) && (shi == k_shi))   //定时开窗
  805.   {
  806.    flag_z_f = 1;     //开窗
  807.   }
  808.   if((miao == 0) && (fen == g_fen) && (shi == g_shi))   //定时关窗
  809.   {
  810.    flag_z_f = 2;    //关窗
  811.   }
  812. }
  813. }

  814. /*****************调试窗帘电机*******************/
  815. void tiaoshi_dianji() //调试窗帘电机
  816. {
  817. static uchar value;
  818. if(menu_1 == 5)     //把窗帘归零
  819. {
  820.   if(key_can == 3)
  821.   {
  822.    flag_z_f = 1;     //手动开窗
  823.    value = 1;
  824.   }
  825.   if(key_can == 4)
  826.   {
  827.    flag_z_f = 2;     //手动关窗
  828.    value = 1;
  829.   }
  830.   if(flag_lj_en == 0)
  831.   {
  832.    if(value == 1)
  833.    {
  834.     value = 0;
  835.     flag_z_f = 0;
  836.        bjdj_value = 0;  
  837.    }
  838.   }
  839.   else
  840.   {
  841.    for(i=0;i<4;i++)          //4相
  842.    {
  843.     if(flag_z_f == 1)   //开
  844.      P2=zheng[i];
  845.     else if(flag_z_f == 2)//关
  846.      P2=fan[i];
  847.     delay_uint(500);        //改变这个参数可以调整电机转速
  848.    }
  849.   }
  850. }      
  851. }

  852. /***********外部中断0初始化程序****************/
  853. void init_int0()   //外部中断0初始化程序
  854. {
  855. EX0=1;     //允许外部中断0中断
  856. EA=1;      //开总中断
  857. IT0 = 1;     //外部中断0负跳变中断
  858. }
  859. /***********红外遥控程序**************/
  860. void hongwai_dis()
  861. {
  862. if(flag_jiema_en == 1)
  863. {
  864.   flag_jiema_en = 0;
  865.   beep = 0;        //蜂鸣器叫一声
  866.   delay_1ms(50);
  867.   beep = 1;
  868.   switch(hw_table[2])
  869.   {
  870.    case 0x07: key_can = 4; break;   //得到按键值
  871.    case 0x15: key_can = 3; break;   //得到按键值
  872.    case 0x44: key_can = 2; break;   //得到按键值
  873.    case 0x40: key_can = 1; break;   //得到按键值
  874.   }
  875.   if(hw_table[2] == 0x45)  //退出键
  876.   {
  877.    menu_1 = 0;
  878.    write_guanbiao(1,2,0);  //关闭光标
  879.    init_1602_dis_csf();      //初始化液晶显示  
  880.   }
  881.   hw_table[2] = 0;    //把数据清零
  882. }
  883. }

  884. /*****************主函数********************/
  885. void main()
  886. {
  887. init_time0();   //初始化定时器
  888. init_1602();   //lcd1602初始化
  889. init_1602_dis_csf(); //lcd1602初始化显示
  890. init_int0();   //外部中断0初始化程序
  891. while(1)
  892. {
  893.   key();    //按键程序
  894.   hongwai_dis();   //红外遥控程序
  895.   if(key_can < 10)
  896.   {
  897.    key_with();
  898.   }
  899.   if(flag_200ms == 1)
  900.   {
  901.    flag_200ms = 0;
  902.    temperature = read_temp();  //读温度 环境温度
  903.    if(temperature >= 99)
  904.     temperature = 99;
  905.    guanxian = ad0832read(1,0) * 99.0 / 255;
  906.    if(menu_1 == 0)
  907.    {
  908.     read_time();    //读时间
  909.     init_1602_ds1302();   //显示时钟
  910.     write_sfm2(1,13,guanxian); //显示温度
  911.     write_sfm2_18B20(2,13,temperature); //显示温度
  912.    }
  913.    if(temperature >= t_high)
  914.     beep = ~beep;   //蜂鸣器温度报警
  915.    else
  916.     beep = 1;     
  917.   }
  918.   if(menu_1 == 0)
  919.   {
  920.    shoudong_kaiguan();   //手动开关窗帘
  921.    zinengchuanglian_dis();   //智能窗帘定时处理函数
  922.   }
  923.   tiaoshi_dianji(); //调试窗帘电机
  924.    bujindj();  //步进电机函数
  925.   delay_1ms(1);
  926. }
  927. }
  928. /*****************红外解码程序********************/
  929. void int0() interrupt 0
  930. {
  931. unsigned char i,j;
  932. delay_100us(40);     //防止干扰
  933. if(hw_P32 == 0)
  934. {         //引导码9+4.5=13.5ms
  935.   while(hw_P32 == 0); //等待9ms的低电平过完
  936.   delay_100us(27);  //2.7ms
  937.   if(hw_P32 == 1)   //引码结束
  938.   {  
  939.    delay_100us(20);  //  说明4.5ms的高电平已经过完 引导码已经结束
  940.    for(i=0;i<4;i++)
  941.     for(j=0;j<8;j++)
  942.     {
  943.      while(hw_P32 == 0);   //等待过完0.56ms
  944.      delay_100us(9);
  945.      if(hw_P32 == 0)  //数据0的时间
  946.      {     //数据1的时间
  947.       hw_table[i] >>= 1;    //低位在前
  948.      }
  949.      else
  950.      {
  951.       delay_100us(10);   //0.9+1.0=1.9ms 延时让1.685高电平的时间过完
  952.       hw_table[i] >>= 1;    //低位在前
  953.       hw_table[i] |= 0x80;  //1.9ms过完后 数据线已经是低电平了
  954.      }
  955.     }
  956.    flag_jiema_en = 1;   //红外解码成功  
  957.   }
  958. }
  959. }
  960. /**************定时器0中断程序*****************/
  961. void time0() interrupt 1
  962. {   
  963. static uchar value;
  964. TH0 = 0X3C;
  965. TL0 = 0XB0;    //50ms
  966. value ++;   
  967. if(value >= 6)    //200ms
  968. {
  969.   value = 0;
  970.   flag_200ms = 1;
  971. }
  972. }
复制代码
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏8 分享淘帖 顶1 踩
回复

使用道具 举报

沙发
ID:987484 发表于 2022-3-16 21:29 | 只看该作者
你好 请问这个有蓝牙功能吗
回复

使用道具 举报

板凳
ID:1009501 发表于 2022-3-17 08:57 | 只看该作者
感谢分享,楼主辛苦
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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