SHT31/85温湿度传感器驱动代码(基于GD32F103)

5 篇文章 2 订阅

IIC驱动.c部分

#include "main.h"
void IIC_SDA(uint8_t status)
{
  if(status == 1)
  {
    gpio_bit_set(SDA_GPIO_Port,SDA_Pin);
  }
  else
  {
    gpio_bit_reset(SDA_GPIO_Port,SDA_Pin);
  }
}

void IIC_SCL(uint8_t status)
{
  if(status == 1)
  {
    gpio_bit_set(SCL_GPIO_Port,SCL_Pin);
  }
  else
  {
    gpio_bit_reset(SCL_GPIO_Port,SCL_Pin);
  }
}

uint8_t READ_SDA(void)
{
  FlagStatus status;
  status = gpio_input_bit_get(SDA_GPIO_Port,SDA_Pin);
  if(status == SET)
  {
    return 1;
  }
  else
  {
    return 0;
  }
}
 
//初始化IIC
void IIC_Init(void)
{
  rcu_periph_clock_enable(RCU_GPIOB);
  gpio_init(SCL_GPIO_Port,GPIO_MODE_OUT_PP,GPIO_OSPEED_50MHZ,SCL_Pin);
  gpio_init(SDA_GPIO_Port,GPIO_MODE_OUT_PP,GPIO_OSPEED_50MHZ,SDA_Pin);
}
//产生IIC起始信号
void IIC_Start(void)
{
	SDA_OUT();     //sda线输出
	IIC_SDA(1);	  	  
	IIC_SCL(1);
	delay_us(4);
 	IIC_SDA(0);//START:when CLK is high,DATA change form high to low 
	delay_us(4);
	IIC_SCL(0);//钳住I2C总线,准备发送或接收数据 
}	  
//产生IIC停止信号
void IIC_Stop(void)
{
	SDA_OUT();//sda线输出
	IIC_SCL(0);
	IIC_SDA(0);//STOP:when CLK is high DATA change form low to high
 	delay_us(4);
	IIC_SCL(1); 
	IIC_SDA(1);//发送I2C总线结束信号
	delay_us(4);							   	
}
//等待应答信号到来
//返回值:1,接收应答失败
//        0,接收应答成功
u8 IIC_Wait_Ack(void)
{
	u8 ucErrTime=0;
	SDA_IN();      //SDA设置为输入  
	IIC_SDA(1);delay_us(1);	   
	IIC_SCL(1);delay_us(1);	 
	while(READ_SDA())
	{
		ucErrTime++;
		if(ucErrTime>250)
		{
			IIC_Stop();
			return 1;
		}
	}
	IIC_SCL(0);//时钟输出0 	   
	return 0;  
} 
//产生ACK应答
void IIC_Ack(void)
{
	IIC_SCL(0);
	SDA_OUT();
	IIC_SDA(0);
	delay_us(2);
	IIC_SCL(1);
	delay_us(2);
	IIC_SCL(0);
}
//不产生ACK应答		    
void IIC_NAck(void)
{
	IIC_SCL(0);
	SDA_OUT();
	IIC_SDA(1);
	delay_us(2);
	IIC_SCL(1);
	delay_us(2);
	IIC_SCL(0);
}					 				     
//IIC发送一个字节
//返回从机有无应答
//1,有应答
//0,无应答			  
void IIC_Send_Byte(u8 txd)
{                        
    u8 t;   
	SDA_OUT(); 	    
    IIC_SCL(0);//拉低时钟开始数据传输
    for(t=0;t<8;t++)
    {              
        IIC_SDA((txd&0x80)>>7);
        txd<<=1; 	  
		delay_us(2);   //对TEA5767这三个延时都是必须的
		IIC_SCL(1);
		delay_us(2); 
		IIC_SCL(0);	
		delay_us(2);
    }	 
} 	    
//读1个字节,ack=1时,发送ACK,ack=0,发送nACK   
u8 IIC_Read_Byte(unsigned char ack)
{
	unsigned char i,receive=0;
	SDA_IN();//SDA设置为输入
    for(i=0;i<8;i++ )
	{
        IIC_SCL(0); 
        delay_us(2);
		IIC_SCL(1);
        receive<<=1;
        if(READ_SDA())receive++;   
		delay_us(1); 
    }					 
    if (!ack)
        IIC_NAck();//发送nACK
    else
        IIC_Ack(); //发送ACK   
    return receive;
}

IIC驱动.h部分

#ifndef __MYIIC_H
#define __MYIIC_H
#include "main.h"

#define SCL_Pin       GPIO_PIN_10
#define SCL_GPIO_Port GPIOB
#define SDA_Pin       GPIO_PIN_11
#define SDA_GPIO_Port GPIOB
 
//IO方向设置 
#define SDA_IN()  gpio_init(SDA_GPIO_Port,GPIO_MODE_IPU,GPIO_OSPEED_50MHZ,SDA_Pin);
#define SDA_OUT() gpio_init(SDA_GPIO_Port,GPIO_MODE_OUT_PP,GPIO_OSPEED_50MHZ,SDA_Pin);

#define u8  unsigned char
#define u16 unsigned short
#define u32 unsigned int 
  
//IIC所有操作函数
void IIC_Init(void);                //初始化IIC的IO口				 
void IIC_Start(void);				//发送IIC开始信号
void IIC_Stop(void);	  			//发送IIC停止信号
void IIC_Send_Byte(u8 txd);			//IIC发送一个字节
u8 IIC_Read_Byte(unsigned char ack);//IIC读取一个字节
u8 IIC_Wait_Ack(void); 				//IIC等待ACK信号
void IIC_Ack(void);					//IIC发送ACK信号
void IIC_NAck(void);				//IIC不发送ACK信号

void IIC_Write_One_Byte(u8 daddr,u8 addr,u8 data);
u8 IIC_Read_One_Byte(u8 daddr,u8 addr);	  
#endif

SHT31、85驱动.c部分

#include "main.h"

SHT85_DATA SHT85_Data;

/*********************************************************
函数名:SHT3X_Wait_Ack()
描述:SHT3X等待Ack
入口参数:标志f
出口参数;f=1,收不到ack重启通信
          f=0,收不到也不重启
附加信息:
说明:
*********************************************************/
void SHT3X_Wait_Ack(u8 f)
{
  u8 flag=1;
  flag=IIC_Wait_Ack();               
	
  if(f)                                                      //这里我索性全用的0,采用1的时候好像会陷入死循环。
   {if(flag) SHT3X_Init();}
	
}
/*********************************************************
函数名:SHT3X_Init()
描述:SHT3X初始化
入口参数:无
出口参数;无
附加信息:
说明:
*********************************************************/
void SHT3X_Init()
{
  IIC_Start();
	IIC_Send_Byte(SHT3X_ADRESS_A<<1|write);    //这里默认ADDR引脚接VDD,采用地址B。且地址左移一位,并补0,准备写数据
  SHT3X_Wait_Ack(0);
  SHT3X_Mode_Set(MPS_4,Repeatability_Medium);       //直接用之前封装好的   
	SHT3X_Wait_Ack(0);
}
/*********************************************************
函数名:SHT3X_Get_Vlaue()
描述:一键取值函数
入口参数:无
出口参数;无
附加信息:
说明:
*********************************************************/
void   SHT3X_Get_Vlaue()
{
  SHT3X_Write_Command(Fetch_Data);
  IIC_Start();                       //准备接受数据
	IIC_Send_Byte(SHT3X_ADRESS_A<<1|read);    //采用地址B,并左移一位,补1,准备读数据。
	SHT3X_Wait_Ack(0);
}
/*********************************************************
函数名:SHT3X_Write(u16 code)
描述:SHT3X写16位数据/命令
入口参数:无
出口参数;无
附加信息:
说明:
*********************************************************/
void SHT3X_Write(u16 code)
{ 
  unsigned int MSB,LSB;
	u16 date;
	date=code;                   //这里采用移位的办法让MSB和LSB分别获得高八位和低八位。
  MSB=code>>8;             //先把数据右移八位让MSB获得高八位
	
  date=date<<8;              //再把原数据左移八位
	
	LSB=date>>8;          //然后把左移过八位的数据再右移八位移回,从而使LSB获得低八位
	
	IIC_Send_Byte(MSB);        //写MSB高八位	
  SHT3X_Wait_Ack(0);
  IIC_Send_Byte(LSB);        //写LSB低八位
	SHT3X_Wait_Ack(0);
}
/*********************************************************
函数名:SHT3X_Write_Command(u16 code)
描述:SHT3X直接写入命令
入口参数:要写入的命令
出口参数;无
附加信息:把整个写命令的流程打包,实现一个函数写命令
说明:
*********************************************************/
void SHT3X_Write_Command(u16 code)
{
  IIC_Start();
	IIC_Send_Byte(SHT3X_ADRESS_A<<1|write);    //这里默认ADDR引脚接VDD,采用地址B
  SHT3X_Wait_Ack(0);
  SHT3X_Write(code);                 //写入命令
	SHT3X_Wait_Ack(0);
}
/*********************************************************
函数名:SHT3X_Read_Date(u8 ack)
描述:   读数据
入口参数:ack
出口参数;16位date
附加信息:ack=1时,发送ack。ack=0时,返回nack
说明:
*********************************************************/
u16  SHT3X_Read_Date(u8 ack)
{
	u8 i;
	u16 MSB,LSB;
	u16 date;
	
  MSB=IIC_Read_Byte(1);     //读完一个字节后返回ACK
  LSB=IIC_Read_Byte(1);      //读完一个字节后返回ACK
  for(i=0;i<8;i++)                       //相当于把MSB左移八位       
	{
	  MSB=MSB*2;
	}
	date=MSB+LSB;              //然后加合MSB与LSB,重新拼接获得原数据
	return date;
}
/*********************************************************
函数名:SHT3X_CRC_Calculation(u16 date)
描述:   CRC数据和计算
入口参数:CRC校验的数据
出口参数;crc
附加信息:
说明:
*********************************************************/
u8 SHT3X_CRC_Calculation(u16 date)
{ 
	u8 i,j=0;
	u32 crc,p=0x31;
	crc=date;
	
	crc<<=8;
	p<<=16;
	
	for(i=0;i<8;i++)
  {
	 while(!((crc&0x800000)>>23)) {p>>=1; j++;}    //对齐最高位
	 crc=crc&p;
	 if(j==15) break;
	}
	return crc;
}
/*********************************************************
函数名:SHT3X_CRC_Check(u8 t,u8 ack,u16 date)
描述:   CRC数据和检测
入口参数:16位数据,ack标志,t标志
出口参数;无
附加信息: ack=1时,发送ack。ack=0时,发送nack。
          t=1时,启动校验。t=0时,进行伪校验。
说明:
*********************************************************/
void   SHT3X_CRC_Check(u8 t,u8 ack,u16 date)
{
	u8 crc_re,crc_ca;
	
	crc_re=IIC_Read_Byte(ack);                
	
	if(t)                                                                             
	{
	 crc_ca=SHT3X_CRC_Calculation(date);          
	 if(crc_ca!=crc_re) SHT3X_Read_Date(ack);
	}
	
  if(!ack) IIC_Stop();
}
/*********************************************************
函数名: SHT3X_Date_Process(u8 Flag);
描述:   数据处理
入口参数:flag标志
出口参数;浮点型Date
附加信息: flag=0,返回RH
          flag=1,返回TC
          flag=2,返回TF
说明:
*********************************************************/

float   SHT3X_Date_Process(u8 Flag,u16 date)
{
	float Date;
  if(Flag==2) Date=SHT3X_TF(date);
	if(Flag==1) Date=SHT3X_TC(date);
	if(Flag==0) Date=SHT3X_RH(date);
  return Date;
}
/*********************************************************
函数名: SHT3X_Mode_Set(u8 mps,u8 re)
描述:   模式选择设置
入口参数:标志mps,re
出口参数;无
附加信息: 注意,mps设定为10时会导致器件发热
说明:
*********************************************************/
void   SHT3X_Mode_Set(u8 mps,u8 re)
{
   if(mps==0)
	 {
	   if(re==0)       SHT3X_Write_Command(0x202F);
		 else if(re==1)  SHT3X_Write_Command(0x2024);
	   else if(re==2)  SHT3X_Write_Command(0x2032);
	 }
	else if(mps==1)
	 {
	   if(re==0)       SHT3X_Write_Command(0x212D);
		 else if(re==1)  SHT3X_Write_Command(0x2126);
	   else if(re==2)  SHT3X_Write_Command(0x2130);
	 }
	else if(mps==2)
	 {
	   if(re==0)       SHT3X_Write_Command(0x222B);
		 else if(re==1)  SHT3X_Write_Command(0x2220);
	   else if(re==2)  SHT3X_Write_Command(0x2236);
	 }
	else if(mps==3) 
	 {
	   if(re==0)       SHT3X_Write_Command(0x2329);
		 else if(re==1)  SHT3X_Write_Command(0x2322);
	   else if(re==2)  SHT3X_Write_Command(0x2334);
	 }
	else if(mps==4) 
	 {
	   if(re==0)       SHT3X_Write_Command(0x272A);
		 else if(re==1)  SHT3X_Write_Command(0x2721);
	   else if(re==2)  SHT3X_Write_Command(0x2737);
	 }
}
/*********************************************************
函数名:  SHT3X_Get_Status(void)
描述:   读传感器模式寄存器
入口参数:无
出口参数;16位传感器状态数据
附加信息: 0位为CRC校验状态位
          1位为命令状态位
说明:
*********************************************************/
u16  SHT3X_Get_Status(void)
{
 u16 sta;
 SHT3X_Write_Command(Read_Status);
 IIC_Start();                       //准备接受数据
 IIC_Send_Byte(SHT3X_ADRESS_A<<1|read);    
 SHT3X_Wait_Ack(0);
 sta=SHT3X_Read_Date(ACK);
 SHT3X_CRC_Check(CRC_OFF,NACK,sta);
 return sta;
}
/*********************************************************
函数名:  SHT3X_Statues_Process(u8 f,u16 sta)
描述:   传感器状态数据处理并送串口传输
入口参数:标志f,读得传感器状态数据sta
出口参数;CRC校验状态或命令执行状态
附加信息: 
说明:
*********************************************************/
void SHT3X_Statues_Process(u8 f,u16 sta)
{
   
}
/*********************************************************
函数名:  SHT85_Read()
描述:   获取传感器数据
入口参数:无
出口参数;无
附加信息: 
说明:
*********************************************************/
void SHT85_Read(void)
{
  SHT3X_Get_Vlaue();                  //SHT3X读值准备		
  SHT85_Data.Temperature_Raw=SHT3X_Read_Date(ACK);         //读温度数据
  SHT3X_CRC_Check(CRC_OFF,ACK,SHT85_Data.Temperature_Raw); //读CRC,伪CRC验证,只读取,不检验
  SHT85_Data.Humidity_Raw=SHT3X_Read_Date(ACK);			       //读湿度数据
  SHT3X_CRC_Check(CRC_OFF,NACK,SHT85_Data.Humidity_Raw);   //伪验证	
  SHT85_Data.Temperature = SHT3X_Date_Process(T_C,SHT85_Data.Temperature_Raw);  //数据处理
  SHT85_Data.Humidity       = SHT3X_Date_Process(R_H,SHT85_Data.Humidity_Raw); 
}

// SHT85 测温任务
void sht85_thread_entry (void *parameter)
{
	IIC_Init();
	SHT3X_Init();  //温湿度传感器初始化
	rt_thread_mdelay(100);
	while(1)
	{
    SHT85_Read();
	  rt_thread_mdelay(1000);
	  rt_thread_mdelay(100);
	}
}

SHT31、85驱动.h部分

#ifndef  _SHT3X_H
#define  _SHT3X_H

#include "main.h"

#define u8  unsigned char
#define u16 unsigned short
#define u32 unsigned int 

typedef struct
{
  float Humidity;
  float Temperature;
  float Humidity_Raw;
  float Temperature_Raw;
  unsigned short Sta;
}SHT85_DATA;
extern SHT85_DATA SHT85_Data;

//ADRESS
#define SHT3X_ADRESS_A               0x44                    //ADDR引脚接VSS时地址
#define SHT3X_ADRESS_B               0x45                    //ADDR引脚接VDD时地址
#define SHT3X_GENERALL_CALL_ADRESS 0X0006                    //广播复位地址,可触发同硬复位一样效果

//COMMAND
#define Mode_Set_A                 0x2C0D      //这里设定为单次采样模式。中断刷新率,开启时钟延伸。
#define Mode_Set_B                 0x2322      //这里设定为周期采样模式。每秒四次,中等刷新率。默认开启时钟延伸。注意每秒10次时会导致器件发热。
#define Fetch_Data                 0xE000      //获取数据命令
#define ART_ON                     0x2B32      //打开ART定期测量
#define Break_Periodic_Mode        0x3093      //中断周期采样模式。这里会回到单次采样模式。
#define Soft_Reset                 0x30A2      //传感器软复位,注意只有传感器处于空闲状态才能接受成功。
#define Heater_Enable              0x306D      //加热器使能
#define Heater_Disable             0x3066      //加热器禁用
#define Read_Status                0xF32D      //读状态寄存器
#define Clear_Status               0x3041      //清部分状态位

//FLAG
#define R_H                        0
#define T_C                        1
#define T_F                        2

#define CRC_ON                     1
#define CRC_OFF                    0

#define ACK                        1
#define NACK                       0

#define write                      0
#define read                       1

#define Repeatability_Low          0
#define Repeatability_Medium       1
#define Repeatability_High         2

#define MPS_0_5                    0
#define MPS_1                      1
#define MPS_2                      2
#define MPS_4                      3
#define MPS_10                     4

#define CRC_Statues                0
#define Command_Statues            1

//DATE PROCESS                                                 将原始量转化为物理量                              
#define SHT3X_TC(date)	(175 * (float)date / 65535 -45)          //摄氏度处理
#define SHT3X_TF(date)  (315 * (float)date / 65535 -49)          //华氏度处理
#define SHT3X_RH(date)  (100 * (float)date / 65535)              //相对湿度处理


void   SHT3X_Init(void);
void   SHT3X_Write(u16 code);
void   SHT3X_Write_Command(u16 code);
void   SHT3X_Wait_Ack(u8 f);
void   SHT3X_Get_Vlaue(void);
void   SHT3X_Mode_Set(u8 mps,u8 re);
void   SHT3X_Statues_Process(u8 f,u16 sta);

u8     SHT3X_CRC_Calculation(u16 date);
void   SHT3X_CRC_Check(u8 t,u8 ack,u16 date);
float  SHT3X_Date_Process(u8 Flag,u16 date);
u16    SHT3X_Read_Date(u8 ack);
u16    SHT3X_Get_Status(void);
void   SHT85_Read(void);

#endif

测试函数

#include "main.h"
IIC_Init();
SHT3X_Init();  //温湿度传感器初始化
rt_thread_mdelay(100);
while(1)
{
	SHT85_Read();
	delay(1000);
	delay(100);
}
  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: sht31湿度传感器是一种数字湿度传感器,可以测量环境的度和湿度。C8T6是一种型号较老的单片机开发板,使用ATmega8芯片。下面是一个可能的SHT31湿度传感器驱动C8T6代码的示例: #include <avr/io.h> #include <util/delay.h> #include <stdint.h> // 定义SHT31传感器的I2C地址 #define SHT31_I2C_ADDR 0x44 // 初始化I2C总线 void i2c_init() { // 设置SCL和SDA引脚为输出模式 DDRD |= (1 << PD0) | (1 << PD1); // 设置TWI控制寄存器的预分频系数为1,设置SCL时钟频率为 400KHz TWSR &= ~(1 << TWPS0); TWSR &= ~(1 << TWPS1); TWBR = 0x0C; } // 启动I2C总线 void i2c_start() { TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN); while (!(TWCR & (1 << TWINT))); } // 发送I2C设备地址和读写模式 void i2c_send_addr(uint8_t addr, uint8_t rw) { TWDR = addr | rw; TWCR = (1 << TWINT) | (1 << TWEN); while (!(TWCR & (1 << TWINT))); } // 发送数据 void i2c_send_data(uint8_t data) { TWDR = data; TWCR = (1 << TWINT) | (1 << TWEN); while (!(TWCR & (1 << TWINT))); } // 读取数据 uint8_t i2c_read_data() { TWCR = (1 << TWINT) | (1 << TWEN); while (!(TWCR & (1 << TWINT))); return TWDR; } // 停止I2C总线 void i2c_stop() { TWCR = (1 << TWINT) | (1 << TWSTO) | (1 << TWEN); _delay_us(50); } // 从SHT31读取度值 float sht31_read_temperature() { // 启动I2C总线 i2c_start(); // 发送传感器的I2C地址和读模式位 i2c_send_addr(SHT31_I2C_ADDR, 0x01); // 等待传感器完成度和湿度测量 _delay_ms(50); // 读取度数据 uint8_t msb = i2c_read_data(); uint8_t lsb = i2c_read_data(); // 停止I2C总线 i2c_stop(); // 计算度值 float temperature = ((msb << 8) | lsb) * 175.0 / 65535.0 - 45.0; return temperature; } // 从SHT31读取湿度值 float sht31_read_humidity() { // 启动I2C总线 i2c_start(); // 发送传感器的I2C地址和读模式位 i2c_send_addr(SHT31_I2C_ADDR, 0x01); // 等待传感器完成度和湿度测量 _delay_ms(50); // 读取湿度数据 uint8_t msb = i2c_read_data(); uint8_t lsb = i2c_read_data(); // 停止I2C总线 i2c_stop(); // 计算湿度值 float humidity = ((msb << 8) | lsb) * 100.0 / 65535.0; return humidity; } 以上代码是一个简单的SHT31湿度传感器驱动代码示例,可以在C8T6开发板上读取度和湿度数值。使用I2C通信协议与传感器进行通信,获取湿度数据,并进行计算转换。需要注意的是,在使用代码前,需要将C8T6开发板上的SCL和SDA引脚连接到SHT31湿度传感器的对应引脚上。 ### 回答2: SHT31湿度传感器是一种广泛应用于物联网和环境监测等领域的传感器。其驱动代码将根据不同的硬件平台和编程语言而有所不同。下面以C语言为例,展示一个简单的SHT31湿度传感器在C8T6开发板上的驱动代码: ```c #include <Wire.h> // 包含I2C库 #define SHT31_ADDR 0x44 // 传感器I2C地址 void setup() { Serial.begin(9600); // 初始化串口 Wire.begin(); // 初始化I2C总线 delay(100); // 延时等待传感器稳定 } void loop() { float temperature, humidity; Wire.beginTransmission(SHT31_ADDR); // 启动传输 Wire.write(0x2C); // 度和湿度读取命令 Wire.write(0x06); // 高精度模式 Wire.endTransmission(); delay(500); // 等待传感器测量 Wire.requestFrom(SHT31_ADDR, 6); // 从传感器读取数据 if(Wire.available() == 6){ uint16_t rawTemp = Wire.read() << 8; rawTemp |= Wire.read(); uint16_t rawHumidity = Wire.read() << 8; rawHumidity |= Wire.read(); Wire.read(); Wire.read(); temperature = -45 + (175 * (float)rawTemp / 65535); humidity = 100 * (float)rawHumidity / 65535; Serial.print("Temperature: "); Serial.print(temperature); Serial.print(" °C, Humidity: "); Serial.print(humidity); Serial.println(" %"); } delay(2000); // 等待2秒后重新进行测量 } ``` 这段代码使用了Wire库进行I2C通信,首先初始化了串口和I2C总线,在主循环里使用I2C读取湿度数据,然后进行数据处理和打印输出。 需要注意的是,SHT31湿度传感器的I2C地址为0x44,读取的命令为0x2C,采用高精度模式。具体的硬件平台和传感器连接方式可能会有所不同,请根据具体情况进行相应的修改。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值