找回密码
 立即注册

QQ登录

只需一步,快速开始

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

SHT11温湿度传感器仿真和代码

  [复制链接]
跳转到指定楼层
楼主
基于SHT11的温湿度传感器的仿真,有需要的下载


单片机源代码:
  1. #include <reg52.h>  //头文件
  2. #include <intrins.h>
  3. #include <stdio.h> //
  4. #include <math.h>    //Keil library  

  5. //**************************************
  6. sbit DATA =P1^1;//数据
  7. sbit SCK=P1^0;//时钟
  8. #define TEMP_ML 0x03   //000   0001    1 温度命令
  9. #define HUMI_ML 0x05   //000   0010    1 温度命令
  10. unsigned char error  ;//全局错误变量
  11. unsigned char ack  ;//全局应答变量
  12. //float temp_zi  ;//全局应答变量
  13. //float humi_zi  ;//全局应答变量
  14. unsigned char temp_h  ;//全局应答变量
  15. unsigned char temp_LL  ;//全局应答变量

  16. #define uchar unsigned char //定义一下方便使用
  17. #define uint  unsigned int
  18. #define ulong unsigned long
  19.         unsigned  int  recs=0;//接收次数


  20. const unsigned char  X_WD[11]="当前温度:+-";
  21. const unsigned char  X_SD[10]="当前湿度:";
  22. const unsigned char  S_WD[11]="报警温度:+-";
  23. const unsigned char  S_SD[10]="报警湿度:";
  24. const unsigned char  SHUO[15]="0123456789.%RH";
  25. const unsigned char  DU_ZHI[6]="℃  ";

  26.    int  xts_zi=0 ;//温度值
  27.    int  xtg_zi=0 ;//温度个位值
  28.    int  xtd_zi=0 ;//温度点值

  29.    int  xss_zi=0 ;//湿度值
  30.    int  xsg_zi=0 ;//湿度个位值
  31.    int  xsd_zi=0 ;//湿度点值

  32.    int  sts_zi=6 ;//温度值
  33.    int  stg_zi=0 ;//温度个位值
  34.    int  std_zi=0 ;//温度点值

  35.    int  sss_zi=9 ;//湿度值
  36.    int  ssg_zi=0 ;//湿度个位值
  37.    int  ssd_zi=0 ;//湿度点值

  38.    int  szf=1   ;//设正负
  39.    int  xzf=1   ;//显正负



  40. //**************************************
  41. sbit E_CLK =P0^7;//起始信号
  42. sbit RW_SID=P0^6;//H:读 L:写
  43. sbit RS_CS =P0^5;// H:数据 L:命令
  44. sbit soud =P0^0;// 声音

  45. //*******************************基本驱动程


  46. void busyaaa_check(void)
  47. {
  48.     uchar keyx;
  49.         P2=0XFF;

  50.         while(1)
  51.         {
  52.                 RS_CS=0;//命令
  53.                 RW_SID=1;//读
  54.                 E_CLK=1;
  55.                 keyx=P2;
  56.                 E_CLK=0;
  57.         if((keyx&0X80)==0X00)
  58.         break;
  59.                 }
  60.   }


  61. void wcom(unsigned char com)//并口写命令
  62.       {
  63.     busyaaa_check();//忙检测
  64.         RS_CS=0; //以命令方式
  65.         RW_SID=0;//写
  66.         E_CLK=1;//使能信号开始
  67.         //nop();
  68.         P2=com;//送出数据
  69.         //_nop_();
  70.         E_CLK=0;//不使能
  71.       }


  72. void wdata(unsigned char dat)//并口写数据
  73.         {
  74.         busyaaa_check();//忙检测
  75.         RS_CS=1;//以数据方式
  76.         RW_SID=0;//写
  77.         E_CLK=1;//使能
  78. //        nop();
  79.         P2=dat;//写入数据
  80. //        nop();//延时
  81.         E_CLK=0;//不使能
  82.         }


  83. //

  84. //**************************系统初始化
  85. //**************************
  86. void initlcd_char(void)
  87. {
  88.         wcom(0x30);//基本指令
  89.         wcom(0x0C);//0000,1100 游标显示关 整体显示开
  90.         // wcom(0x01);//0000,0001 清除显示RAM
  91.         wcom(0x02);//0000,0010 显示RAM 地址归位
  92.         wcom(0x80);//1000,0000 设定显示RAM 地址到地址计数器
  93.         wcom(0x06);//0000 0110 右移位
  94.         wcom(0x0c);//0000 1100开显示
  95. }


  96. //****清屏******************
  97. void clear(void)
  98.         {
  99.                 wcom(0x30);//基本指令
  100.                 wcom(0x01);//清屏
  101.         }

  102. //****************************调用字库显示汉字
  103. //***************************************
  104. //printf 函数用到的函数。要在STDIO.H 中将原有的PUTCHAR 函数屏蔽。
  105. //写汉字要在基本指令集下进行。
  106. void putchara(unsigned char cc)
  107. {
  108.         switch(cc)
  109.         {
  110.                 case 'c' : //clear
  111.                 wcom(0x01);
  112.                 break ;
  113.                 case 'f' : //first line
  114.                 wcom(0x80);
  115.                 break ;
  116.                 case 's' : //second line
  117.                 wcom(0x90);
  118.                 break ;
  119.                 case 't' : //third line
  120.                 wcom(0x88);
  121.                 break ;
  122.                 case 'd' : //fourth line
  123.                 wcom(0x98);

  124.                 break ;
  125.                 default :
  126.                 wdata(cc); //data
  127.                 break;
  128.         }
  129. }

  130. //--显示字---
  131. xian_zhi_t()
  132. {
  133.    int i;


  134.    for (i=0;i<9;i++)
  135.       wdata(X_WD[i]);

  136.           if(xzf==1)
  137.            wdata(X_WD[9]);
  138.           else
  139.            wdata(X_WD[10]);
  140.       

  141.       wdata(SHUO[xts_zi]);//十位
  142.       wdata(SHUO[xtg_zi]);//个位
  143.       wdata(SHUO[10]);//点
  144.           wdata(SHUO[xtd_zi]);//点值

  145.    for (i=0;i<2;i++)
  146.      wdata(DU_ZHI[i]);
  147. }
  148. /////////////////
  149. xian_zhi_s()
  150. {
  151.    int i;
  152.    for (i=0;i<9;i++)
  153.       wdata(X_SD[i]);

  154.       wdata(SHUO[xss_zi]);//十位
  155.       wdata(SHUO[xsg_zi]);//个位
  156.       wdata(SHUO[10]);//点
  157.           wdata(SHUO[xsd_zi]);//点值

  158.    for (i=11;i<14;i++)  //RH
  159.      wdata(SHUO[i]);
  160. }

  161. //--设定---
  162. set_zhi_t()
  163. {
  164.    int i;
  165.    for (i=0;i<9;i++)
  166.       wdata(S_WD[i]);


  167.           if(szf==1)
  168.            wdata(S_WD[9]);
  169.           else
  170.            wdata(S_WD[10]);

  171.       wdata(SHUO[sts_zi]);//十位
  172.       wdata(SHUO[stg_zi]);//个位
  173.       wdata(SHUO[10]);//点
  174.           wdata(SHUO[std_zi]);//点值

  175.    for (i=0;i<2;i++)
  176.      wdata(DU_ZHI[i]);
  177. }

  178. //////////////
  179. set_zhi_s()
  180. {
  181.    int i;
  182.    for (i=0;i<9;i++)
  183.       wdata(S_SD[i]);

  184.       wdata(SHUO[sss_zi]);//十位
  185.       wdata(SHUO[ssg_zi]);//个位
  186.       wdata(SHUO[10]);//点
  187.           wdata(SHUO[ssd_zi]);//点值

  188.    for (i=11;i<14;i++)  //RH
  189.      wdata(SHUO[i]);
  190. }










  191. /////////////////
  192. //////////////////////


  193. char read() //读一个字节 返回应答信号
  194. //----------------------------------------------------------------------------------
  195. // reads a byte form the Sensibus and gives an acknowledge in case of "ack=1"
  196. {
  197.   unsigned char i,val=0;
  198.   temp_LL=0;
  199.   temp_h=0;
  200.   DATA=1;                           //释放数据总线
  201.   for (i=0x80;i>0;i/=2)             //位移8位
  202.   { SCK=1;                          //上升沿读入
  203.     if (DATA) val=(val | i);        //确定值  
  204.     SCK=0;                                           
  205.   }
  206.    DATA=0;                        //读应答信号,有应答为1,为应答为0 通过CPU下拉为应答
  207.   SCK=1;                            //第9个脉冲
  208.    _nop_(); _nop_(); _nop_();          //pulswith approx. 5 us
  209.   SCK=0;                                                    
  210.   DATA=1;                           //释放数据总线
  211.   temp_h=val;
  212.   val=0;

  213. ////低8位/////////////////////////////

  214.     DATA=1;                           //释放数据总线
  215.   for (i=0x80;i>0;i/=2)             //位移8位
  216.   { SCK=1;                          //上升沿读入
  217.     if (DATA) val=(val | i);        //确定值  
  218.     SCK=0;                                           
  219.   }
  220.    DATA=1;//0;                        //不需要应答 通过CPU下拉为应答
  221.   SCK=1;                            //第9个脉冲
  222.    _nop_(); _nop_(); _nop_();          //pulswith approx. 5 us
  223.   SCK=0;                                                    
  224.   DATA=1;                           //释放数据总线
  225.   temp_LL=val;

  226. }
  227. ////////////






  228.   char write(unsigned char value) //写一个字节 返回应答信号
  229. //---------------------------------------------------------
  230. {
  231.   unsigned char i ;
  232.    ack=0;  
  233.   for (i=0x80;i>0;i/=2)             //释放数据总线
  234.   { if (i & value) DATA=1;          //写入值
  235.     else DATA=0;                        
  236.     SCK=1;                          //上升沿写入
  237.      _nop_(); _nop_(); _nop_();        //延时       
  238.     SCK=0;
  239.   }
  240.   DATA=1;                           //释放数据总线
  241.   SCK=1;                            //第9个脉冲
  242.   if  (DATA==1) ack=1;
  243.                          //读应答信号
  244.   SCK=0;        
  245.   return ack;                     //error=1 表示没有应答
  246. }
  247. ////////

  248. void start(void)  //启动
  249. //--------------------------------------------------------
  250. {  
  251.    DATA=1; SCK=0;                   //数据为1,SCK=0
  252.     _nop_();
  253.    SCK=1;                          //第一个脉冲
  254.     _nop_();
  255.    DATA=0;                         //数据跌落
  256.     _nop_ ();
  257.    SCK=0;                         //完成一个脉冲
  258.     _nop_(); _nop_(); _nop_();
  259.    SCK=1;                         //再一个脉冲
  260.     _nop_();
  261.    DATA=1;                        //数据变为1                  
  262.     _nop_();
  263.    SCK=0;                         //完成该脉冲                  
  264. }


  265. //////////////////////////////////
  266. void sht_rest(void)  //复位
  267.    
  268. {  
  269.   unsigned char i;
  270.   DATA=1; SCK=0;                    //数据为1 时钟为0
  271.   for(i=0;i<9;i++)                  //9 个脉冲为 复位
  272.   { SCK=1;
  273.     SCK=0;
  274.   }
  275.   start();                   //启动
  276. }

  277. ////////////////////////////////

  278. ///////

  279.                           //测量温度或者是温度,返回校验值
  280.   text_a(unsigned char ml)
  281.         {
  282.                  unsigned int i;

  283.                  start();                   //启动
  284.                  write(ml);//写入测温度
  285.                  if (ack==1)
  286.                     {
  287.                             sht_rest() ;//复位
  288.                            write(ml);//写入测温度
  289.              }
  290.       
  291.           //判断是否处于忙

  292.         //         DATA=1;//释放数据总线
  293.       for (i=0;i<65535;i++) if(DATA==0) break;


  294.                  read();//读温度


  295.   }


  296. ///////

  297.     text_jishuan_temp11()
  298.         {
  299.            error=0;
  300.            ack=0;
  301.        sht_rest() ;//复位
  302.            text_a(TEMP_ML);
  303.          text_jishuan_temp();
  304.             text_a(HUMI_ML);
  305.          text_jishuan_humi();


  306.           }

  307. /////

  308. //////////////
  309. text_jishuan_temp()
  310. {
  311.     float aa=0,bb=0,temp_zi;
  312.         int   abcd=0;

  313. aa=(float)temp_h*256+(float)temp_LL;
  314. temp_zi=0.01*aa-40;

  315. //
  316. xzf=1;
  317. if  (temp_zi<0)
  318.     { xzf=0;
  319.           temp_zi=-temp_zi ;
  320.           }

  321.     temp_zi=temp_zi*10;
  322.    abcd=(int)temp_zi;
  323. xts_zi=abcd/100;
  324. abcd=abcd%100;
  325. xtg_zi=abcd/10;
  326. abcd=abcd%10;
  327. xtd_zi=abcd/1;


  328.    }
  329.   /////////////
  330.   text_jishuan_humi()
  331. {
  332.     float aa=0,bb=0,humi_zi;
  333.         int   abcd=0;

  334. aa=(float)temp_h*256+(float)temp_LL;

  335. bb=aa*aa*2.8/1000000;
  336. aa=0.0405*aa;
  337. aa=aa-4-bb;
  338. humi_zi=aa;

  339. //
  340.     humi_zi=humi_zi*10;
  341.    abcd=(int)humi_zi;
  342.    xss_zi=abcd/100;
  343.    abcd=abcd%100;
  344.    xsg_zi=abcd/10;
  345.    abcd=abcd%10;
  346.    xsd_zi=abcd/1;



  347.    }





  348. ////

  349. //-----显示---
  350. xianshi()
  351. {

  352.     putchara('f');//在第一行显示
  353.     xian_zhi_t();
  354.        
  355.     putchara('s');//在第二行显示
  356.     xian_zhi_s();

  357.     putchara('t');//在第三行显示
  358.     set_zhi_t();
  359.        
  360.     putchara('d');//在第四行显示
  361.     set_zhi_s();


  362. }


  363. /////////////////////////////////
  364. ///////////////////////////////////////////
  365. ///////////////////////////////////////////
  366. ////接收给值/////
  367. void rece(int cc)
  368. {
  369.         switch(cc)
  370.         {
  371.                 case 1 : //clear
  372.         {        if (SBUF==0XCC)  break;
  373.             else
  374.                 {recs=0; //判断头对不对
  375.                 break;
  376.                 }
  377.           }
  378.                 case 2 : //clear
  379.                 szf=(int) SBUF;               
  380.                 break;

  381.                 case 3 : //clear
  382.                 sts_zi=(int) SBUF;               
  383.                 break;               

  384.                 case 4 : //clear
  385.                 stg_zi=(int) SBUF;               
  386.                 break;

  387.                    case 5 : //clear
  388.                 std_zi=(int) SBUF;               
  389.                 break;


  390.                 case 6 : //clear
  391.             {        if (SBUF==0xdd)  break;
  392.             else
  393.         {recs=recs-6;
  394.                 break;
  395.                 }
  396.           }
  397.               case 7 : //clear
  398.                 sss_zi=(int) SBUF;               
  399.                 break;

  400.               case 8 : //clear
  401.                 ssg_zi=(int) SBUF;               
  402.                 break;

  403.               case 9 : //clear
  404.                 ssd_zi=(int) SBUF;               
  405.                 break;

  406.    }

  407.   }

  408.   ///////////////////////////////
  409.   void text_232_main()
  410.         {



  411.                 TI=0;          //清发送完标志
  412.                 SBUF=0xaa;                 //AA头码
  413.                 while(!TI);         //等发送完
  414.                 TI=0;
  415.                 SBUF=(char) xzf ;//发送正负
  416.                 while(!TI);         //等发送完
  417.                 TI=0;
  418.                 SBUF=(char) xts_zi ;//发送正负
  419.                 while(!TI);         //等发送完
  420.                 TI=0;
  421.                 SBUF=(char) xtg_zi ;//发送正负
  422.                 while(!TI);         //等发送完
  423.                 TI=0;
  424.                 SBUF=(char) xtd_zi ;//发送正负
  425.                 while(!TI);         //等发送完
  426.                 TI=0;
  427.                 SBUF=0xbb ;//发送正负
  428.                 while(!TI);         //等发送完
  429.                 TI=0;
  430.                 SBUF=(char) xss_zi ;//发送正负
  431.                 while(!TI);         //等发送完
  432.                 TI=0;
  433.                 SBUF=(char) xsg_zi ;//发送正负
  434.                 while(!TI);         //等发送完
  435.                 TI=0;
  436.                 SBUF=(char) xsd_zi ;//发送正负
  437.                 while(!TI);         //等发送完
  438.                 TI=0;

  439.         }

  440. ///////////////

  441.   void intrr() interrupt 4 //接收和发送中断
  442. {
  443.         char temp;
  444.          if(RI)
  445.          {
  446.                 RI=0;
  447.             recs++;
  448.                 rece(recs);        //接收给值
  449.                 while(recs==9) recs=0;
  450.        

  451.                 temp=SBUF;
  452.                 P2=temp;

  453.          }
  454.          if(TI)
  455.          {
  456.          P0=SBUF  ;
  457.          }
  458. }


  459. //初始化串行口
  460. void csh()
  461.         {

  462.         SCON=0X50; //允许接收  工作方式1
  463.     TI=0;          //清发送完成标志
  464.         RI=0;        //清接收完成标志
  465.         PCON=0;          //波特率不加倍
  466.         TH1=0xFD;          //初始波特率的值
  467.         TL1=0XFD;
  468.         TMOD=0X20;         //定时1工作方式1,自动装载定时器值
  469.         EA=1;                                  //允许总中断
  470.         ET1=0;                          //不允许定时器0中断
  471.         ES=1;                 //允许串口中断
  472.         TR1=1;                  //启动TM1
  473.         }



  474.   /////////////////////////////////
  475.   //////////
  476.    text_baojing()//报警
  477.    {
  478.      int  temp1=0,temp2=0;

  479.                  temp1=xss_zi*100+xsg_zi*10+xsd_zi;
  480.                  temp2=sss_zi*100+ssg_zi*10+ssd_zi;            
  481.         while ((temp1-temp2)>0)
  482.                 { speek_cl();
  483.                   break;
  484.                   }


  485.             while (xzf>szf) //当显示为正,设定为负,立即报
  486.                    { speek_cl();
  487.                   break;
  488.                  }

  489.                  temp1=xts_zi*100+xtg_zi*10+xtd_zi;
  490.                  temp2=sts_zi*100+stg_zi*10+std_zi;
  491.                 if ((xzf>0)&&(szf>0)) //如果显示大于0,设定也大于0
  492.               {
  493.                           while ((temp1-temp2)>0)
  494.                             {
  495.                                   speek_cl();
  496.                                   break;
  497.                                  }
  498.                    }
  499.         else         
  500.                    {
  501.                         
  502.                                           while ((temp2-temp1)>0)
  503.                                             {
  504.                                                   speek_cl();
  505.                                                   break;
  506.                                              }
  507.                         }


  508. }

  509. ////////
  510. ///////////////////////////////
  511. /////////////////////////////////
  512. speek_cl()
  513.    {
  514.      int  i=0,j=0;

  515.          for(i=0;i<500;i++)
  516.          { soud=!soud ;
  517.            for(j=0;j<30;j++);
  518.           }
  519.         }

  520. ///////////////////////
  521. main()
  522. {




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

复制代码

下载:
SHT11温湿度传感器仿真.rar (76.65 KB, 下载次数: 148)


评分

参与人数 1黑币 +3 收起 理由
崩坏的人 + 3 很给力!

查看全部评分

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

使用道具 举报

沙发
ID:201367 发表于 2017-5-16 15:02 | 只看该作者
楼主好样的!!!
回复

使用道具 举报

板凳
ID:212839 发表于 2017-6-22 17:14 来自手机 | 只看该作者
楼主有电路分析论文吗?
回复

使用道具 举报

地板
ID:510898 发表于 2019-4-12 23:49 | 只看该作者
谢谢楼主分享!
回复

使用道具 举报

5#
ID:551579 发表于 2019-5-31 03:37 | 只看该作者
怎么都是半截的 啊
回复

使用道具 举报

6#
ID:581183 发表于 2019-11-18 12:43 | 只看该作者
楼主有电路图的解释吗
回复

使用道具 举报

7#
ID:581183 发表于 2019-11-21 15:55 | 只看该作者
有没有电路分析的文档啊
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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