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

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);
}

你可能感兴趣的:(GD32,STM32,单片机,stm32,嵌入式硬件,SHT31,SHT85)