找回密码
 立即注册

QQ登录

只需一步,快速开始

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

sht71温湿度控制系统(单片机程序源码,proteus仿真)

[复制链接]
跳转到指定楼层
楼主
这是我做的温湿度控制系统资料。采用sht71温湿度传感器作为检测元件。

包含proteus仿真资料。
源代码。



程序如下:
  1. /*注意:子函数多层调用时,要记住:写子函数以及子函数声明用形参;而调用子函数用实参*/
  2. /*头文件*/
  3. #include<reg52.h>
  4. #include<intrins.h>
  5. #include<math.h>
  6. #include<hc595.h>
  7. #include<delay.h>
  8. #include<actuator.h>
  9. #include<ini.h>
  10. #include<sht71.h>

  11. /*全局变量定义 */                                       
  12. uchar code duan[21]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,                    
  13.                                          0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef,
  14.                                          0x40};        //CC码表:数字0~9  带小数点数字0~9   负号
  15. uchar code wei[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//从LED0-7
  16. uchar high8=0,low8=0;//传感器16位数据高低8位
  17. uchar temphigh8=0,templow8=0;//温度高低8位
  18. uchar humihigh8=0,humilow8=0;//湿度高低8位
  19. long SO_RH=0;//湿度10进制数据
  20. long SO_T=0;//温度10进制数据
  21. char temp;        //实际温度值,温度分正负
  22. char temp_2;//因为湿度值计算时会用到温度值,防止对temp数学处理过程引起的值变化影响湿度的计算,故将temp赋给temp_2保存以用于湿度计算
  23. char humi_relative;//相对湿度值,湿度只有正值
  24. char humi;        //实际湿度值

  25. uchar a1,b1,c1,d1;//正负位、十位、个位、小数位
  26. uchar a2,b2,c2,d2;//正负位、十位、个位、小数位
  27. uchar error_command;//通讯检查信号 0正常 1错误
  28. uchar temp_max,temp_min;//温度上下极限值
  29. uchar p[16];

  30. /**********************温湿度测量子函数***********************/
  31. void sht_measurement(uchar measure)
  32. {
  33.   measurement_start();
  34.   command_send(measure);
  35.   measurement_wait();
  36.   mcu_receive_date();
  37. }
  38. /************************启动测量子函数***********************/
  39. void measurement_start()
  40. {
  41.    SCK=0;//赋予时钟线初始电平
  42.    DATE=1;//赋予数据线初始电平
  43.    
  44.    SCK=1;
  45.    _nop_();
  46.    _nop_();
  47.    DATE=0;
  48.    _nop_();
  49.    _nop_();
  50.    SCK=0;

  51.    _nop_();
  52.    _nop_();//时钟线低电平保持

  53.    SCK=1;
  54.    _nop_();
  55.    _nop_();
  56.    DATE=1;
  57.    _nop_();
  58.    _nop_();
  59.    SCK=0;
  60. }
  61. /*********************发送测量命令子函数*********************/
  62. char command_send(uchar command)           //写时序:上升沿-高电平保持-下降沿
  63. {                                                                           //注意:要先给DATE,再给写时序(SCK)
  64.   uchar value=0x80,i=0;         
  65.   SCK=0;//写时序初始低电平
  66.   for(i=0;i<8;i++)
  67.   {      
  68.         if(command&value)
  69.           DATE=1;
  70.         else DATE=0;
  71.         SCK=1;
  72.         _nop_();
  73.         SCK=0;        
  74.         value=value>>1;
  75.   }
  76.   SCK=1;
  77.   if(DATE==0)
  78.     error_command=0;
  79.   SCK=0;                                //第9脉冲,即ACK脉冲,同时也是一个读脉冲

  80.   if(error_command==1)
  81.     sht_reset();//如果通讯错误,则传感器软件复位  
  82.          
  83.   return error_command;  //error=1通讯错误
  84. }
  85. /***********************测量等待子函数*********************/
  86. void measurement_wait()
  87. {
  88.   delay(40000);//测量等待390ms(20/80/320ms对应8、12、14位)
  89. }
  90. /***********************读数据子函数**********************/
  91. void mcu_receive_date()
  92. {
  93.   high8=mcu_receive_byte();        
  94.   
  95.   DATE=0;//写时序:上升沿-高电平保持-下降沿                  
  96.   SCK=1;_nop_();_nop_();
  97.   SCK=0;_nop_();_nop_();//接收完高字节数据后,手动拉低数据线(写0),表示接收结束
  98.   DATE=1;         
  99.       
  100.   low8=mcu_receive_byte();

  101.   DATE=1;//写时序:上升沿-高电平保持-下降沿                  
  102.   SCK=1;_nop_();_nop_();
  103.   SCK=0;_nop_();_nop_();//接收完高字节校数据后,手动拉高数据线,传感器不经校验,直接休眠
  104. }
  105. /***********************读字节子函数***********************/
  106. uchar mcu_receive_byte()
  107. {
  108.   uchar value=0x80,dat=0,i=0;
  109.   SCK=0;//读时序初始低电平
  110.   for(i=0;i<8;i++)        //读时序:低电平保持-上升沿-高电平保持
  111.   {         
  112.     SCK=1;_nop_();              
  113.         if(DATE)
  114.           dat=dat|value;
  115.         SCK=0;_nop_();         
  116.         value=value>>1;        
  117.   }
  118.   return dat;
  119. }
  120. /******************取实际温度子函数********************/
  121. void temperature_calculate()
  122. {
  123.   float d1_5V=-40.1;//定义温度计算公式参数
  124.   float d2_14bit=0.01;//定义温度计算公式参数
  125.   temphigh8=high8;
  126.   templow8=low8;

  127.   SO_T=temphigh8;//先赋值给低8位
  128.   SO_T=((SO_T<<8)&0xff00)|templow8;//将两个8位合成一个16位。与0xff00与运算,目的在于清低八位,避免不稳定错误
  129.   SO_T=SO_T&0x3fff;//sht温度精度默认为最高14位,即temp16的高2位为0,这里人为将高2位清零,避免不稳定错误。0011 1111 1111 1111=0x3fff
  130.   temp=d1_5V+d2_14bit*SO_T;

  131.   compensation_temp();//正温度修正

  132.   temp_2=temp;        
  133. }
  134. /******************分离温度值子函数********************/
  135. void temperature_seperate()
  136. {
  137.   uchar i=0;//正负数标志位
  138.   i=0x80&temp;//取符号位,判断正负
  139.   if(i)
  140.   {
  141.     temp=temp-1; //由补码取原码
  142.         temp=~temp;

  143.         a1=20;
  144.         b1=(temp*10)/100;
  145.     c1=((temp*10)%100)/10;
  146.     d1=((temp*10)%100)%10;

  147.         temp=~temp;        //还原补码,防止下次显示将负数扫描成正数
  148.         temp=temp+1;

  149.         /*负温度范围补偿代码  统一上浮1度,使得精度保证在+-1度以内
  150.          -12度以内,显示误差为0;-12以下,显示误差为-1度*/
  151.         if(c1==9)
  152.         {
  153.           c1=0;
  154.           b1+=1;
  155.         }
  156.         else
  157.         {
  158.           c1+=1;
  159.         }
  160.         c1+=10;        //+10表示附带小数点
  161.         p[0]=a1;
  162.         p[1]=b1;
  163.         p[2]=c1;
  164.         p[3]=d1;
  165.   }
  166.   else
  167.   {
  168.     a1=0;
  169.     b1=(temp*10)/100;
  170.     c1=((temp*10)%100)/10;
  171.     d1=((temp*10)%100)%10;        

  172.         c1+=10;        //+10表示附带小数点
  173.         p[0]=a1;
  174.         p[1]=b1;
  175.         p[2]=c1;
  176.         p[3]=d1;
  177.   }
  178. }
  179. /*****************温度极限值分离子函数*********************/
  180. void temperature_limit_seperate()
  181. {
  182.         uchar min1,min2,max1,max2;//温度下限十位、温度下限个位、温度上限十位、温度上限个位
  183.         temp_min=10;temp_max=50;
  184.         
  185.         min1=temp_min/10;
  186.         min2=temp_min%10;
  187.         max1=temp_max/10;
  188.         max2=temp_max%10;
  189.         
  190.         p[8]=min1;
  191.         p[9]=min2;
  192.         p[10]=max1;
  193.         p[11]=max2;        

  194.         p[12]=8;
  195.         p[13]=8;
  196.         p[14]=8;
  197.         p[15]=8;
  198. }
  199. /*****************温湿度显示子函数*********************/
  200. void display()
  201. {
  202.    uchar m=0;
  203.    for(m=0;m<16;m++)
  204.         {
  205.                 if(m<8)                           //扫描显示前8位数码管,屏蔽后8位数码管(因为数据线共用)
  206.                 {
  207.                         InputData(0xff);       //给第三片595送屏蔽位选,LED8~15
  208.                          InputData(wei[m]);     //给第二片595送位选,LED0~7
  209.                         InputData(duan[p[m]]);        
  210.                         OutputData();
  211.                         delay(100);
  212.                 }
  213.                 else                       //扫描显示后8位数码管,屏蔽前8位数码管(因为数据线共用)
  214.                 {
  215.                         InputData(wei[m-8]);   //给第三片595送位选,LED8~15
  216.                          InputData(0xff);       //给第三片595送屏蔽位选,LED0~7
  217.                         InputData(duan[p[m]]);        
  218.                         OutputData();
  219.                         delay(100);
  220.                 }
  221.         }
  222. }
  223. /****************取实际湿度子函数**********************/
  224. void humidity_calculate()
  225. {
  226.   float c1_12bit=-2.0468,c2_12bit=0.0367,c3_12bit=-0.0000015955;//定义湿度计算公式参数
  227.   float t1_12bit=0.01;//定义湿度计算温补公式参数
  228.   float t2_12bit=0.00008;//定义湿度计算温补公式参数
  229.   humihigh8=high8;
  230.   humilow8=low8;

  231.   SO_RH=humihigh8;        //先赋值给低8位
  232.   SO_RH=((SO_RH<<8)&0xff00)|humilow8;//将两个8位合成一个16位。
  233.   SO_RH=SO_RH&0x0fff;//湿度精度默认12位。0000 1111 1111 1111=0x0fff
  234.   humi_relative=c1_12bit+c2_12bit*SO_RH+c3_12bit*SO_RH*SO_RH;

  235. //  humi=(temp_2-25)*(t1_12bit+t2_12bit*SO_RH)+humi_relative; //温度补偿
  236.   humi=humi_relative;        
  237.   compensation_humi();//湿度误差修正
  238. }
  239. /******************分离湿度值子函数********************/
  240. void humidity_seperate()
  241. {
  242.     a2=0;
  243.     b2=(humi*10)/100;
  244.     c2=((humi*10)%100)/10;
  245.     d2=((humi*10)%100)%10;
  246.         
  247.         c2+=10;        //+10表示附带小数点
  248.         p[4]=a2;
  249.         p[5]=b2;
  250.         p[6]=c2;
  251.         p[7]=d2;
  252. }
  253. /*******************湿度补偿子函数******************/
  254. void compensation_humi()
  255. {
  256.         if(humi<=12)  //0~7%
  257.         {        
  258.                 humi-=5;
  259.         }
  260.         else
  261.         {
  262.                 if(humi<=20) //8~16%
  263.                 {
  264.                         humi-=4;
  265.                 }
  266.                 else
  267.                 {
  268.                         if(humi<=33)        //17~30%
  269.                         {
  270.                                 humi-=3;
  271.                         }
  272.                         else
  273.                         {        
  274.                                 if(humi<=93)   //31~91%
  275.                                 {
  276.                                         humi-=2;
  277.                                 }
  278.                                 else
  279.                                 {
  280.                                         if(humi<=103)         //92~100%
  281.                                         {        
  282.                                                 humi-=3;
  283.                                         }
  284.                                 }
  285.                         }
  286.                 }
  287.         }        
  288. }
  289. /************************软复位子函数******************/
  290. void sht_reset()
  291. {
  292.   uchar i;
  293.   while(DATE==1)
  294.   {         
  295.     SCK=0;
  296.     for(i=0;i<12;i++)           //数据线高电平的情况下,给时钟线至少9个脉冲
  297.     {
  298.       SCK=1;
  299.           _nop_ ();
  300.           SCK=0;
  301.           _nop_ ();
  302.     }
  303.   }
  304. }
  305. /************************温度补偿子函数******************/
  306. void compensation_temp()
  307. {
  308.         if(temp>=20)
  309.         {
  310.                 temp+=1;
  311.         }
  312.         if(temp>=53)
  313.         {
  314.                 temp+=1;        
  315.         }        
  316.         if(temp>=86)
  317.         {
  318.                 temp+=1;
  319.         }        
  320. }
复制代码



全部资料请下载附件:

SHT71模块化最终版本.rar

113.2 KB, 下载次数: 145, 下载积分: 黑币 -5

评分

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

查看全部评分

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

使用道具 举报

沙发
ID:121023 发表于 2016-6-6 19:46 | 只看该作者
C语言的学习旅程,称得上是:路漫漫,其修远矣!有师者,则数日可成。
回复

使用道具 举报

板凳
ID:170353 发表于 2017-3-13 16:57 | 只看该作者
请问楼主能不能把52改51,仿真会受影响吗
回复

使用道具 举报

地板
ID:171855 发表于 2017-5-18 16:43 | 只看该作者
楼主你这个程序编译有问题但是hex文件又可以,i请问能改一下吗,
回复

使用道具 举报

5#
ID:542441 发表于 2019-5-19 22:34 | 只看该作者
是不是真的
回复

使用道具 举报

6#
ID:542441 发表于 2019-5-19 22:35 | 只看该作者
怎么下载不了????
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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