找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 8984|回复: 1
收起左侧

单片机检测环境温度,可通过按键设置温度,当环境温度高于上下限时,蜂鸣器报警,L...

[复制链接]
ID:595055 发表于 2019-8-15 21:38 | 显示全部楼层 |阅读模式
检测环境温度,可通过按键设置上下限温度,当环境温度高于上下限温度时,蜂鸣器和LED报警,同时LED显示当前温度值和设定温度值

单片机源程序如下:
  1. #include<reg52.h>
  2. #include "intrins.h"
  3. typedef unsigned char uint8;
  4. typedef unsigned int uint16;
  5. sbit rs=P2^6;         // 数据命令选择
  6. sbit rw=P2^5;         //读写选择
  7. sbit e=P2^7;          //使能

  8. sbit k1=P3^1; //模式
  9. sbit k2=P3^0; //加
  10. sbit k3=P3^2; //减

  11. //sbit DHT11_DQ_OUT=P3^2;
  12. sbit led1=P2^0;
  13. sbit led2=P2^1;
  14. sbit bz=P1^5;

  15. sbit dq=P3^7;

  16. uint8 mode=0,xian;
  17. char temph=35,templ=20;
  18. //char humih=80,humil=20;
  19. uint8 temp,humi;
  20. uint8 flag;          //设定报警标志
  21. uint8 a,c,tempvalue;
  22. uint8 code num[10]="0123456789";

  23. uint8 code str1[]="Temp:";  //温度
  24. uint8 code str2[]="Humi:";  //湿度
  25. uint8 code str3[]="Error";  
  26. uint8 code str4[]="Success    ";
  27. uint8 code str5[]="%RH";
  28. uint8 code str6[]="TempH:";          //设定温度上限显示
  29. uint8 code str7[]="TempL:";          //设定温度下限显示
  30. uint8 code str8[]="HumiH:";           //设定湿度上限显示
  31. uint8 code str9[]="HumiL:";           //设定湿度下限显示


  32. void delay(uint16 i)
  33. {
  34.         while(i--);
  35. }

  36. void delay_ms(uint16 i)
  37. {
  38.         while(i--);
  39.         delay(90);
  40. }

  41. void sound()
  42. {
  43.         int n=100;
  44.         while(n--)
  45.         {
  46.                 bz=~bz;
  47.                 delay(100);       
  48.         }
  49. }
  50. void wrc(uint8 c)         //写命令
  51. {
  52.         delay(1000);
  53.         rs=0;
  54.         rw=0;
  55.         e=0;
  56.         P0=c;
  57.         e=1;
  58.         delay(10);
  59.         e=0;
  60. }
  61. void wrd(uint8 dat)          //写数据
  62. {
  63.         delay(1000);
  64.         rs=1;
  65.         rw=0;
  66.         e=0;
  67.         P0=dat;
  68.         e=1;
  69.         delay(10);
  70.         e=0;
  71.         rs=0;
  72. }
  73. void lcd_init()           // LCD1602初始化
  74. {
  75.         delay(1000);
  76.         wrc(0x38);
  77.         wrc(0x38);         //功能设置命令,选择8位总线,双行显示  5*7点阵字符
  78.         wrc(0x38);
  79.         wrc(0x06);        //光标和显示模式设置  光标右移  整屏不移动
  80.         wrc(0x0c);        //显示开关控制  开显示  无光标 光标不闪烁
  81.         wrc(0x01);        //清零指令  固定的
  82. }
  83. //复位DHT11
  84. //void DHT11_Rst()          
  85. //{                 
  86. //    DHT11_DQ_OUT=0;         //拉低DQ
  87. //    delay_ms(20);            //拉低至少18ms
  88. //    DHT11_DQ_OUT=1;         //DQ=1
  89. //        delay(3);             //主机拉高20~40us
  90. //}

  91. //等待DHT11的回应
  92. //返回1:未检测到DHT11的存在
  93. //返回0:存在
  94. //uint8 DHT11_Check()           
  95. //{   
  96. //        uint8 retry=0;         
  97. //    while (DHT11_DQ_OUT&&retry<100)//DHT11会拉低40~50us
  98. //        {
  99. //                retry++;
  100. //                _nop_();
  101. //        };         
  102. //        if(retry>=100)return 1;
  103. //        else retry=0;
  104. //    while (!DHT11_DQ_OUT&&retry<100)//DHT11拉低后会再次拉高40~50us
  105. //        {
  106. //                retry++;
  107. //                _nop_();
  108. //        };
  109. //        if(retry>=100)return 1;            
  110. //        return 0;
  111. //}


  112. //DHT11初始化
  113. //返回0:初始化成功,1:失败
  114. //uint8 DHT11_Init()
  115. //{
  116. //        DHT11_Rst();          
  117. //        return DHT11_Check();       
  118. //}


  119. //从DHT11读取一个位
  120. //返回值:1/0
  121. //uint8 DHT11_Read_Bit(void)                          
  122. //{
  123. //         uint8 retry=0;
  124. //        while(DHT11_DQ_OUT&&retry<100)//等待变为低电平 12-14us 开始
  125. //        {
  126. //                retry++;
  127. //                _nop_();
  128. //        }
  129. //        retry=0;
  130. //        while((!DHT11_DQ_OUT)&&retry<100)//等待变高电平         26-28us表示0,116-118us表示1
  131. //        {
  132. //                retry++;
  133. //                _nop_();
  134. //        }
  135. //        delay(1);//等待40us
  136. //        if(DHT11_DQ_OUT)return 1;
  137. //        else return 0;                  
  138. //}

  139. //从DHT11读取一个字节
  140. //返回值:读到的数据
  141. //uint8 DHT11_Read_Byte(void)   
  142. //{        
  143. //    uint8 i,dat=0;
  144. //        for (i=0;i<8;i++)
  145. //        {
  146. //                   dat<<=1;
  147. //            dat|=DHT11_Read_Bit();
  148. //    }                                                    
  149. //    return dat;
  150. //}

  151. //从DHT11读取一次数据
  152. //temp:温度值(范围:0~50°)
  153. //humi:湿度值(范围:20%~90%)
  154. //返回值:0,正常;1,读取失败
  155. //uint8 DHT11_Read_Data(uint8 *temp,uint8 *humi)   
  156. //{        
  157. //         uint8 buf[5];
  158. //        uint8 i;
  159. //        DHT11_Rst();
  160. //        if(DHT11_Check()==0)
  161. //        {
  162. //                for(i=0;i<5;i++)//读取40位数据
  163. //                {
  164. //                        buf[i]=DHT11_Read_Byte();
  165. //                }
  166. //                if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])
  167. //                {
  168. //                        *humi=buf[0];
  169. //                        *temp=buf[2];
  170. //                }
  171. //               
  172. //        }else return 1;
  173. //        return 0;            
  174. //}




  175. void ds18b20init()                //18b20的初始化
  176. {
  177.         dq=1;
  178.         delay(1);
  179.         dq=0;
  180.         delay(80);
  181.         dq=1;
  182.         delay(5);
  183.         dq=0;
  184.         delay(20);
  185.         dq=1;
  186.         delay(35);
  187. }
  188. void ds18b20wr(uint8 dat)          //18b20写数据
  189. {
  190.         uint8 i;
  191.         for(i=0;i<8;i++)
  192.         {
  193.                 dq=0;
  194.                 dq=dat&0x01;
  195.                 dat>>=1;
  196.                 delay(8);//在时序上只有这一块对时序要求最准确,他的时间必须大于15us
  197.                 dq=1;
  198.                 delay(1);
  199.         }       
  200. }
  201. uint8 ds18b20rd()                  //18b20读数据
  202. {
  203.         uint8 value,i;
  204.         for(i=0;i<8;i++)       
  205.         {
  206.                 dq=0;
  207.                 value>>=1;
  208.                 dq=1;
  209.                 if(dq==1)value|=0x80;
  210.                 delay(8);//在这一块也对时间要求特别准确,整段程序必须大于60us               
  211.         }
  212.         return value;
  213. }
  214. uint8 readtemp()                          //读取温度内需要复位的
  215. {
  216.         uint8 b;
  217.         ds18b20init();                //初始化
  218.         ds18b20wr(0xcc);   //发送忽略ROM指令
  219.         ds18b20wr(0x44);   //发送温度转换指令
  220.         delay(100);
  221.         ds18b20init();           //初始化
  222.         ds18b20wr(0xcc);   //发送忽略ROM指令
  223.         ds18b20wr(0xbe);   //发读暂存器指令
  224.         a=ds18b20rd();         //温度的低八位
  225.         b=ds18b20rd();         //温度的高八位
  226.         b<<=4;                         //ssss s***;s为标志位s=0表示温度值为正数,s=1温度值为负数
  227.         c=b&0x80;                //温度正负标志位确认
  228.         b+=(a&0xf0)>>4;
  229.         a=a&0x0f;          //温度的小数部分
  230.         return b;
  231. }


  232. void key_pros()  //按键处理函数
  233. {
  234.         if(k1==0)
  235.         {
  236.                 delay(1000);
  237.                 if(k1==0)
  238.                 {
  239.                         mode++;
  240.                         if(mode==3)mode=0;
  241.                         wrc(0x01);
  242.                 }
  243.                 while(!k1);
  244.         }
  245.         if(mode==1)                  //对温度上限设定
  246.         {
  247.                 if(k2==0)                  //加
  248.                 {
  249.                         delay(1000);
  250.                         if(k2==0)
  251.                         {
  252.                                 temph++;
  253.                                 if(temph>=80)temph=80;
  254.                         }
  255.                         while(!k2);
  256.                 }
  257.                 if(k3==0)           //减
  258.                 {
  259.                         delay(1000);
  260.                         if(k3==0)
  261.                         {
  262.                                 temph--;
  263.                                 if(temph<=0)temph=0;
  264.                         }
  265.                         while(!k3);
  266.                 }
  267.         }
  268.         if(mode==2)                  //对温度下限设定
  269.         {
  270.                 if(k2==0)                  //加
  271.                 {
  272.                         delay(1000);
  273.                         if(k2==0)
  274.                         {
  275.                                 templ++;
  276.                                 if(templ>=80)templ=80;
  277.                         }
  278.                         while(!k2);
  279.                 }
  280.                 if(k3==0)           //减
  281.                 {
  282.                         delay(1000);
  283.                         if(k3==0)
  284.                         {
  285.                                 templ--;
  286.                                 if(templ<=0)templ=0;
  287.                         }
  288.                         while(!k3);
  289.                 }
  290.         }
  291. //        if(mode==3)                  //对湿度上限设定
  292. //        {
  293. //                if(k2==0)                  //加
  294. //                {
  295. //                        delay(1000);
  296. //                        if(k2==0)
  297. //                        {
  298. //                                humih++;
  299. //                                if(humih>=80)humih=80;
  300. //                        }
  301. //                        while(!k2);
  302. //                }
  303. //                if(k3==0)           //减
  304. //                {
  305. //                        delay(1000);
  306. //                        if(k3==0)
  307. //                        {
  308. //                                humih--;
  309. //                                if(humih<=0)humih=0;
  310. //                        }
  311. //                        while(!k3);
  312. //                }
  313. //        }
  314. //        if(mode==4)                  //对湿度下限设定
  315. //        {
  316. //                if(k2==0)                  //加
  317. //                {
  318. //                        delay(1000);
  319. //                        if(k2==0)
  320. //                        {
  321. //                                humil++;
  322. //                                if(humil>=80)humil=80;
  323. //                        }
  324. //                        while(!k2);
  325. //                }
  326. //                if(k3==0)           //减
  327. //                {
  328. //                        delay(1000);
  329. //                        if(k3==0)
  330. //                        {
  331. //                                humil--;
  332. //                                if(humil<=0)humil=0;
  333. //                        }
  334. //                        while(!k3);
  335. //                }
  336. //        }
  337. }

  338. void lcd_init_display()           //LCD初始化显示
  339. {
  340.         uint8 i;
  341.         for(i=0;i<5;i++)
  342.         {
  343.                 wrc(0x80+i);
  344.                 wrd(str1[i]);       
  345.         }

  346. //        for(i=0;i<5;i++)
  347. //        {
  348. //                wrc(0xc0+i);
  349. //                wrd(str2[i]);       
  350. //        }
  351. }

  352. void data_pros()        //数据处理函数
  353. {
  354.         uint8 i;              
  355.         uint8 temp_buf[2],humi_buf[2];
  356.         uint8 temphbuf[2],templbuf[2],humihbuf[2],humilbuf[2];
  357.         float dio;
  358.         uint16 k;

  359.         tempvalue=readtemp();
  360. //        DHT11_Read_Data(&temp,&humi);
  361. //        temp_buf[0]=temp/10+0x30;       
  362. //        temp_buf[1]=temp%10+0x30;
  363. //
  364. //        humi_buf[0]=humi/10+0x30;       
  365. //        humi_buf[1]=humi%10+0x30;
  366.        
  367.         dio=a*0.0625;
  368.         k=dio*10000;//取小数点后两位有效数字

  369.         temphbuf[0]=temph/10+0x30;
  370.         temphbuf[1]=temph%10+0x30;
  371.         templbuf[0]=templ/10+0x30;
  372.         templbuf[1]=templ%10+0x30;

  373. //        humihbuf[0]=humih/10+0x30;
  374. //        humihbuf[1]=humih%10+0x30;
  375. //        humilbuf[0]=humil/10+0x30;
  376. //        humilbuf[1]=humil%10+0x30;

  377.         if(mode==0)
  378.         {
  379.                 lcd_init_display();
  380.                 wrc(0x85);
  381.                 wrd(num[tempvalue%100/10]);
  382.                 wrd(num[tempvalue%100%10]);
  383.                 wrd('.');
  384.                 wrd(num[k/1000]);
  385.                 wrd(0xdf);
  386.                 wrd('C');
  387.        
  388. //                for(i=0;i<2;i++)
  389. //                {
  390. //                        wrc(0Xc5+i);
  391. //                        wrd(humi_buf[i]);                  
  392. //                }       
  393. //                for(i=0;i<3;i++)
  394. //                {
  395. //                        wrc(0Xc7+i);
  396. //                        wrd(str5[i]);                  
  397. //                }       
  398.         }
  399.         if(mode==1)                          //温度上限显示
  400.         {
  401.                 wrc(0x80);
  402.                 for(i=0;i<6;i++)
  403.                 {
  404.                         wrd(str6[i]);                  
  405.                 }
  406.                 wrd(temphbuf[0]);
  407.                 wrd(temphbuf[1]);                       
  408.         }
  409.         if(mode==2)                          //温度下限显示
  410.         {
  411.                 wrc(0x80);
  412.                 for(i=0;i<6;i++)
  413.                 {
  414.                         wrd(str7[i]);                  
  415.                 }
  416.                 wrd(templbuf[0]);
  417.                 wrd(templbuf[1]);                       
  418.         }
  419. //        if(mode==3)                          //湿度上限显示
  420. //        {
  421. //                wrc(0x80);
  422. //                for(i=0;i<6;i++)
  423. //                {
  424. //                        wrd(str8[i]);                  
  425. //                }
  426. //                wrd(humihbuf[0]);
  427. //                wrd(humihbuf[1]);                       
  428. //        }
  429. //        if(mode==4)                          //湿度下限显示
  430. //        {
  431. //                wrc(0x80);
  432. //                for(i=0;i<6;i++)
  433. //                {
  434. //                        wrd(str9[i]);                  
  435. //                }
  436. //                wrd(humilbuf[0]);
  437. //                wrd(humilbuf[1]);                       
  438. //        }
  439. }

  440. void baojinpros()        //报警处理
  441. {
  442.         if(tempvalue>=temph)         //检测温度或者湿度高于设定上限值 降温湿
  443.         {
  444.                 led1=0;                //降温湿指示灯
  445.                 led2=1;
  446.                 sound();
  447.         }
  448.         if(tempvalue<=templ)        //检测温度或者湿度低于设定下限值  升温湿
  449.         {
  450.                 led1=1;
  451.                 led2=0;           //升高温湿指示灯
  452.                 sound();
  453.         }
  454.         if((tempvalue>templ&&tempvalue<temph))
  455.         {
  456.                 led1=1;
  457.                 led2=1;       
  458.         }
  459. }

  460. void main()
  461. {
  462.         uint8 i=0;
  463.         led1=0;
  464.         led2=0;
  465.         lcd_init();
  466. //        while(DHT11_Init())        //检测DHT11是否纯在
  467. //        {
  468. //                for(i=0;i<6;i++)
  469. //                {
  470. //                        wrc(0x80+i);
  471. //                        wrd(str4[i]);       
  472. //                }                       
  473. //        }
  474.         wrc(0x01);
  475.         lcd_init_display();           //LCD初始化显示
  476.         i=0;
  477.         while(1)
  478.         {       
  479.                 i++;
  480.                 key_pros();
  481.                 baojinpros();        //报警处理
  482.                 if(i==15)
  483.                 {
  484.                         i=0;
  485.                         data_pros();           //读取一次DHT11数据最少要大于100ms
  486.                 }
  487.                 delay(1000);
  488.                
  489.         }       
  490. }
复制代码

所有程序51hei提供下载:
程序设计.zip (47.92 KB, 下载次数: 48)
回复

使用道具 举报

ID:442461 发表于 2020-6-28 10:19 | 显示全部楼层
没有proteus 工程文件啊
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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