找回密码
 立即注册

QQ登录

只需一步,快速开始

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

温湿度仿真SHT11和1602显示

[复制链接]
跳转到指定楼层
楼主
SHT11温湿度仿真,自己拿去用
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)




流程图:


单片机源程序如下:
  1. #include<reg51.h>
  2. #include <intrins.h>  
  3. #include <math.h>   
  4. #include <stdio.h>   
  5. #define LCD_DB        P0
  6. sbit         LCD_RS=P2^0;   
  7. sbit         LCD_RW=P2^1;  
  8. sbit         LCD_E=P2^2;     
  9. sbit         beep = P1^7;
  10. sbit         key1 = P3^0;
  11. sbit         key2 = P3^1;
  12. sbit                     key3 = P3^2;
  13. sbit                     key4 = P3^3;

  14. unsigned char Time;                  //用来存放定时时间
  15. unsigned char Second;
  16. unsigned char w;  //标志位
  17. unsigned char wendumode = 0;
  18. unsigned char shidumode = 0;
  19. unsigned char  wenduCB = 40;
  20. unsigned char  shiduCB = 100;
  21. unsigned int wendu,shidu;     

  22. /******定义函数****************/
  23. #define uchar unsigned char
  24. #define uint unsigned int
  25. void LCD_init(void);                          //初始化函数
  26. void LCD_write_command(uchar command);        //写指令函数
  27. void LCD_write_data(uchar dat);               //写数据函数  
  28. void LCD_disp_char(uchar x,uchar y,uchar dat);//在某个屏幕位置上显示一个字符,X(0-15),y(1-2)  
  29. void LCD_disp_str(uchar x,uchar y,uchar *str); //LCD1602显示字符串函数
  30. void delay_n10us(uint n);                     //延时函数
  31. void kcankey()
  32. {

  33.                 if(key1==0)
  34.                 {
  35.                   delay_n10us(1000);
  36.                         if(key1==0)
  37.                         {
  38.                           wendumode = 1;
  39.                                 shidumode = 0;
  40.                         }
  41.                 }
  42.                 if(key2==0)
  43.                 {
  44.                   delay_n10us(1000);
  45.                         if(key2==0)
  46.                         {
  47.                           wendumode = 0;
  48.                                 shidumode = 1;
  49.                         }
  50.                 }
  51.                 if(wendumode==1)
  52.                 {
  53.                   if(key3==0)
  54.                         {
  55.                           delay_n10us(1000);
  56.                                 if(key3==0)
  57.                                 {
  58.                                   wenduCB++;
  59.                                 }
  60.                         }
  61.                   if(key4==0)
  62.                         {
  63.                           delay_n10us(1000);
  64.                                 if(key4==0)
  65.                                 {
  66.                                   wenduCB--;
  67.                                 }
  68.                         }
  69.                 }
  70.                 if(shidumode==1)
  71.                 {
  72.                   if(key3==0)
  73.                         {
  74.                           delay_n10us(1000);
  75.                                 if(key3==0)
  76.                                 {
  77.                                   shiduCB++;
  78.                                 }
  79.                         }
  80.                   if(key4==0)
  81.                         {
  82.                           delay_n10us(1000);
  83.                                 if(key4==0)
  84.                                 {
  85.                                   shiduCB--;
  86.                                 }
  87.                         }
  88.                 }
  89.                 if(wendu>=wenduCB*10)
  90.                   {
  91.                                      beep = 1;
  92.                    }
  93.                 if(shidu>=shiduCB*10)
  94.                   {
  95.                                      beep = 1;
  96.                    }
  97.                 if(wendu<wenduCB*10&&shidu<shiduCB*10)
  98.                 {
  99.                  beep = 0;
  100.                 }
  101. }

  102. void LCD_init(void)
  103. {  
  104.         delay_n10us(10);  
  105.         LCD_write_command(0x38);//设置8位格式,2行,5x7
  106.         delay_n10us(10);  LCD_write_command(0x0c);//开显示,关光标,不闪烁
  107.         delay_n10us(10);  LCD_write_command(0x06);//设定输入方式,增量不移位
  108.         delay_n10us(10);  LCD_write_command(0x01);//清除屏幕显示  
  109.         delay_n10us(100);       //延时清屏,延时函数,延时约n个10us
  110. }

  111. void LCD_write_command(uchar dat)
  112. {  
  113.         delay_n10us(10);  
  114.         LCD_RS=0;         //指令
  115.         LCD_RW=0;         //写入
  116.         LCD_E=1;          //允许
  117.         LCD_DB=dat;  delay_n10us(10);  //实践证明,我的LCD1602上,用for循环1次就能完成普通写指令。
  118.         LCD_E=0;  delay_n10us(10);  //实践证明,我的LCD1602上,用for循环1次就能完成普通写指令。
  119. }

  120. void LCD_write_data(uchar dat)
  121. {  
  122.         delay_n10us(10);  
  123.         LCD_RS=1;          //数据
  124.         LCD_RW=0;                   //写入
  125.         LCD_E=1;           //允许
  126.         LCD_DB=dat; delay_n10us(10);
  127.          LCD_E=0;  delay_n10us(10);
  128. }

  129. void LCD_disp_char(uchar x,uchar y,uchar dat)
  130. {   
  131.         uchar address;   
  132.         if(y==1)           
  133.         address=0x80+x;  
  134.         else           
  135.         address=0xc0+x;   
  136.         LCD_write_command(address);   
  137.         LCD_write_data(dat);
  138. }

  139. void LCD_disp_str(uchar x,uchar y,uchar *str)
  140. {   
  141.         uchar address;   
  142.         if(y==1)           
  143.         address=0x80+x;   
  144.         else           
  145.         address=0xc0+x;   
  146.         LCD_write_command(address);   
  147.         while(*str!='\0')   
  148.                 {      
  149.                 LCD_write_data(*str);
  150.                 str++;
  151.                 }
  152. }

  153. void delay_n10us(uint n)  //延时n个10us@12M晶振
  154. {                 
  155.         uint i;                    
  156.         for(i=n;i>0;i--)            
  157.          {         
  158.          nop_();_nop_();_nop_();_nop_();_nop_();_nop_();   
  159.          }
  160. }

  161. sbit SCK  = P2^6;      //定义通讯时钟端口
  162. sbit DATA = P2^7;      //定义通讯数据端口   
  163. typedef union   
  164. { unsigned int i;      //定义了两个共用体   
  165.   float f;  } value;   
  166.   enum {TEMP,HUMI};      //TEMP=0,HUMI=1

  167. #define noACK 0             //用于判断是否结束通讯
  168. #define ACK   1             //结束数据传输                              //adr  command  r/w  
  169. #define STATUS_REG_W 0x06   //000   0011    0  
  170. #define STATUS_REG_R 0x07   //000   0011    1  
  171. #define MEASURE_TEMP 0x03   //000   0001    1  
  172. #define MEASURE_HUMI 0x05   //000   0010    1  
  173. #define RESET        0x1e   //000   1111    0  
  174. /****************定义函数****************/  
  175. void s_transstart(void);               //启动传输函数
  176. void s_connectionreset(void);          //连接复位函数
  177. char s_write_byte(unsigned char value);//DHT90写函数
  178. char s_read_byte(unsigned char ack);   //DHT90读函数  
  179. char s_measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode);//测量
  180. void calc_dht90(float *p_humidity ,float *p_temperature);//温湿度补偿

  181. void s_transstart(void)   // generates a transmission start   
  182. {        
  183.         DATA=1; SCK=0;                   //Initial state   
  184.         _nop_();     
  185.         SCK=1;     
  186.         _nop_();     
  187.         DATA=0;     
  188.         _nop_();     
  189.         SCK=0;        
  190.         _nop_();_nop_();_nop_();     
  191.         SCK=1;     
  192.         _nop_();      
  193.         DATA=1;           
  194.          _nop_();      
  195.          SCK=0;        
  196. }

  197. void s_connectionreset(void)   // communication reset: DATA-line=1 and at least 9 SCK cycles followed by transstart  
  198. {      
  199.         unsigned char i;      
  200.         DATA=1;
  201.         SCK=0;                    //Initial state   
  202.         for(i=0;i<9;i++)                  //9 SCK cycles   
  203.         {      
  204.         SCK=1;     
  205.         SCK=0;   
  206.         }     
  207.         s_transstart();                   //transmission start
  208. }

  209. char s_write_byte(unsigned char value)   
  210. //----------------------------------------------------------------------------------  
  211. // writes a byte on the Sensibus and checks the acknowledge   
  212. {      
  213.         unsigned char i,error=0;      
  214.         for (i=0x80;i>0;i/=2)             //shift bit for masking   
  215.         {        
  216.         if (i & value) DATA=1;          //masking value with i , write to SENSI-BUS      
  217.         else DATA=0;                              
  218.         SCK=1;                          //clk for SENSI-BUS      
  219.         _nop_();_nop_();_nop_();        //pulswith approx. 3 us         
  220.         SCK=0;   
  221.         }     
  222.         DATA=1;                           //release DATA-line   
  223.         SCK=1;                            //clk #9 for ack      
  224.         error=DATA;                       //check ack (DATA will be pulled down by DHT90),DATA在第9个上升沿将被DHT90自动下拉为低电平。   
  225.         _nop_();_nop_();_nop_();   
  226.         SCK=0;   
  227.         DATA=1;                           //release DATA-line     
  228.         return error;                     //error=1 in case of no acknowledge //返回:0成功,1失败
  229. }

  230. char s_read_byte(unsigned char ack)    // reads a byte form the Sensibus and gives an acknowledge in case of "ack=1"   
  231. {      
  232.         unsigned char i,val=0;     
  233.         DATA=1;                           //release DATA-line   
  234.         for (i=0x80;i>0;i/=2)             //shift bit for masking
  235.         {
  236.         SCK=1;                          //clk for SENSI-BUS      
  237.         if (DATA) val=(val | i);        //read bit      
  238.         _nop_();_nop_();_nop_();        //pulswith approx. 3 us     
  239.         SCK=0;                 
  240.         }     
  241.         if(ack==1)
  242.         DATA=0;                 //in case of "ack==1" pull down DATA-Line   
  243.         else DATA=1;                      //如果是校验(ack==0),读取完后结束通讯   
  244.         _nop_();_nop_();_nop_();          //pulswith approx. 3 us   
  245.         SCK=1;                            //clk #9 for ack   
  246.         _nop_();_nop_();_nop_();          //pulswith approx. 3 us     
  247.         SCK=0;                     
  248.         _nop_();_nop_();_nop_();          //pulswith approx. 3 us   
  249.         DATA=1;                           //release DATA-line   
  250.         return val;  
  251. }

  252. char s_measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode)  // makes a measurement (humidity/temperature) with checksum  
  253. {      
  254.         unsigned error=0;   
  255.         unsigned int i;      
  256.         s_transstart();                   //transmission start     
  257.         switch(mode){                     //send command to sensor      
  258.         case TEMP  : error+=s_write_byte(MEASURE_TEMP); break;     
  259.         case HUMI  : error+=s_write_byte(MEASURE_HUMI); break;      default     : break;      
  260.         }     
  261.         for (i=0;i<65535;i++)
  262.         if(DATA==0) break; //wait until sensor has finished the measurement   
  263.         if(DATA) error+=1;                // or timeout (~2 sec.) is reached   
  264.         *(p_value)  =s_read_byte(ACK);    //read the first byte (MSB)   
  265.         *(p_value+1)=s_read_byte(ACK);    //read the second byte (LSB)   
  266.         *p_checksum =s_read_byte(noACK);  //read checksum   
  267.         return error;  
  268. }

  269. void calc_dht90(float *p_humidity ,float *p_temperature)
  270. // calculates temperature [C] and humidity [%RH]  
  271. // input :  humi [Ticks] (12 bit)  
  272. //          temp [Ticks] (14 bit)
  273. // output:  humi [%RH]
  274. //          temp [C]  
  275. { const float C1=-4.0;              // for 12 Bit   
  276. const float C2=+0.0405;           // for 12 Bit   
  277. const float C3=-0.0000028;        // for 12 Bit   
  278. const float T1=+0.01;             // for 14 Bit @ 5V   
  279. const float T2=+0.00008;           // for 14 Bit @ 5V     
  280. float rh=*p_humidity;             // rh:      Humidity [Ticks] 12 Bit   
  281. float t=*p_temperature;           // t:       Temperature [Ticks] 14 Bit   
  282. float rh_lin;                     // rh_lin:  Humidity linear   
  283. float rh_true;                    // rh_true: Temperature compensated humidity   
  284. float t_C;                        // t_C   :  Temperature [C]     
  285. t_C=t*0.01 - 40;                  //calc. temperature from ticks to [C]   
  286. rh_lin=C3*rh*rh + C2*rh + C1;     //calc. humidity from ticks to [%RH]   
  287. rh_true=(t_C-25)*(T1+T2*rh)+rh_lin;   //calc. temperature compensated humidity [%RH]   
  288. if(rh_true>100)rh_true=100;       //cut if the value is outside of   
  289. if(rh_true<0.1)rh_true=0.1;       //the physical possible range     
  290. *p_temperature=t_C;               //return temperature [C]   
  291. *p_humidity=rh_true;              //return humidity[%RH]
  292. }

  293. //*********主函数*****************
  294. void main(void)
  295. {   
  296.         value humi_val,temp_val;         
  297.         unsigned char error,checksum;            
  298.         LCD_init();           
  299.         s_connectionreset();  
  300.   beep = 0;
  301.         LCD_disp_str(0,1,"TE       CB:");   
  302.         LCD_disp_str(0,2,"RH       CB:");  
  303. ……………………

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

所有资料51hei提供下载:
温湿度仿真.zip (111.44 KB, 下载次数: 201)





评分

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

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏4 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:225105 发表于 2018-3-8 01:20 | 只看该作者

很不错啊,下载学习学习
回复

使用道具 举报

板凳
ID:329860 发表于 2018-6-8 22:22 | 只看该作者
很好,写论文用上了。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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