找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 7053|回复: 10
收起左侧

单片机+PT100+SHT11的温湿度检测系统仿真与程序源码

  [复制链接]
ID:331903 发表于 2018-5-17 10:08 | 显示全部楼层 |阅读模式
pt100+SHT11测温仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)

微信截图_20180517100737.png 0.jpg 0.png

0.jpg

单片机源程序如下:
  1. #include<reg51.h>
  2. #include <intrins.h>
  3. #include <math.h>    //Keil library
  4. #include <stdio.h>         //Keil library
  5. #define unchar unsigned char
  6. #define unint unsigned int
  7. #define port P1                              //LCD12864的8位数据口


  8. typedef union                   //定义共同类型
  9. { unsigned int i;           //i表示测量得到的温湿度数据(int 形式保存的数据)
  10.   unsigned char c;
  11. float f;                           //f表示测量得到的温湿度数据(float 形式保存的数据)
  12. } value;

  13. /******************************************12864函数声明******************************************/
  14. void delay_12864();                                   //延时函数
  15. void check_busy();                                   //检查是否“忙”
  16. void write_cmd(unchar cmd);                   //给LCD12864写命令。
  17. void set_page(unchar page);                   //设置显示的“页”。
  18. void set_line(unchar line);                   //设置显示的“行”。
  19. void set_column(unchar column);           //设置显示的“列”。
  20. void write_data(unchar dat);           //写数据。
  21. void set_onoff(unchar onoff);           //开关屏幕函数。
  22. void select_screen(unchar screen); //选择屏幕函数。
  23. void clear_screen(unchar screen);  //清屏函数。
  24. void initial();                                           //初始化LCD 12864
  25. void hz_LCDDisp16(unchar page,unchar column, unchar code *hzk,unchar num);        //显示函数。
  26. void print_SHT11_temp();           //显示输出SHT11的温度
  27. void print_SHT11_humi();                   //显示输出SHT11的湿度
  28. void print_PT100_temp();                   //显示输出PT100的温度
  29. void delay(int z);                           //z为毫秒数延时
  30. /*******************************12864的端口定义、文字库**********************************/
  31. //首先要选择“读,写”是对与谁。以人来说,读是LCD12864来读取人的指令或数据。写是给人写。
  32. sbit rs=P2^0;                                  //rs=1时,为读写数据。rs=0时,为读写指令。
  33. sbit rw=P2^1;                                  //rw=1时,为读数据(指令)。rw=0时,为写数据(指令)。(以人来说。)
  34. sbit en=P2^2;                                  //使能信号。
  35. sbit cs1=P2^3;                                  //片选信号,0时选中左半屏。
  36. sbit cs2=P2^4;                                  //片选信号,0时选中右半屏。
  37. char code hz_wen[]=   //温
  38. {
  39. 0x10,0x60,0x02,0x8C,0x00,0x00,0xFE,0x92,0x92,0x92,0x92,0x92,0xFE,0x00,0x00,0x00,
  40. 0x04,0x04,0x7E,0x01,0x40,0x7E,0x42,0x42,0x7E,0x42,0x7E,0x42,0x42,0x7E,0x40,0x00
  41. };                                         //度
  42. char code hz_du[]=
  43. {
  44. 0x00,0x00,0xFC,0x24,0x24,0x24,0xFC,0x25,0x26,0x24,0xFC,0x24,0x24,0x24,0x04,0x00,
  45. 0x40,0x30,0x8F,0x80,0x84,0x4C,0x55,0x25,0x25,0x25,0x55,0x4C,0x80,0x80,0x80,0x00
  46. };
  47. char code hz_shi[]=         //湿
  48. {
  49. 0x10,0x60,0x02,0x8C,0x00,0xFE,0x92,0x92,0x92,0x92,0x92,0x92,0xFE,0x00,0x00,0x00,
  50. 0x04,0x04,0x7E,0x01,0x44,0x48,0x50,0x7F,0x40,0x40,0x7F,0x50,0x48,0x44,0x40,0x00
  51. };
  52. char code maohao[]=                //:
  53. {
  54. 0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00
  55. };
  56. char code dian[]=                //.
  57. {
  58. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00
  59. };
  60. char code wenduhao[]=   //℃
  61. {
  62. 0x06,0x09,0x09,0xE6,0xF8,0x0C,0x04,0x02,0x02,0x02,0x02,0x02,0x04,0x1E,0x00,0x00,
  63. 0x00,0x00,0x00,0x07,0x1F,0x30,0x20,0x40,0x40,0x40,0x40,0x40,0x20,0x10,0x00,0x00
  64. };
  65. char code baifenhao[]=        //%
  66. {
  67. 0xF0,0x08,0xF0,0x00,0xE0,0x18,0x00,0x00,0x00,0x21,0x1C,0x03,0x1E,0x21,0x1E,0x00
  68. };
  69. char code fuhao[]=      //- 负号
  70. {
  71. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01
  72. };
  73. char code kongbai[]=        //空白
  74. {
  75. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
  76. };
  77. char code zero[]=      //0
  78. {
  79. 0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00
  80. };
  81. char code one[]=       //1
  82. {
  83. 0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00
  84. };
  85. char code two[]=       //2
  86. {
  87. 0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00
  88. };
  89. char code there[]=     //3
  90. {
  91. 0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00
  92. };
  93. char code four[]=       //4
  94. {
  95. 0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00
  96. };
  97. char code five[]=       //5
  98. {
  99. 0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00
  100. };
  101. char code six[]=        //6
  102. {
  103. 0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00
  104. };
  105. char code seven[]=      //7
  106. {
  107. 0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00
  108. };
  109. char code eight[]=      //8
  110. {
  111. 0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00
  112. };
  113. char code nine[]=       //9
  114. {
  115. 0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00
  116. };
  117. /******************************************PCF8591函数声明******************************************/
  118. void delay_6us();               //6us延迟函数
  119. void pcf8591_start();                        //启动信号函数
  120. void pcf8591_stop();                        //停止信号函数
  121. void pcf8591_ack();                                //应答信号函数
  122. void pcf8591_noack();                         //非应答信号函数
  123. void pcf8591_write(unchar cmd);        //单片机给pcf8591发送指令数据。
  124. char pcf8591_read();                        //单片机读取pcf8591发来的数据
  125. void pcf8591_process();                        //pcf8591把模拟量转换成数字量并进行显示
  126. /******************************************PCF8591定义**********************************************/
  127. sbit scl_pcf8591=P2^6;
  128. sbit sda_pcf8591=P2^7;
  129. unsigned char pt100_temp[4];
  130. /******************************************SHT11函数声明******************************************/
  131. void sht11_delay();                                //SHT11延迟函数
  132. void sht11_start();                                //SHT11的启动传输函数
  133. char sht11_read(unchar ack) ;        //单片机读取SHT11发来的数据
  134. char sht11_write(unchar cmd);        //单片机给SHT11发送指令数据。
  135. void sht11_restart();                        //SHT11“通信复位”
  136. char s_measure(unsigned char *p_value, unsigned char mode);//SHT11温湿度测量
  137. void zhuanhuan_sth11(float *p_shidu ,float *p_wendu);      //温湿度值转换及修正
  138. void sht11_process();                        //SHT11数据处理及显示
  139. /******************************************SHT11定义**********************************************/
  140. #define ACK   0             //结束数据传输;
  141. #define NoACK 1                                //继续通信
  142.                                                           //地址  命令  读/写
  143. #define ce_liang_wendu 0x03   //000   0001    1
  144. #define ce_liang_shidu 0x05   //000   0010    1
  145. #define RESET          0x1e   //000   1111    0
  146. sbit sht11_scl=P3^0;
  147. sbit sht11_sda=P3^1;
  148. char temp_print[7];                                                     //用于记录温度
  149. unsigned char humi_print[7];                                         //用于记录湿度
  150. /******************************************SHT11程序部分******************************************/
  151. /*SHT11延迟函数*/
  152. void sht11_delay()
  153. {
  154.         _nop_();
  155.         _nop_();
  156.         _nop_();
  157. }
  158. /*SHT11的启动传输函数*/
  159. void sht11_start()
  160. {
  161.     sht11_sda=1; sht11_scl=0;       //预先准备好开始。        
  162.         sht11_delay();
  163.         sht11_scl=1;
  164.         sht11_delay();
  165.         sht11_sda=0;
  166.         sht11_delay();
  167.         sht11_scl=0;
  168.         sht11_delay();
  169.         sht11_scl=1;
  170.         sht11_delay();
  171.         sht11_sda=1;
  172.         sht11_delay();
  173.         sht11_scl=0;
  174. }
  175. /*单片机读取SHT11发来的数据*/
  176. char sht11_read(unchar ack)
  177. {
  178.         unchar i=0,dat=0;
  179.         sht11_sda=1;                        //释放数据线
  180.         for(i=0x80;i>0;i>>=1)            //按位取数据,从高位开始依次按位取。
  181.         {
  182.           sht11_scl=1;
  183.           if(sht11_sda)
  184.           dat=dat|i;                                //读取1位的数据值。
  185.           sht11_scl=0;
  186.         }
  187.         sht11_sda=ack;                                //若读取完数据,结束通信。
  188.         sht11_scl=1;                                //sht11_sda=ack; sht11_scl=1; sht11_scl=0;  这三句是产生一个应答或非信号。
  189.         sht11_delay();
  190.         sht11_scl=0;
  191.         sht11_delay();
  192.         sht11_sda=1;                                //释放数据线。
  193.         return dat;
  194. }
  195. /*单片机给SHT11发送指令数据。*/
  196. char sht11_write(unchar cmd)
  197. {
  198.         unchar i=0,error=0;
  199.         for(i=0x80;i>0;i>>=1)  //按位发数据,从高位开始依次按位取。
  200.         {                                                   
  201.           if(i&cmd)                          //按位与,发送数据。
  202.             sht11_sda=1;
  203.           else sht11_sda=0;
  204.           sht11_scl=1;
  205.           sht11_delay();
  206.           sht11_scl=0;
  207.         }
  208.         sht11_sda=0;          // sht11_sda=0; sht11_scl=1; sht11_scl=0;  这三句是产生一个应答信号。
  209.         sht11_scl=1;
  210.         error=sht11_sda;          //检查通讯是否正常,为0是正常,1为错误。
  211.         sht11_delay();
  212.         sht11_scl=0;
  213.         sht11_sda=1;                  //释放数据线。
  214.         return error;
  215. }
  216. /*SHT11“通信复位”*/
  217. void sht11_restart()                //数据线保持高,时钟线产生9个脉冲。SHT11通信复位。
  218. {
  219.          unchar i;
  220.          sht11_sda=1; //预先准备。
  221.          sht11_scl=0;
  222.          for(i=0;i<9;i++)
  223.          {
  224.           sht11_scl=1;
  225.           sht11_scl=0;         
  226.          }
  227.         sht11_start();//启动传输。
  228. }
  229. /*SHT11温湿度测量*/
  230. char s_measure(unsigned char *p_value, unsigned char mode)
  231. {
  232.         unsigned int error=0;
  233.         unsigned int i;
  234.         sht11_start();                   //启动传输
  235.         switch(mode)                     //选择发送命令
  236.     {        
  237.                 case 0 : error+=sht11_write(ce_liang_wendu); break;                   //测量温度
  238.             case 1 : error+=sht11_write(ce_liang_shidu); break;                   //测量湿度
  239.             default: break;
  240.         }
  241.         for (i=0;i<65535;i++) if(sht11_sda==0) break; //等待测量结束
  242.         if(sht11_sda) error+=1;                // 如果长时间数据线没有拉低,说明测量错误
  243.         *(p_value) =sht11_read(NoACK);    //读第一个字节,高字节 (MSB)
  244.         *(p_value+1)=sht11_read(NoACK);    //读第二个字节,低字节 (LSB)
  245.         *(p_value+1)=sht11_read(ACK);
  246.         return error;                                         // error=1 通讯错误
  247. }
  248. /*温湿度值转换及修正*/
  249. void zhuanhuan_sth11(float *p_shidu ,float *p_wendu)
  250. {
  251.     //温度转换、修正的系数值、常量值。
  252.         const float C1=-4.0;              
  253.         const float C2=+0.0405;           
  254.         const float C3=-0.0000028;        
  255.         const float T1=+0.01;            
  256.         const float T2=+0.00008;         
  257.         //定义一些温湿度相关变量。
  258.         float RH=*p_shidu;                // 取出SHT11测量的12位湿度值
  259.         float T=*p_wendu;                 // 取出SHT11测量的14位温度值
  260.         float RH_xiangdui;                // 相对湿度
  261.         float T_C;                        // 转换后的温度
  262.         //温湿度转换、修正公式。
  263.         T_C=T*0.01 - 40;                           //温度转换
  264.         RH_xiangdui=C3*RH*RH + C2*RH + C1;         //相对湿度修正
  265.         //返回转换、修正后的值。                                                                           
  266.         *p_wendu=T_C;                         //返回温度结果
  267.         *p_shidu=RH_xiangdui;                     //返回湿度结果
  268. }
  269. /*SHT11数据处理及显示*/
  270. void sht11_process()
  271. {
  272.   int temp;
  273.   unint humi;
  274.   value humi_val,temp_val;                //定义两个共同体,一个用于湿度,一个用于温度
  275.   unchar error,wendu=0,shidu=1;                    //用于检验是否出现错误

  276.           error=0;                                           //初始化error=0,即没有错误
  277.                 error+=s_measure(( char*)&temp_val.i,wendu); //温度测量
  278.                 error+=s_measure((unsigned char*)&humi_val.i,shidu); //湿度测量
  279.             if(error!=0)                                         //如果发生错误,系统复位
  280.                    sht11_restart();                 
  281.             else
  282.             {
  283.                         humi_val.f=(float)humi_val.i;                   //转换为浮点数
  284.                      temp_val.f=(float)temp_val.i;                   //转换为浮点数
  285.                      zhuanhuan_sth11(&humi_val.f,&temp_val.f);       //修正相对湿度及温度
  286.                            temp=temp_val.f*10;
  287.                      humi=humi_val.f*10;
  288.    
  289.                       temp_print[0]=temp/1000;                     //温度百位
  290.                         temp_print[1]=temp%1000/100;             //温度十位        
  291.                         temp_print[2]=temp%1000%100/10;            //温度个位
  292.                       temp_print[3]=10;                                        //小数点
  293.                            temp_print[4]=temp%10;                                //温度小数点后第一位               
  294.                         temp_print[5]=11;                                        //显示温度符号℃               
  295.                         print_SHT11_temp();                                        //输出温度                     
  296.                         
  297.                     humi_print[0]=humi/1000;                     //湿度百位
  298.                         humi_print[1]=humi%1000/100;             //湿度十位                           
  299.                         humi_print[2]=humi%1000%100/10;                //湿度个位
  300.                       humi_print[3]=10;                                        //小数点
  301.                            humi_print[4]=humi%10;                                //湿度小数点后第一位
  302.                         humi_print[5]=11;        
  303.                     if(humi_print[0]==1)                                //如果湿度到100则显示99.9
  304.                         {
  305.                         humi_print[0]=0;                                 
  306.                         humi_print[1]=9;                                                               
  307.                         humi_print[2]=9;
  308.                         humi_print[4]=9;
  309.                         }
  310.                         print_SHT11_humi();                                        //输出湿度                           
  311.             }  
  312.                 delay(800);                             //等待足够长的时间,以进行下一次转换        
  313. }
  314. /******************************************PCF8591程序部分******************************************/
  315. /*6us延迟函数*/
  316. void delay_6us()
  317. {
  318.         _nop_();_nop_();_nop_();
  319.         _nop_();_nop_();_nop_();
  320. }
  321. /*启动信号函数*/
  322. void pcf8591_start()         
  323. {
  324.          sda_pcf8591=1;
  325.          delay_6us();
  326.          scl_pcf8591=1;
  327.          delay_6us();
  328.          sda_pcf8591=0;                  //这时候 启动开始。
  329.          delay_6us();
  330.          scl_pcf8591=0;
  331. }
  332. /*停止信号函数*/
  333. void pcf8591_stop()                 
  334. {
  335.          sda_pcf8591=0;
  336.          delay_6us();
  337.          scl_pcf8591=1;
  338.          delay_6us();
  339.          sda_pcf8591=1;
  340.          delay_6us();
  341. }
  342. /*应答信号函数*/
  343. void pcf8591_ack()           
  344. {
  345.          sda_pcf8591=0;
  346.          delay_6us();
  347.          scl_pcf8591=1;
  348.          delay_6us();
  349.          scl_pcf8591=0;
  350.          delay_6us();
  351. }
  352. /*非应答信号函数*/
  353. void pcf8591_noack()  
  354. {
  355.          sda_pcf8591=1;
  356.          scl_pcf8591=1;
  357.          delay_6us();
  358.          scl_pcf8591=0;
  359. }
  360. /*单片机给pcf8591发送指令数据。*/
  361. void pcf8591_write(unchar cmd)
  362. {
  363.         unchar i=0,error=0;
  364.         for(i=0x80;i>0;i>>=1)  //按位发数据,从高位开始依次按位取。
  365.         {                                                   
  366.           if(i&cmd)                           //按位与,发送数据。
  367.             sda_pcf8591=1;
  368.           else sda_pcf8591=0;
  369.           scl_pcf8591=1;
  370.           delay_6us();
  371.           scl_pcf8591=0;
  372.         }
  373.         sda_pcf8591=1;                  //释放数据线。
  374. }
  375. /*单片机读取pcf8591发来的数据*/
  376. char pcf8591_read()
  377. {
  378.         unchar i=0,dat=0;
  379.         sda_pcf8591=1;                        //释放数据线
  380.         for(i=0x80;i>0;i>>=1)            //按位取数据,从高位开始依次按位取。
  381.         {
  382.           scl_pcf8591=1;
  383.           if(sda_pcf8591)
  384.           dat=dat|i;                                //读取1位的数据值。
  385.           scl_pcf8591=0;
  386.         }
  387.         sda_pcf8591=1;                                //释放数据线。
  388.         return dat;
  389. }
  390. /*pcf8591把模拟量转换成数字量并进行显示*/
  391. void pcf8591_process()
  392. {        unchar temp;
  393.         value pcf8591_value;
  394.             pcf8591_start();
  395.                  pcf8591_write(0x90);        //上来必须先发地址,选择是什么操作,这里进行写操作
  396.                 pcf8591_ack();
  397.                 pcf8591_write(0x00);        //输出模拟量         0通道。
  398.                 pcf8591_ack();
  399.                
  400.                 pcf8591_start();        //开始进行模数转换
  401.                 pcf8591_write(0x91);
  402.                 pcf8591_ack();
  403.                 pcf8591_value.c=pcf8591_read();
  404.                 pcf8591_noack();
  405.                 pcf8591_stop();
  406.                
  407.                 if(pcf8591_value.c>0xff)
  408.                 {
  409.                         pt100_temp[0]=1;                     //温度百位
  410.                         pt100_temp[1]=0;             //温度十位        
  411.                               pt100_temp[2]=0;            //温度个位
  412.                         pt100_temp[3]=11;
  413.                         print_PT100_temp();                                
  414.                 }
  415.                
  416.                 if(pcf8591_value.c<=0xff)
  417.                 {
  418.                 pcf8591_value.f=(float)pcf8591_value.c;
  419.                 temp=pcf8591_value.f/2.55+0.5;           //加0.5为了四舍五入               
  420.                 pt100_temp[0]=temp/100;                     //温度百位
  421.                 pt100_temp[1]=temp%100/10;             //温度十位        
  422.                       pt100_temp[2]=temp%10;            //温度个位
  423.                 pt100_temp[3]=11;
  424.                 print_PT100_temp();
  425.                 }
  426. }
  427. /******************************************12864程序部分********************************************/
  428. /*延时函数*/
  429. void delay_12864()                                 
  430. {
  431.   unchar i,j;
  432.   for(i=0;i>10;i++)
  433.   for(j=0;j>256;j++);

  434. }
  435. /*检查LCD12864是否“忙”*/
  436. void check_busy()                          //检查LCD12864是否“忙”   数据线的最高位DB7为1时则“忙”。
  437. {                                                          //因为每次LCD12864读指令或者数据时候,都要判断“自己”是否“忙”。
  438.   P1=0x00;
  439.   rs=0;                                                  //选择 指令。
  440.   rw=1;                                                  //选择 (人)读。
  441.   en=1;                                                  //这时LCD12864写出来一个指令,告诉人,是否“忙”,这个指令从数据口出来,也就是给了P1。
  442.   while(P1&0x80);                          //直到,数据线的最高位DB7为0时则“不忙”。
  443.   en=0;                                                  //en由1——0,产生一个下降沿,才能锁存数据。
  444. }
  445. /*给LCD12864写命令。*/
  446. void write_cmd(unchar cmd)          //给LCD12864写命令。
  447. {
  448.   check_busy();                                  //检查“忙不忙”。
  449.   rs=0;                                                  //选择 指令。
  450.   rw=0;                                                  //选择 (人)写。
  451.   port=cmd;                                          //指令赋给数据端。
  452.   en=1;                                                  //使能信号。
  453.   delay_12864();                                          //延时。
  454.   en=0;
  455. }
  456. /*设置显示的“页”*/
  457. void set_page(unchar page)          //设置显示的“页”。因为一页有8行,一共有64行,所以LCD12864有8页。
  458. {
  459.   page=0xb8|page;                          //“页”的首地址为0xb8。
  460.   write_cmd(page);                          //把命令给LCD12864。
  461. }
  462. /*设置显示的“行”*/
  463. void set_line(unchar line)          //设置显示的“行”。一般是从第0行开始。
  464. {
  465.   line=0xc0|line;                          //第0行的地址为0xc0。
  466.   write_cmd(line);                          //把命令给LCD12864。
  467. }
  468. /*设置显示的“列”*/
  469. void set_column(unchar column) //设置显示的“列”。
  470. {
  471.   column=column&0x3f;                  //因为一个屏的“列”最多有64列,所以防止越出来。
  472.   column=0x40|column;                  //“列”的首地址为0x40。
  473.   write_cmd(column);                  //把命令给LCD12864。
  474. }
  475. /*单片机给12864写数据*/
  476. void write_data(unchar dat)          //写数据。
  477. {
  478.   check_busy();                                 //检查“忙不忙”。
  479.   rs=1;                                                 //选择 数据。
  480.   rw=0;                                                 //选择 (人)写。
  481.   port=dat;                                         //数据赋给数据端。
  482.   en=1;
  483.   delay_12864();                                                
  484.   en=0;
  485. }
  486. /*开关屏幕函数*/
  487. void set_onoff(unchar onoff)         //开关屏幕函数。0x3f是开,0x3e是关。
  488. {
  489.   onoff=0x3e|onoff;                         //选择开或关。
  490.   write_cmd(onoff);                         //把命令给LCD12864。
  491. }
  492. /*选择屏幕函数*/
  493. void select_screen(unchar screen)   //选择屏幕函数。
  494. {
  495.   switch(screen)
  496.   {
  497.     case 0:cs1=0;cs2=0;break;          //选择全屏。
  498.         case 1:cs1=0;cs2=1;break;          //选择左半屏。
  499.         case 2:cs1=1;cs2=0;break;          //选择右半屏。
  500.         default:break;
  501.   }
  502. }
  503. /*清屏函数*/
  504. void clear_screen(unchar screen)         //清屏函数。
  505. {
  506.   unchar p,c;
  507.   select_screen(screen);         //选屏幕。
  508.   for(p=0;p<8;p++)                                 //控制“页”数。从第0页开始。每页每页进行写。
  509.   {
  510.     set_page(p);
  511.         set_column(0);
  512.         for(c=0;c<64;c++)                         //控制“列” 。从第0列开始。每页最多可写32个中文文字或64个ASCII字符
  513.         {
  514.           write_data(0x00);                         //写入“0”(就是空白)。列地址自动加1。
  515.         }
  516.   }
  517. }
  518. /*初始化LCD 12864*/
  519. void initial()                           //初始化LCD 12864
  520. {
  521.   check_busy();
  522.   select_screen(0);             //选择全屏
  523.   set_onoff(0);                           //关闭屏幕
  524.   select_screen(0);             //选择全屏
  525.   set_onoff(1);                           //开启屏幕
  526.   select_screen(0);             //选择全屏
  527.   clear_screen(0);                    //清空屏幕
  528.   set_line(0);                            //从第0行开始
  529. }
  530. /*12864显示函数*/
  531. void hz_LCDDisp16(unchar page,unchar column, unchar code *hzk,unchar num)        //显示函数。
  532. {
  533.         unchar j=0,i=0;
  534.         for(j=0;j<2;j++)
  535.         {
  536.                 write_cmd(0xb8+page+j);
  537.                 write_cmd(0x40+column);
  538.                 if(num==0)
  539.                 {
  540.                  for(i=0;i<16;i++)
  541.                         write_data(hzk[16*j+i]);
  542.                 }
  543.                 else
  544.                   for(i=0;i<8;i++)
  545.                         write_data(hzk[8*j+i]);
  546.         }
  547. }
  548. /*12864显示SHT11输出的温度*/
  549. void print_SHT11_temp()             //显示输出温度
  550. {        
  551.            unchar i,j;
  552.           for(i=0;i<6;i++)
  553.         {
  554.         if(i==3)
  555.         {
  556.            j=0;
  557.         }
  558.          if(i<3)
  559.          {
  560.            cs1=0;
  561.        cs2=1;
  562.            if(temp_print[0]==0&&i==0)
  563.             {
  564.                   hz_LCDDisp16(0,38,kongbai,1);
  565.                   j=8;
  566.                   i++;
  567.                 }
  568.            if(temp_print[1]==0&&temp_print[0]==0)
  569.            {
  570.                     hz_LCDDisp16(0,46,kongbai,1);
  571.                  j=16;
  572.                  i++;
  573.            }

  574.            if(temp_print[1]<0||temp_print[2]<0)
  575.            {
  576.                     temp_print[1]=abs(temp_print[1]);
  577.                  temp_print[2]=abs(temp_print[2]);
  578.                  temp_print[4]=abs(temp_print[4]);
  579.                  hz_LCDDisp16(0,38,fuhao,1);
  580.            }
  581.           switch(temp_print[i])
  582.           {
  583.                   case 0:hz_LCDDisp16(0,j+38,zero,1);break;
  584.                 case 1:hz_LCDDisp16(0,j+38,one,1);break;
  585.                 case 2:hz_LCDDisp16(0,j+38,two,1);break;
  586.                 case 3:hz_LCDDisp16(0,j+38,there,1);break;
  587.                 case 4:hz_LCDDisp16(0,j+38,four,1);break;
  588.                 case 5:hz_LCDDisp16(0,j+38,five,1);break;
  589.                 case 6:hz_LCDDisp16(0,j+38,six,1);break;
  590.                 case 7:hz_LCDDisp16(0,j+38,seven,1);break;
  591.                 case 8:hz_LCDDisp16(0,j+38,eight,1);break;
  592.                 case 9:hz_LCDDisp16(0,j+38,nine,1);break;
  593.                 case 10:hz_LCDDisp16(0,j+38,dian,1);break;         
  594.           }
  595.      }
  596.          else if(i>=3)
  597.          { cs1=1;
  598.        cs2=0;
  599.             switch(temp_print[i])
  600.           {
  601.                   case 0:hz_LCDDisp16(0,j,zero,1);break;
  602.                 case 1:hz_LCDDisp16(0,j,one,1);break;
  603.                 case 2:hz_LCDDisp16(0,j,two,1);break;
  604.                 case 3:hz_LCDDisp16(0,j,there,1);break;
  605.                 case 4:hz_LCDDisp16(0,j,four,1);break;
  606.                 case 5:hz_LCDDisp16(0,j,five,1);break;
  607.                 case 6:hz_LCDDisp16(0,j,six,1);break;
  608.                 case 7:hz_LCDDisp16(0,j,seven,1);break;
  609.                 case 8:hz_LCDDisp16(0,j,eight,1);break;
  610.                 case 9:hz_LCDDisp16(0,j,nine,1);break;
  611.                 case 10:hz_LCDDisp16(0,j,dian,1);break;
  612.                 case 11:hz_LCDDisp16(0,j,wenduhao,0);break;
  613.           }
  614.          }        
  615.         j+=8;        
  616.    }
  617. }
  618. /*12864显示SHT11输出的湿度*/
  619. void print_SHT11_humi()
  620. {        
  621.            unchar i,j;
  622.           for(i=0;i<6;i++)
  623.         {
  624.         if(humi_print[0]==0&&i==0)
  625.         {
  626.           i++;
  627.           j=8;         
  628.         }
  629.         if(i==3)
  630.         {
  631.            j=0;
  632.         }
  633.          if(i<3)
  634.          {
  635.            cs1=0;
  636.        cs2=1;
  637.           if(humi_print[0]==0&&i==0)
  638.             {
  639.                   hz_LCDDisp16(2,38,kongbai,1);
  640.                   j=8;
  641.                   i++;
  642.                 }
  643.            if(humi_print[1]==0&&humi_print[0]==0)
  644.            {
  645.                     hz_LCDDisp16(2,46,kongbai,1);
  646.                  j=16;
  647.                  i++;
  648.            }
  649.           switch(humi_print[i])
  650.           {
  651.                   case 0:hz_LCDDisp16(2,j+38,zero,1);break;
  652.                 case 1:hz_LCDDisp16(2,j+38,one,1);break;
  653.                 case 2:hz_LCDDisp16(2,j+38,two,1);break;
  654.                 case 3:hz_LCDDisp16(2,j+38,there,1);break;
  655.                 case 4:hz_LCDDisp16(2,j+38,four,1);break;
  656.                 case 5:hz_LCDDisp16(2,j+38,five,1);break;
  657.                 case 6:hz_LCDDisp16(2,j+38,six,1);break;
  658.                 case 7:hz_LCDDisp16(2,j+38,seven,1);break;
  659.                 case 8:hz_LCDDisp16(2,j+38,eight,1);break;
  660.                 case 9:hz_LCDDisp16(2,j+38,nine,1);break;
  661.                 case 10:hz_LCDDisp16(2,j+38,dian,1);break;         
  662.           }
  663.      }
  664.          else if(i>=3)
  665.          { cs1=1;
  666.        cs2=0;
  667.             switch(humi_print[i])
  668.           {
  669.                   case 0:hz_LCDDisp16(2,j,zero,1);break;
  670.                 case 1:hz_LCDDisp16(2,j,one,1);break;
  671.                 case 2:hz_LCDDisp16(2,j,two,1);break;
  672.                 case 3:hz_LCDDisp16(2,j,there,1);break;
  673.                 case 4:hz_LCDDisp16(2,j,four,1);break;
  674.                 case 5:hz_LCDDisp16(2,j,five,1);break;
  675.                 case 6:hz_LCDDisp16(2,j,six,1);break;
  676.                 case 7:hz_LCDDisp16(2,j,seven,1);break;
  677.                 case 8:hz_LCDDisp16(2,j,eight,1);break;
  678.                 case 9:hz_LCDDisp16(2,j,nine,1);break;
  679.                 case 10:hz_LCDDisp16(2,j,dian,1);break;
  680.                 case 11:hz_LCDDisp16(2,j,baifenhao,1);break;
  681.           }
  682.          }        
  683.         j+=8;        
  684.    }
  685. }
  686. /*12864显示PT100输出的温度*/
  687. void print_PT100_temp()
  688. {
  689. unchar i,j=0;
  690.           for(i=0;i<4;i++)
  691.         {
  692.         if(i==3)
  693.         {
  694.            j=0;
  695.         }
  696.          if(i<3)
  697.          {
  698.            cs1=0;
  699.        cs2=1;
  700.            if(pt100_temp[0]==0&&i==0)
  701.             {
  702.                   hz_LCDDisp16(6,38,kongbai,1);
  703.                   j=8;
  704.                   i++;
  705.                 }
  706.            if(pt100_temp[1]==0&&pt100_temp[0]==0)
  707.            {
  708.                     hz_LCDDisp16(6,46,kongbai,1);
  709.                  j=16;
  710.                  i++;
  711.            }
  712. /*
  713.            if(temp_print[1]<0||temp_print[2]<0)
  714.            {
  715.                     temp_print[1]=abs(temp_print[1]);
  716.                  temp_print[2]=abs(temp_print[2]);
  717.                  temp_print[4]=abs(temp_print[4]);
  718.                  hz_LCDDisp16(0,38,fuhao,1);
  719.            }
  720. */
  721.           switch(pt100_temp[i])
  722.           {
  723.                   case 0:hz_LCDDisp16(6,j+38,zero,1);break;
  724.                 case 1:hz_LCDDisp16(6,j+38,one,1);break;
  725.                 case 2:hz_LCDDisp16(6,j+38,two,1);break;
  726.                 case 3:hz_LCDDisp16(6,j+38,there,1);break;
  727.                 case 4:hz_LCDDisp16(6,j+38,four,1);break;
  728.                 case 5:hz_LCDDisp16(6,j+38,five,1);break;
  729.                 case 6:hz_LCDDisp16(6,j+38,six,1);break;
  730.                 case 7:hz_LCDDisp16(6,j+38,seven,1);break;
  731.                 case 8:hz_LCDDisp16(6,j+38,eight,1);break;
  732.                 case 9:hz_LCDDisp16(6,j+38,nine,1);break;         
  733.           }
  734.      }
  735.          else if(i>=3)
  736.          { cs1=1;
  737.        cs2=0;
  738.             switch(pt100_temp[i])
  739.           {
  740.                   case 0:hz_LCDDisp16(6,j,zero,1);break;
  741.                 case 1:hz_LCDDisp16(6,j,one,1);break;
  742.                 case 2:hz_LCDDisp16(6,j,two,1);break;
  743.                 case 3:hz_LCDDisp16(6,j,there,1);break;
  744.                 case 4:hz_LCDDisp16(6,j,four,1);break;
  745.                 case 5:hz_LCDDisp16(6,j,five,1);break;
  746.                 case 6:hz_LCDDisp16(6,j,six,1);break;
  747.                 case 7:hz_LCDDisp16(6,j,seven,1);break;
  748.                 case 8:hz_LCDDisp16(6,j,eight,1);break;
  749.                 case 9:hz_LCDDisp16(6,j,nine,1);break;
  750.                 case 11:hz_LCDDisp16(6,j,wenduhao,0);break;
  751.           }
  752.          }        
  753.         j+=8;        
  754.    }        
  755. }

  756. /*z为毫秒数延迟*/
  757. void delay(int z)                //z为毫秒数
  758. {
  759.         int x,y;
  760.         for(x=z;x>0;x--)
  761.                 for(y=125;y>0;y--);
  762. }
  763. /*************************************************************************************************/
  764. void main()
  765. {


  766.   initial();                                  //初始化。
  767.   clear_screen(0);                          //清屏。
  768.   cs1=0;                                          //选左半屏。
  769.   cs2=1;
  770.   hz_LCDDisp16(0,0,hz_wen,0);          //显示“温”字。
  771.   hz_LCDDisp16(0,15,hz_du,0);          //显示“度”字。
  772.   hz_LCDDisp16(0,30,maohao,1);          //显示“:”。
  773.   hz_LCDDisp16(2,0,hz_shi,0);          //显示“湿”字。
  774.   hz_LCDDisp16(2,17,hz_du,0);          //显示“度”字。
  775.   hz_LCDDisp16(2,31,maohao,1);    //显示“:”。

  776.   hz_LCDDisp16(6,0,hz_wen,0);          //显示“温”字。
  777.   hz_LCDDisp16(6,15,hz_du,0);          //显示“度”字。
  778.   hz_LCDDisp16(6,30,maohao,1);          //显示“:”。
  779.   sht11_restart();  
  780.    while(1)                                          //无限循环。
  781.   {
  782.            sht11_process();
  783.          pcf8591_process();
  784.   }        
  785. }

复制代码

所有资料51hei提供下载:
1111.zip (131.22 KB, 下载次数: 271)
回复

使用道具 举报

ID:317909 发表于 2018-5-19 10:10 | 显示全部楼层
非常好,正是我所需求的
回复

使用道具 举报

ID:228452 发表于 2018-5-26 04:12 | 显示全部楼层
Nice work 800 lines of code
Thanks
回复

使用道具 举报

ID:570882 发表于 2019-6-26 09:49 | 显示全部楼层
可以添加一个报警系统吗
回复

使用道具 举报

ID:558897 发表于 2019-7-9 14:38 | 显示全部楼层
太好了,我好喜欢哦
回复

使用道具 举报

ID:421308 发表于 2019-7-12 12:09 | 显示全部楼层
正好需要,太好了
回复

使用道具 举报

ID:303572 发表于 2020-2-11 23:37 | 显示全部楼层
可以添加控制部分么
回复

使用道具 举报

ID:706224 发表于 2020-5-10 16:18 | 显示全部楼层
为什么我编译程序的时候显示目标未创建啊
回复

使用道具 举报

ID:368810 发表于 2020-5-10 20:42 | 显示全部楼层
楼主,可以实现多点监测吗,想用在农业生产大棚里
回复

使用道具 举报

ID:371674 发表于 2020-6-19 10:59 | 显示全部楼层
感谢分享
回复

使用道具 举报

ID:911035 发表于 2021-6-1 16:32 | 显示全部楼层
非常好,正是我所需求的
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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