51单片机对SHT30的驱动,读取温湿度

一、SHT30简介

SHT30温湿度传感器是一种数字式温湿度传感器,由Sensirion公司开发和生产。它具有高精度、快速响应和稳定性强的特点,被广泛用于气象观测、室内环境监测、智能家居和工业自动化等领域。

以下是SHT30温湿度传感器的主要特点:

  1. 高精度:SHT30具有高精度的温度测量范围,可达到±0.3°C,并且在较广的温度范围内保持较低的测量误差。

  2. 快速响应:该传感器具有快速的响应时间,可以在很短的时间内提供准确的温湿度读数。

  3. 低功耗:SHT30采用超低功耗设计,使其适用于电池供电的设备和便携式应用。

  4. 数字输出:传感器通过I2C接口进行数字信号输出,可以直接与微控制器或其他数字设备连接。

  5. 高抗干扰性:SHT30采用了先进的信号处理技术和抗干扰设计,能够有效地抵抗外界干扰,提供可靠的测量结果。

  6. 多种封装形式:SHT30可供选择不同的封装形式,如DIP、SMD和TO-39等,以满足不同应用场景的需求。

总之,SHT30温湿度传感器是一款性能优异的数字式温湿度传感器,适用于各种环境监测和控制应用。它的高精度、快速响应和稳定性强使得它成为许多领域中首选的温湿度传感器之一。

51单片机对SHT30的驱动,读取温湿度_第1张图片

二、资料链接

下载链接:https://pan.baidu.com/s/1UKDi0A6putMa2bqbqg09Gg                    提取码:5sl8

三、驱动工程

1、SHT30

SHT30.h

#ifndef __SHT30_H__
#define __SHT30_H__

#include 
#include 



#define  uchar  unsigned char 
#define  uint   unsigned int
	
extern uchar read_sht_data[7];

//struct data_process
//{
extern	uint SHT30_temperature;
extern	uint SHT30_humidity;
//};

extern void sht30_init(void);
extern void read_sht30(uchar *p,uchar number);
extern void sht30_data_process(void);
extern int  crc8_compute(uchar *check_data, uchar num_of_data);
extern int  sht30_crc8_check(uchar *p,uchar num_of_data,uchar CrcData);
extern void sht30_display(void);

#endif

SHT30.c

#include 

uchar read_sht_data[7];//数据读取缓存


uint SHT30_temperature;
uint SHT30_humidity;


/*****SHT30初始化*******/
void sht30_init(void)
{	
	I2C_Start();                //启动总线
	I2C_WriteAbyte(0x88);      //发送从器件写地址 
	I2C_Check_ACK();            //器件应答检测	此函数已设F0=SDA
	I2C_WriteAbyte(0x20);       //low Repeatability,0.5mps
	I2C_Check_ACK();            //器件应答检测	此函数已设F0=SDA ;
	I2C_WriteAbyte(0x32);       //low Repeatability,0.5mps
	I2C_Check_ACK();            //器件应答检测	此函数已设F0=SDA ;
	I2C_Stop();
	Delay_ms(150);              //延时测量数据,为下一步读取做准备
}

/*****SHT30读数据*******/
void read_sht30(uchar *p,uchar number)
{
	I2C_Start();                //启动总线
	I2C_WriteAbyte(0x88);      //发送从器件写地址 
	I2C_Check_ACK();            //器件应答检测	此函数已设F0=SDA
	I2C_WriteAbyte(0xe0);       //数据获取命令
	I2C_Check_ACK();            //器件应答检测	此函数已设F0=SDA ;
	I2C_WriteAbyte(0x00);       //数据获取命令
	I2C_Check_ACK();            //器件应答检测	此函数已设F0=SDA ;

	I2C_Start();                //启动总线
	I2C_WriteAbyte(0x89);      //发送从器件读地址 
	I2C_Check_ACK();            //器件应答检测	此函数已设F0=SDA
          do
		  {
		    *p=I2C_ReadAbyte();	 //开始逐个读出字节
			p++;
			if(number!=1)
			  S_ACK();			 //应答
		  }
		  while(--number);       //直至读完数据
		  S_NOACK();             //总线非应答
	I2C_Stop();			
}

/**********CRC数据校验**********/
int  crc8_compute(uchar *check_data, uchar num_of_data)
{
 	uchar i;        // bit mask
    uchar crc = 0xFF; // calculated checksum
    uchar byteCtr;    // byte counter

 // calculates 8-Bit checksum with given polynomial
    for(byteCtr = 0; byteCtr < num_of_data; byteCtr++) 
	{
     crc ^= (check_data[byteCtr]);//异或赋值,crc=crc^(check_data[byteCtr])
		
 	//crc校验,最高位是1就^0x31
     for(i = 8; i > 0; --i) 
		{
         if(crc & 0x80) 
			{
             crc = (crc << 1) ^ 0x31;
            }  
		 else 
			{
             crc = (crc << 1);
            }
        }
    }
 return crc;
}

/********CRC数据校验缓冲***************/
int sht30_crc8_check(uchar *p,uchar num_of_data,uchar CrcData)
{
  uchar crc;
  crc = crc8_compute(p, num_of_data);// calculates 8-Bit checksum
  if(crc != CrcData) 
   {   
    return 1;           
   }
return 0;
}

/*****SHT30温度数据处理*******/
void sht30_data_process(void)
{
	uchar temporary[3];           //用于暂时存放总线读出的温湿度值
    uint  Data_convert;           //用于数据转换
    uchar crc_result;             //用于CRC校验结果存放,为判断数据准确性做准备
	
	read_sht30(read_sht_data,6);  //读出数据放入缓存数组等待处理>>T高八位>>T低八位>>温度T的CRC校验位>>H高八位>>H低八位>>湿度H的CRC校验位
	temporary[0]=read_sht_data[0];//温度数据高八位
    temporary[1]=read_sht_data[1];//温度数据低八位
    temporary[2]=read_sht_data[2];//温度数据CRC校验位
	
    crc_result=sht30_crc8_check(temporary,2,temporary[2]);	 //crc校验,crc校验要是不成功就返回1,
	                                                         //同时不会更新温度值
    if(crc_result==0)  
    {
    Data_convert=(uint)(temporary[0] << 8) | temporary[1];  //把2个8位数据拼接为一个16位的数据
    //温度转换,将16位温度数据转化为10进制的温度数据,
	//这里保留了一位小数,SHT30_temperature这是一个全局变量,
	//计算温度值(uchar强制转换,数据在超过八位范围后会丢失)
    SHT30_temperature = (uint)((175.0 * (float)(0x7fff&Data_convert) / 65535.0 - 45.0) *10.0); 
    }

    temporary[0]=read_sht_data[3];//湿度数据高八位
    temporary[1]=read_sht_data[4];//湿度数据低八位
    temporary[2]=read_sht_data[5];//湿度数据CRC校验位
  //crc校验
    crc_result=sht30_crc8_check(temporary,2,temporary[2]);   //crc校验,crc校验要是不成功就返回1,
	                                                         //同时不会更新湿度值
  	if(crc_result==0)
    {
    Data_convert=(uint)(temporary[0] << 8) | temporary[1];
    //湿度转换,将16位湿度数据转化为10进制的湿度数据,
	//这里保留了一位小数,SHT30_humidity这是一个全局变量,
	//计算湿度值(uchar强制转换,数据在超过八位范围后会丢失)
    SHT30_humidity = (uint)((100.0 * (float)(0x7fff&Data_convert) / 65535.0) *10.0); 
    }	
}

/***********SHT30温湿度显示函数************/
//void sht30_display(void)
//{	
//	uchar tempe[5];
//	uchar humid[6];
//	
//	sht30_data_process();//读取sht30数据并处理得到温湿度值
//	
//	tempe[0] = (uchar)((SHT30_temperature/100)%10)+48;//温度十位
//	tempe[1] = (uchar)((SHT30_temperature/10)%10)+48;//温度个位
//	tempe[2] = '.';
//	tempe[3] = (uchar)((SHT30_temperature/1)%10)+48;//温度小数位
//	OLED_P16x16Ch(42, 4, 1);//摄氏度符号
//	
//	humid[0] = (uchar)((SHT30_humidity/100)%10)+48;//湿度十位
//	humid[1] = (uchar)((SHT30_humidity/10)%10)+48;//湿度个位
//	humid[2] = '.';
//	humid[3] = (uchar)((SHT30_humidity/1)%10)+48;//湿度小数位
//	humid[4] = '%';
//	
//	OLED_P8x16Str(10, 4, tempe); //OLED显示温度值
//	
//	OLED_P8x16Str(10, 6, humid); //OLED显示湿度值	
//}

2、IIC

I2C.h

#ifndef __I2C_H_
#define __I2C_H_

#define  uchar  unsigned char 
#define  uint   unsigned int 

#include 
#include 

#define slaw1 0xA2   //PCF8563写命令字
#define slar1 0xA3   //PCF8563读命令字
#define slaw2 0x78   //0.96寸OLED写命令字
#define slar2 0x79   //0.96寸OLED读命令字
#define slaw3 0x88   //SHT30写命令字
#define slar3 0x89   //SHT30读命令字

sbit SCL  =P1^4;    //I2C时钟线
sbit SDA  =P1^3;    //I2C数据线


extern void I2C_Start(void);
extern void I2C_Stop(void);
extern void S_ACK(void);
extern void S_NOACK(void);
extern void I2C_Check_ACK(void);
extern void I2C_WriteAbyte(uchar dat);
extern uchar I2C_ReadAbyte(void);
extern void WriteNbyte(uchar sla_w,uchar addr,uchar *p,uchar number);
extern void ReadNbyte(uchar sla_w,uchar addr,uchar sla_r,uchar *p,uchar number);

#endif

I2C.c

#include 

/*******I2C总线启动函数*************/
void I2C_Start(void)
{
    SDA=1;
	Delay_us(1);
	SCL=1;
	Delay_us(1);
	SDA=0;
	Delay_us(1);
	SCL=0;
	Delay_us(1);
}

/*******I2C总线停止函数*************/
void I2C_Stop(void)
{
    SDA=0;
	Delay_us(1);
	SCL=1;
	Delay_us(1);
	SDA=1;
	Delay_us(1);
}

/********I2C总线应答函数***********/
void S_ACK(void)
{
    SDA=0;
	Delay_us(1);
	SCL=1;
	Delay_us(1);
	SCL=0;
	Delay_us(1);
}

/*******I2C总线非应答函数*************/
void S_NOACK(void)
{
    SDA=1;
	Delay_us(1);
	SCL=1;
	Delay_us(1);
	SCL=0;
	Delay_us(1);
}

/*********I2C总线应答检查函数*********/
void I2C_Check_ACK(void)
{
	uchar i;
	SDA=1;
	Delay_us(1);
	SCL=1;
	Delay_us(1);
	F0=SDA;			             //F0为用户标志位,单片机内置寄存器,相当于一个全局变量,其值可由用户自己定义
	while((F0==1)&&(i<255)) i++; //若SDA被拉低,即收到应答信号,则退出while循环,若i=255,则按超时处理,同样退出循环
	SCL=0;
	Delay_us(1);
}

/********I2C总线单字节写函数************/
void I2C_WriteAbyte(uchar dat)
{
    uchar i;
	i=8;
	do
	{
	  if(dat&0x80)
	  {
	  SDA=1;
	  }
	  else
	  {
	  SDA=0;
	  }
	  dat<<=1;
	  Delay_us(1);
	  SCL=1;
	  Delay_us(1);
	  SCL=0;
	  Delay_us(1);
	}
    while(--i);
}

/*********I2C总线单字节读函数*************/
uchar I2C_ReadAbyte(void)
{
    uchar i,dat;
	i=8;
	SDA=1;
	Delay_us(1);
	do
	{ 
	  SCL=1;
	  Delay_us(1);
	  dat<<=1;
	  if(SDA)
	    dat++;
	  SCL=0;
	  Delay_us(1);
	}
	while(--i);
	return(dat);
}

/***********I2C总线N字节写函数**************/
//void WriteNbyte(uchar sla_w,uchar addr,uchar *p,uchar number)
//{
//    I2C_Start();                //启动总线
//	I2C_WriteAbyte(sla_w);      //发送从器件地址 
//	I2C_Check_ACK();            //器件应答检测	此函数已设F0=SDA
//	I2C_WriteAbyte(addr);       //发送从器件相关寄存器地址
//	I2C_Check_ACK();            //器件应答检测	此函数已设F0=SDA 
//	    do
//		{
//		  I2C_WriteAbyte(*p);   //开始逐个写入字节
//		  p++;
//		  I2C_Check_ACK();
//		  if(F0)
//		    break;
//		}
//	  while(--number);         //直至写完数据
//	I2C_Stop();
//}

//I2C总线N字节读函数//
//void ReadNbyte(uchar sla_w,uchar addr,uchar sla_r,uchar *p,uchar number)	 //I2C器件写地址,器件相关寄存器地址,I2C器件读地址,第一位数据地址,数据宽度
//{
//    I2C_Start();				//启动总线
//	I2C_WriteAbyte(sla_w);      //发送从器件地址
//	I2C_Check_ACK();			//器件应答检测	此函数已设F0=SDA
//	I2C_WriteAbyte(addr);		//发送从器件相关寄存器地址
//	I2C_Check_ACK();			//器件应答检测
//	I2C_Start();			    //重新通信
//    I2C_WriteAbyte(sla_r);	    //发送从器件地址和读信号
//	I2C_Check_ACK();		    //器件应答检测 
//		  do
//		  {
//		    *p=I2C_ReadAbyte();	 //开始逐个读出字节
//			p++;
//			if(number!=1)
//			  S_ACK();			 //应答
//		  }
//		  while(--number);       //直至读完数据
//		  S_NOACK();             //总线非应答
//	I2C_Stop();
//}

四、完整代码工程

链接:https://pan.baidu.com/s/1bhFkaj2A1zoSOECTt-Ik0Q?pwd=zxf1 
提取码:zxf1 
--来自百度网盘超级会员V3的分享

你可能感兴趣的:(51单片机,嵌入式硬件,51单片机,嵌入式硬件,单片机)