找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2670|回复: 0
收起左侧

做的环境监测装置,为什么仿真的时候显示屏显示的数据和传感器数据不一样呢

[复制链接]
ID:293297 发表于 2018-5-3 20:17 | 显示全部楼层 |阅读模式
200黑币
1.png
采用的是dht11温湿度传感器
代码如下:
  1. #include <reg52.h>                 //调用单片机头文件
  2. #define uchar unsigned char  //无符号字符型 宏定义        变量范围0~255
  3. #define uint  unsigned int         //无符号整型 宏定义        变量范围0~65535

  4. sbit beep = P1^4;   //蜂鸣器IO口定义

  5. bit flag_300ms ;

  6. sbit CS=P2^2;                //CS定义为P2口的第4位脚,连接ADC0832CS脚
  7. sbit SCL=P2^1;                //SCL定义为P2口的第3位脚,连接ADC0832SCL脚
  8. sbit DO=P2^0;                //DO定义为P2口的第4位脚,连接ADC0832DO脚

  9. //  按键的IO变量的定义
  10. uchar key_can;                 //按键值的变量


  11. uchar menu_1;        //菜单设计的变量
  12. uint t_high = 30,t_low = 10;        //温度报警参数
  13. uint s_high = 90,s_low = 10;        //湿度报警参数
  14. uint yanwu_h;
  15. long yanwu;
  16. uchar flag_w_bj_en,flag_s_bj_en;

  17. /***************************************************************
  18. * 名称 : delay_1ms()
  19. * 功能 : 延时1ms函数
  20. * 输入 : q
  21. * 输出 : 无
  22. ****************************************************************/
  23. void delay_1ms(uint q)
  24. {
  25.         uint i,j;
  26.         for(i=0;i<q;i++)
  27.                 for(j=0;j<120;j++);
  28. }

  29. sbit dht11=P1^5;         //温度传感器IO口定义
  30. uchar table_dht11[5]={1,2,3,4,5};


  31. uchar code table_num[]="0123456789abcdefg";

  32. sbit rs=P1^0;         //寄存器选择信号 H:数据寄存器          L:指令寄存器
  33. sbit rw=P1^1;         //寄存器选择信号 H:数据寄存器          L:指令寄存器
  34. sbit e =P1^2;         //片选信号   下降沿触发

  35. /********************************************************************
  36. * 名称 : delay_uint()
  37. * 功能 : 小延时。
  38. * 输入 : 无
  39. * 输出 : 无
  40. ***********************************************************************/
  41. void delay_uint(uint q)
  42. {
  43.         while(q--);
  44. }

  45. /********************************************************************
  46. * 名称 : write_com(uchar com)
  47. * 功能 : 1602命令函数
  48. * 输入 : 输入的命令值
  49. * 输出 : 无
  50. ***********************************************************************/
  51. void write_com(uchar com)
  52. {
  53.         e=0;
  54.         rs=0;
  55.         rw=0;
  56.         P0=com;
  57.         delay_uint(25);
  58.         e=1;
  59.         delay_uint(100);
  60.         e=0;
  61. }

  62. /********************************************************************
  63. * 名称 : write_data(uchar dat)
  64. * 功能 : 1602写数据函数
  65. * 输入 : 需要写入1602的数据
  66. * 输出 : 无
  67. ***********************************************************************/
  68. void write_data(uchar dat)
  69. {
  70.         e=0;
  71.         rs=1;
  72.         rw=0;
  73.         P0=dat;
  74.         delay_uint(25);
  75.         e=1;
  76.         delay_uint(100);
  77.         e=0;        
  78. }


  79. /***********************lcd1602上显示特定的字符****0XDF 度********************/
  80. void write_zifu(uchar hang,uchar add,uchar date)
  81. {
  82.         if(hang==1)   
  83.                 write_com(0x80+add);
  84.         else
  85.                 write_com(0x80+0x40+add);
  86.         write_data(date);        
  87. }

  88. /***********************lcd1602上显示两位十进制数************************/
  89. void write_sfm2(uchar hang,uchar add,uint date)
  90. {
  91.         if(hang==1)   
  92.                 write_com(0x80+add);
  93.         else
  94.                 write_com(0x80+0x40+add);
  95.         write_data(0x30+date/10%10);
  96.         write_data(0x30+date%10);        
  97. }


  98. /***********************lcd1602上显示两位十进制数************************/
  99. void write_sfm_yanwu(uchar hang,uchar add,uint date)
  100. {
  101.         if(hang==1)   
  102.                 write_com(0x80+add);
  103.         else
  104.                 write_com(0x80+0x40+add);
  105.         if(date/100%10 == 0)
  106.                 write_data(' ');
  107.         else
  108.                 write_data(0x30+date/100%10);
  109.         write_data(0x30+date/10%10);
  110.         write_data(0x30+date%10);        
  111. }




  112. /***********************lcd1602上显示这字符函数************************/
  113. void write_string(uchar hang,uchar add,uchar *p)
  114. {
  115.         if(hang==1)   
  116.                 write_com(0x80+add);
  117.         else
  118.                 write_com(0x80+0x40+add);
  119.                 while(1)                                                                                                                 
  120.                 {
  121.                         if(*p == '\0')  break;
  122.                         write_data(*p);
  123.                         p++;
  124.                 }        
  125. }

  126. /***********************lcd1602初始化设置************************/
  127. void init_1602()        //lcd1602初始化
  128. {
  129.         write_com(0x38);        
  130.         write_com(0x0c);
  131.         write_com(0x06);
  132.         delay_uint(1000);
  133.         write_string(1,0,"    YW:000PPM     ");        
  134.         write_string(2,0,"  W:    S:  %RH    ");        
  135.         write_zifu(2,6,0xdf);        //显示度               
  136. }

  137. /***********读数模转换数据********************************************************/        
  138. //请先了解ADC0832模数转换的串行协议,再来读本函数,主要是对应时序图来理解,本函数是模拟0832的串行协议进行的
  139. unsigned char ad0832read(bit SGL,bit ODD)
  140. {
  141.         unsigned char i=0,value=0,value1=0;               
  142.         SCL=0;
  143.         DO=1;
  144.         CS=0;                //开始
  145.         SCL=1;                //第一个上升沿        
  146.         SCL=0;
  147.         DO=ODD;
  148.         SCL=1;          //第二个上升沿
  149.         SCL=0;
  150.         DO=SGL;
  151.         for(i=0;i<8;i++)
  152.         {
  153.                 SCL=0; //开始从第四个下降沿接收数据
  154.                 value<<=1;
  155.                 SCL=1;
  156.                 if(DO)
  157.                         value++;                                                
  158.         }
  159.         return value;
  160. }

  161. /*************定时器0初始化程序***************/
  162. void time_init()         
  163. {
  164.         EA   = 1;                   //开总中断
  165.         TMOD = 0X01;          //定时器0、定时器1工作方式1
  166.         ET0  = 1;                  //开定时器0中断
  167.         TR0  = 1;                  //允许定时器0定时
  168. }

  169. /********************独立按键程序*****************/
  170. uchar key_can;         //按键值

  171. void key()             //独立按键程序
  172. {
  173.         static uchar key_new;
  174.         key_can = 20;               //按键值还原
  175.         P3 |= 0xf0;
  176.         if((P3 & 0xf0) != 0xf0)                //按键按下
  177.         {
  178.                 delay_1ms(1);                     //按键消抖动
  179.                 if(((P3 & 0xf0) != 0xf0) && (key_new == 1))
  180.                 {                                                //确认是按键按下
  181.                         key_new = 0;
  182.                         switch(P3 & 0xf0)
  183.                         {
  184.                                 case 0xa0: key_can = 1; break;           //得到k1键值
  185.                                 case 0xc0: key_can = 2; break;           //得到K2键值
  186.                                 case 0x80: key_can = 3; break;           //得到k3键值
  187.                         }
  188.                 }                        
  189.         }
  190.         else
  191.                 key_new = 1;        
  192. }

  193. /****************按键显示函数***************/
  194. void key_with()
  195. {
  196.         if(key_can == 1)           //设置键
  197.         {
  198.                 menu_1 ++;
  199.                 if(menu_1 > 5)
  200.                 {
  201.                         menu_1 = 0;
  202.                         init_1602();  //lcd1602初始化                        
  203.                 }
  204.                 if(menu_1 == 1)                                 //初始化显示
  205.                 {
  206.                         write_string(1,0," WH:    WL:     ");
  207.                         write_string(2,0," SH:  % SL:  %  ");
  208.                         write_zifu(1,6,0xdf);          //显示度               
  209.                         write_zifu(1,13,0xdf);          //显示度               
  210.                         write_sfm2(1,4,t_high);          //显示温度
  211.                         write_sfm2(1,11,t_low);          //显示温度
  212.                         write_sfm2(2,4,s_high);   //显示湿度        
  213.                         write_sfm2(2,11,s_low);   //显示湿度        
  214.                 }
  215.                 if(menu_1 == 5)                                 //初始化显示
  216.                 {
  217.                         write_string(1,0,"   Set Yanwu    ");
  218.                         write_string(2,0,"     000PPM     ");

  219.                 }
  220.         }
  221.         if(menu_1 == 1)                        //设置高温报警
  222.         {
  223.                 if(key_can == 2)
  224.                 {
  225.                         t_high ++ ;                //设置高温值加1         
  226.                         if(t_high > 99)
  227.                                 t_high = 99;
  228.                 }
  229.                 if(key_can == 3)
  230.                 {
  231.                         t_high -- ;                //设置高温值减1         
  232.                         if(t_high <= t_low)
  233.                                 t_high = t_low + 1;
  234.                 }
  235.                 write_sfm2(1,4,t_high);           //显示温度
  236.                 write_com(0x80+3);             //将光标移动到秒个位
  237.                 write_com(0x0f);                    //显示光标并且闪烁        
  238.         }        
  239.         if(menu_1 == 2)                        //设置低温报警
  240.         {
  241.                 if(key_can == 2)
  242.                 {
  243.                         t_low ++ ;                        //设置低温值加1
  244.                         if(t_low >= t_high)
  245.                                 t_low = t_high - 1;
  246.                 }
  247.                 if(key_can == 3)                         //设置高温值减1
  248.                 {
  249.                         t_low -- ;                        
  250.                         if(t_low <= 1)
  251.                                 t_low = 1;
  252.                 }
  253.                 write_sfm2(1,11,t_low);   //显示湿度        
  254.                 write_com(0x80+10);            //将光标移动到秒个位
  255.                 write_com(0x0f);                    //显示光标并且闪烁        
  256.         }
  257.         if(menu_1 == 3)                        //设置高湿报警
  258.         {
  259.                 if(key_can == 2)
  260.                 {
  261.                         s_high ++ ;                //设置高湿值加1         
  262.                         if(s_high > 99)
  263.                                 s_high = 99;
  264.                 }
  265.                 if(key_can == 3)
  266.                 {
  267.                         s_high -- ;                //设置高湿值减1         
  268.                         if(s_high <= s_low)
  269.                                 s_high = s_low + 1;
  270.                 }
  271.                 write_sfm2(2,4,s_high);           //显示湿度
  272.                 write_com(0x80+0x40+3);             //将光标移动到秒个位
  273.                 write_com(0x0f);                    //显示光标并且闪烁        
  274.         }        
  275.         if(menu_1 == 4)                        //设置低湿报警
  276.         {
  277.                 if(key_can == 2)
  278.                 {
  279.                         s_low ++ ;                        //设置低湿值加1
  280.                         if(s_low >= s_high)
  281.                                 s_low = s_high - 1;
  282.                 }
  283.                 if(key_can == 3)                         //设置低湿值减1
  284.                 {
  285.                         s_low -- ;                        
  286.                         if(s_low <= 1)
  287.                                 s_low = 1;
  288.                 }
  289.                 write_sfm2(2,11,s_low);           //显示湿度
  290.                 write_com(0x80+0x40+10);            //将光标移动到秒个位
  291.                 write_com(0x0f);                    //显示光标并且闪烁        
  292.         }
  293.         if(menu_1 == 5)                        //设置烟物
  294.         {
  295.                 if(key_can == 2)
  296.                 {
  297.                         yanwu_h ++ ;                        //设置烟物加1
  298.                         if(yanwu_h >= 999)
  299.                                 yanwu_h = 999;
  300.                 }
  301.                 if(key_can == 3)                         //设置烟物减1
  302.                 {
  303.                         yanwu_h -- ;                        
  304.                         if(yanwu_h <= 1)
  305.                                 yanwu_h = 1;
  306.                 }
  307.                 write_sfm_yanwu(2,5,yanwu_h);           //显示湿度
  308.                 write_com(0x80+0x40+7);            //将光标移动到秒个位
  309.                 write_com(0x0f);                    //显示光标并且闪烁        
  310.         }
  311.                         
  312. }

  313. /*****************读温湿度传感器程序****************/
  314. void dst11()
  315. {
  316.         static uint value;
  317.         uchar i,j;                         //读温湿度时不能打开中断
  318.         dht11 = 0;        
  319.         delay_1ms(18);
  320.         dht11 = 1;
  321.         delay_uint(4);         //50us
  322.         if(dht11 == 0)          //判断是否响应    0 为响应
  323.         {
  324.                 while(dht11 == 1);          //等待响应时间过完
  325.                 for(i=0;i<5;i++)
  326.                 {
  327.                         for(j=0;j<8;j++)
  328.                         {
  329.                                 table_dht11[i] <<= 1;
  330.                                 value = 0;
  331.                                 while(dht11 == 0);
  332.                                 delay_uint(4);         //50us         数据1的高电平时间为110us 低为27us
  333.                                 if(dht11 == 1)
  334.                                 {
  335.                                         table_dht11[i] |= 0x01;
  336.                                         value = 0;
  337.                                         while(dht11 == 1);          //等待响应时间过完
  338.                                 }                        
  339.                         }                        
  340.                 }                        
  341.         }
  342.         dht11 = 0;
  343. }


  344. /****************报警函数***************/
  345. void clock_h_l()
  346. {
  347.         if((table_dht11[2] >= t_high))           //温度上限报警
  348.         {                        
  349.                 flag_w_bj_en = 1;
  350.         }
  351.         else if((table_dht11[2] <= t_low))          //温度下限报警
  352.         {                        
  353.                 flag_w_bj_en = 1;
  354.         }
  355.         else
  356.         {        
  357.                 flag_w_bj_en = 0;
  358.         }

  359.         if((table_dht11[0] >= s_high))          //湿度上限报警
  360.         {
  361.                 flag_s_bj_en = 1;
  362.         }else if((table_dht11[0] <= s_low))         //湿度下限报警
  363.         {
  364.                 flag_s_bj_en = 1;
  365.         }else
  366.         {        
  367.                 flag_s_bj_en = 0;
  368.         }

  369.         if((flag_w_bj_en == 1) || (flag_s_bj_en == 1) || (yanwu >= yanwu_h))
  370.         {
  371.                 beep = ~beep;           //蜂鸣器报警
  372.         }
  373.         else
  374.         {
  375.                 beep = 1;
  376.         }
  377. }


  378. /******************主程序**********************/           
  379. void main()
  380. {               
  381.         beep = 0;                                //开机叫一声   
  382.         delay_1ms(150);
  383.         P0 = P1 = P2 = P3 = 0xff;
  384.         time_init();          //定时器初始化
  385.         init_1602();        //lcd1602初始化
  386.         dst11();            //先读出温湿度的值
  387.         while(1)
  388.         {
  389.                 if(flag_300ms == 1)
  390.                 {
  391.                         flag_300ms = 0;
  392.                         if(menu_1 == 0)           //开始界面显示的内容
  393.                         {               
  394.                                 if(beep == 1)
  395.                                         dst11();                //先读出温湿度的值
  396.                                 yanwu = ad0832read(1,0);        
  397.                                 yanwu = yanwu * 450 / 255.0;
  398.                                 yanwu = yanwu - 100;              //首先减去零点漂移,一般是1V
  399.                                 if(yanwu < 0)
  400.                                         yanwu = 0;        
  401.                                 write_sfm2(2,10,table_dht11[0]);   //显示湿度        
  402.                                 write_sfm2(2,4,table_dht11[2]);           //显示温度
  403.                                 write_sfm_yanwu(1,7,yanwu);                           //显示烟物
  404.                         }        
  405.                         clock_h_l();   //报警函数
  406.                 }
  407.                 key();
  408.                 if(key_can < 10)
  409.                 {
  410.                         key_with();                            //设置报警温度        
  411.                 }
  412.                 delay_1ms(1);
  413.         }
  414. }

  415. /*************定时器0中断服务程序***************/
  416. void time0_int() interrupt 1
  417. {        
  418.         static uchar value;
  419.         TH0 = 0x3c;
  420.         TL0 = 0xb0;     // 50ms
  421.         value ++;         
  422.         if(value % 6 == 0)
  423.         {
  424.                 flag_300ms = 1;           //300ms        
  425.                 value = 0;        
  426.         }
  427. }
复制代码


回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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