找回密码
 立即注册

QQ登录

只需一步,快速开始

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

51单片机大棚环境检测程序

[复制链接]
跳转到指定楼层
楼主
ID:605065 发表于 2020-11-29 21:30 | 显示全部楼层 回帖奖励 |倒序浏览 |阅读模式
51单片机,检测大棚土壤温湿度、CO2浓度和光照强度。用到sht10、GY-30和SGP-30,用1602显示,三个程序凑的,加蜂鸣器报警,三个LED随光照强度改变点亮个数。小白勿喷

单片机源程序如下:
  1. /***********************************************************************
  2. * 文 件 名: 温湿度测量仪
  3. * 使用芯片: STC89C52RC
  4. * 使用晶振: 12MHz
  5. * 编程方式: 框架式编程
  6. * 硬件连接: P0口连接到LCD1602的数据口,P2^0接到LCD数据/命令选择端RS,P2^1接到LCD读/写控制信号端RW,P2^2接到LCD1602使能端EN
  7. * 描述功能: LCD1602显示温湿度传感器SHT11的温湿度
  8. * 日    期: 2018/12/16
  9. * 作    者: (果果小师弟)B站
  10. ***********************************************************************/

  11. # include <all.h>
  12. #include  <REG51.H>       
  13. #include  <math.h>    //Keil library  
  14. #include  <stdio.h>   //Keil library       
  15. #include  <INTRINS.H>
  16. #define   uchar unsigned char
  17. #define   uint unsigned int       

  18. #include "main.h"
  19. #include "stdio.h"
  20. #include "stdio.h"
  21. #include "SGP30.h"
  22. #include "delay.h"

  23. sbit          SCL=P1^5;      //IIC时钟引脚定义
  24. sbit            SDA=P1^4;      //IIC数据引脚定义

  25. sbit                bee=P3^7;
  26. sbit    gled=P3^6;
  27. sbit    yled=P3^5;
  28. sbit    rled=P3^4;
  29. #define          SlaveAddress   0x46 //定义器件在IIC总线中的从地址,根据ALT  ADDRESS地址引脚不同修改
  30.                               //ALT  ADDRESS引脚接地时地址为0xA6,接电源时地址为0x3A
  31. typedef   unsigned char BYTE;
  32. typedef   unsigned short WORD;

  33. BYTE    BUF[8];                         //接收数据缓存区             
  34. uchar   ge,shi,bai,qian,wan,q;            //显示变量
  35. int     dis_data;                       //变量
  36. unsigned int flag=0;
  37. void delay_nms(unsigned int k);
  38. void InitLcd();
  39. void Init_BH1750(void);

  40. void WriteDataLCM(uchar dataW);
  41. void WriteCommandLCM(uchar CMD,uchar Attribc);
  42. void DisplayOneChar(uchar X,uchar Y,uchar DData);
  43. void conversion(uint temp_data);

  44. void  Single_Write_BH1750(uchar REG_Address);               //单个写入数据
  45. uchar Single_Read_BH1750(uchar REG_Address);                //单个读取内部寄存器数据
  46. void  Multiple_Read_BH1750();                               //连续的读取内部寄存器数据
  47. //------------------------------------
  48. void Delay5us();
  49. void Delay5ms();
  50. void BH1750_Start();                    //起始信号
  51. void BH1750_Stop();                     //停止信号
  52. void BH1750_SendACK(bit ack);           //应答ACK
  53. bit  BH1750_RecvACK();                  //读ack
  54. void BH1750_SendByte(BYTE dat);         //IIC单个字节写
  55. BYTE BH1750_RecvByte();                 //IIC单个字节读


  56. uint wendu,shidu;
  57. typedef union   
  58. {
  59.   uint i;        //定义了两个共用体   
  60.   float f;  
  61. } value;   
  62.   enum
  63.   {
  64.           TEMP,HUMI   //TEMP=0,HUMI=1
  65.   };
  66.        
  67. void conversion(uint temp_data)  //  数据转换出 个,十,百,千,万
  68. {  

  69.                         if(temp_data<3000)
  70.                 {
  71.                  rled=1;
  72.                  gled=0;
  73.                  yled=1;
  74.                  }
  75.                  else if(temp_data>3000)
  76.                 {
  77.                 if(temp_data>6000)
  78.                 {
  79.                         rled=0;
  80.                  gled=0;
  81.                  yled=0;
  82.                  }else
  83.                  {
  84.                          rled=1;
  85.                  gled=0;
  86.                  yled=0;
  87.                  }
  88.                  }else
  89.                  {
  90.                  rled=1;
  91.                  gled=1;
  92.                  yled=1;
  93.                  }

  94.     wan=temp_data/10000+0x30 ;
  95.     temp_data=temp_data%10000;   //取余运算
  96.         qian=temp_data/1000+0x30 ;
  97.     temp_data=temp_data%1000;    //取余运算
  98.     bai=temp_data/100+0x30   ;
  99.     temp_data=temp_data%100;     //取余运算
  100.     shi=temp_data/10+0x30    ;
  101.     temp_data=temp_data%10;      //取余运算
  102.     ge=temp_data+0x30;        
  103.                

  104. }

  105. //毫秒延时**************************
  106. void delay_nms(unsigned int k)       
  107. {                                               
  108. unsigned int i,j;                               
  109. for(i=0;i<k;i++)
  110. {                       
  111. for(j=0;j<121;j++)                       
  112. {;}}                                               
  113. }


  114. /**************************************
  115. 延时5微秒(STC90C52RC@12M)
  116. 不同的工作环境,需要调整此函数,注意时钟过快时需要修改
  117. 当改用1T的MCU时,请调整此延时函数
  118. **************************************/
  119. void Delay5us()
  120. {
  121.     _nop_();_nop_();_nop_();_nop_();
  122.     _nop_();_nop_();_nop_();_nop_();
  123.         _nop_();_nop_();_nop_();_nop_();
  124.         _nop_();_nop_();_nop_();_nop_();
  125. }

  126. /**************************************
  127. 延时5毫秒(STC90C52RC@12M)
  128. 不同的工作环境,需要调整此函数
  129. 当改用1T的MCU时,请调整此延时函数
  130. **************************************/
  131. void Delay5ms()
  132. {
  133.     WORD n = 560;

  134.     while (n--);
  135. }

  136. /**************************************
  137. 起始信号
  138. **************************************/
  139. void BH1750_Start()
  140. {
  141.     SDA = 1;                    //拉高数据线
  142.     SCL = 1;                    //拉高时钟线
  143.     Delay5us();                 //延时
  144.     SDA = 0;                    //产生下降沿
  145.     Delay5us();                 //延时
  146.     SCL = 0;                    //拉低时钟线
  147. }

  148. /**************************************
  149. 停止信号
  150. **************************************/
  151. void BH1750_Stop()
  152. {
  153.     SDA = 0;                    //拉低数据线
  154.     SCL = 1;                    //拉高时钟线
  155.     Delay5us();                 //延时
  156.     SDA = 1;                    //产生上升沿
  157.     Delay5us();                 //延时
  158. }

  159. /**************************************
  160. 发送应答信号
  161. 入口参数:ack (0:ACK 1:NAK)
  162. **************************************/
  163. void BH1750_SendACK(bit ack)
  164. {
  165.     SDA = ack;                  //写应答信号
  166.     SCL = 1;                    //拉高时钟线
  167.     Delay5us();                 //延时
  168.     SCL = 0;                    //拉低时钟线
  169.     Delay5us();                 //延时
  170. }

  171. /**************************************
  172. 接收应答信号
  173. **************************************/
  174. bit BH1750_RecvACK()
  175. {
  176.     SCL = 1;                    //拉高时钟线
  177.     Delay5us();                 //延时
  178.     CY = SDA;                   //读应答信号
  179.     SCL = 0;                    //拉低时钟线
  180.     Delay5us();                 //延时

  181.     return CY;
  182. }

  183. /**************************************
  184. 向IIC总线发送一个字节数据
  185. **************************************/
  186. void BH1750_SendByte(BYTE dat)
  187. {
  188.     BYTE i;

  189.     for (i=0; i<8; i++)         //8位计数器
  190.     {
  191.         dat <<= 1;              //移出数据的最高位
  192.         SDA = CY;               //送数据口
  193.         SCL = 1;                //拉高时钟线
  194.         Delay5us();             //延时
  195.         SCL = 0;                //拉低时钟线
  196.         Delay5us();             //延时
  197.     }
  198.     BH1750_RecvACK();
  199. }

  200. /**************************************
  201. 从IIC总线接收一个字节数据
  202. **************************************/
  203. BYTE BH1750_RecvByte()
  204. {
  205.     BYTE i;
  206.     BYTE dat = 0;

  207.     SDA = 1;                    //使能内部上拉,准备读取数据,
  208.     for (i=0; i<8; i++)         //8位计数器
  209.     {
  210.         dat <<= 1;
  211.         SCL = 1;                //拉高时钟线
  212.         Delay5us();             //延时
  213.         dat |= SDA;             //读数据               
  214.         SCL = 0;                //拉低时钟线
  215.         Delay5us();             //延时
  216.     }
  217.     return dat;
  218. }

  219. //*********************************

  220. void Single_Write_BH1750(uchar REG_Address)
  221. {
  222.     BH1750_Start();                  //起始信号
  223.     BH1750_SendByte(SlaveAddress);   //发送设备地址+写信号
  224.     BH1750_SendByte(REG_Address);    //内部寄存器地址,请参考中文pdf22页
  225.   //  BH1750_SendByte(REG_data);       //内部寄存器数据,请参考中文pdf22页
  226.     BH1750_Stop();                   //发送停止信号
  227. }

  228. //*********************************************************
  229. //
  230. //连续读出BH1750内部数据
  231. //
  232. //*********************************************************
  233. void Multiple_read_BH1750(void)
  234. {   uchar i;       
  235.     BH1750_Start();                          //起始信号
  236.     BH1750_SendByte(SlaveAddress+1);         //发送设备地址+读信号
  237.        
  238.          for (i=0; i<3; i++)                      //连续读取6个地址数据,存储中BUF
  239.     {
  240.         BUF[i] = BH1750_RecvByte();          //BUF[0]存储0x32地址中的数据
  241.         if (i == 3)
  242.         {

  243.            BH1750_SendACK(1);                //最后一个数据需要回NOACK
  244.         }
  245.         else
  246.         {               
  247.           BH1750_SendACK(0);                //回应ACK
  248.        }
  249.    }

  250.     BH1750_Stop();                          //停止信号
  251.     Delay5ms();
  252. }


  253. //初始化BH1750,根据需要请参考pdf进行修改****
  254. void Init_BH1750()
  255. {
  256.    Single_Write_BH1750(0x01);  

  257. }
  258. //*********************************************************
  259. //主程序********
  260. //*********************************************************

  261. void main(void)
  262. {  
  263.         float temp1;
  264.                 value humi_val,temp_val;         
  265.     char error;
  266.         char checksum;  
  267.         u32 sgp30_dat;
  268.         u16 CO2Data,TVOCData;//定义CO2浓度变量与TVOC浓度变量,
  269.         SGP30_Init();   //初始化SGP30
  270.        
  271.        
  272.          
  273.         LCD_init();           
  274.         s_connectionreset();  
  275.   LCD_disp_str(5,1,"welcome");
  276.         delay_n10us(2000);              //延时0.2s
  277.   Init_BH1750();       //初始化BH1750       
  278.        
  279.         SGP30_Write(0x20,0x08);
  280.         sgp30_dat = SGP30_Read();//读取SGP30的值
  281.         CO2Data = (sgp30_dat & 0xffff0000) >> 16;
  282.         TVOCData = sgp30_dat & 0x0000ffff;       
  283.        
  284.                 /*while(CO2Data == 400 && TVOCData == 0)
  285.         {
  286.                 SGP30_Write(0x20,0x08);
  287.                 sgp30_dat = SGP30_Read();//读取SGP30的值
  288.                 CO2Data = (sgp30_dat & 0xffff0000) >> 16;//取出CO2浓度值
  289.                 TVOCData = sgp30_dat & 0x0000ffff;                         //取出TVOC值
  290.                
  291.                 delay_ms(100);
  292.         }*/
  293.        
  294.         while(1)         
  295.         {
  296.                 error=0;            
  297.                 error+=s_measure((uchar*) &humi_val.i,&checksum,HUMI);  //测量湿度            
  298.                 error+=s_measure((uchar*) &temp_val.i,&checksum,TEMP);  //测量温度   

  299.                 Single_Write_BH1750(0x01);   // power on
  300.     Single_Write_BH1750(0x10);   // H- resolution mode
  301.                
  302.                 SGP30_Write(0x20,0x08);
  303.                 (u32)sgp30_dat = (u32)SGP30_Read();//读取SGP30的值
  304.                 CO2Data = (sgp30_dat & 0xffff0000) >> 16;//取出CO2浓度值
  305.                 if(CO2Data>10000 | temp1>9000)
  306.                         bee=0;
  307.                 else
  308.                 {
  309.                         bee=1;
  310.                 }

  311.                 TVOCData = sgp30_dat & 0x0000ffff;       //取出TVOC值
  312.                
  313.      delay_nms(180);              //延时180ms

  314.     Multiple_Read_BH1750();       //连续读出数据,存储在BUF中

  315.     dis_data=BUF[0];
  316.     dis_data=(dis_data<<8)+BUF[1];//合成数据
  317.    
  318.     temp1=(float)dis_data/1.2;
  319.     conversion(temp1);         //计算数据和显示
  320.                 if(error!=0)
  321.                 s_connectionreset();                 //如果出现错误:连接重置         
  322.                 else            
  323.                 {               
  324.                                 //flag++;
  325.                                 //if(flag==11)
  326.                                         //flag=0;
  327.                                        
  328.                                 //if(flag<5)
  329.                                 //{
  330.                                 //LCD_disp_str(0,1,"s       ");   
  331.                                 //LCD_disp_str(0,2,"w       ");
  332.                                 LCD_disp_str(0,1,"TT.T %  ");           //初始化温度显示区
  333.                                 LCD_disp_str(0,2,"RR.R C  ");     //初始化湿度显示区
  334.                         humi_val.f=(float)humi_val.i;                   //将整数转换为浮点数            
  335.                         temp_val.f=(float)temp_val.i;                   //将整数转换为浮点数           
  336.                         calc_dht90(&humi_val.f,&temp_val.f);            //计算湿度、温度
  337.                         wendu=10*temp_val.f;     
  338.                         //LCD_disp_char(2,2,wendu/1000+'0');              //显示温度百位              
  339.                         LCD_disp_char(0,2,(wendu%1000)/100+'0');        //显示温度十位            
  340.                         LCD_disp_char(1,2,(wendu%100)/10+'0');         //显示温度个位   
  341.                         LCD_disp_char(3,2,(wendu%10)+'0');             //显示温度小数点后第一位
  342.                         LCD_disp_char(4,2,0xdf);
  343.                         shidu=10*humi_val.f;     
  344.                         //LCD_disp_char(2,1,shidu/1000+'0');               //显示湿度百位              
  345.                         LCD_disp_char(0,1,(shidu%1000)/100+'0');         //显示湿度十位            
  346.                         LCD_disp_char(1,1,(shidu%100)/10+'0');          //显示湿度个位   
  347.                         LCD_disp_char(3,1,(shidu%10)+'0');              //显示湿度小数点后第一位
  348.                         //}
  349.                        
  350.                         //if (flag>5)
  351.                         //{
  352.                         LCD_disp_str(7,1,"       lx");
  353.                         LCD_disp_char(8,1,wan);
  354.                         LCD_disp_char(9,1,qian);
  355.                         LCD_disp_char(10,1,bai);
  356.                         LCD_disp_char(11,1,shi);
  357.                         LCD_disp_char(12,1,ge);
  358.                        
  359.                         if (CO2Data == 400 && TVOCData == 0)
  360.                                 LCD_disp_str(8,2," loading");
  361.                         else
  362.                         {                       
  363.                         LCD_disp_str(7,2,"      ppm");
  364.                         LCD_disp_char(7,2,CO2Data/10000+'0');
  365.                         LCD_disp_char(8,2,(CO2Data/1000)%10+'0');
  366.                         LCD_disp_char(9,2,(CO2Data%1000)/100+'0');
  367.                         LCD_disp_char(10,2,(CO2Data%100)/10+'0');
  368.                         LCD_disp_char(11,2,CO2Data%10+'0');
  369.                         }
  370.                         //}
  371.                  }            
  372.        delay_n10us(8000);                               //延时约0.8s         
  373.   }
  374. }  
复制代码

所有程序51hei提供下载:
检测.zip (91.44 KB, 下载次数: 63)


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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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