Stm32F4标准库驱动Sht4温湿度传感器

SHT4温湿度传感器

1.1 SHT4参数

在这里插入图片描述

  • 精度 湿度ΔRH = ±1.0% RH,温度 ΔT =±0.1°C
  • 工作范围:0 ~ 100% RH,−40 ~ 125℃

1.2 IIC通讯读取温湿度

在这里插入图片描述

1.3 数据格式

​ 总共6个字节

​ 湿度和温度数据将始终以以下方式传输:第一个值是温度信号(2 * 8位数据+ 8位CRC),第二个值是湿度信号(2 * 8位数据+ 8位CRC)。

1.4 CRC校验

在这里插入图片描述

  • 单字节
unsigned char cal_table_high_first(unsigned char value)
{
    unsigned char i, crc;
    crc = value;
    /* 数据往左移了8位,需要计算8次 */
    for (i=8; i>0; --i)
    { 
        if (crc & 0x80)  /* 判断最高位是否为1 */
        {
        /* 最高位为1,不需要异或,往左移一位,然后与0x31异或 */
        /* 0x31(多项式:x8+x5+x4+1,100110001),最高位不需要异或,直接去掉 */
            crc = (crc << 1) ^ 0x31;        }
        else
        {
            /* 最高位为0时,不需要异或,整体数据往左移一位 */
            crc = (crc << 1);
        }
    }
 
    return crc;
}
  • 多字节
unsigned char crc_high_first(unsigned char *ptr, unsigned char len)
{
    unsigned char i; 
    unsigned char crc=0x00/* 计算的初始crc值 */ 
 
    while(len--)
    {
        crc ^= *ptr++;  /* 每次先与需要计算的数据异或,计算完指向下一数据 */  
        for (i=8; i>0; --i)   /* 下面这段计算过程与计算一个字节crc一样 */  
        { 
            if (crc & 0x80)
                crc = (crc << 1) ^ 0x31;
            else
                crc = (crc << 1);
        }
    }
 
    return (crc); 
}

1.5 通讯命令与计算公式

在这里插入图片描述

  • 0xFD 启用高精度温湿度检测。

1.6 实例

在这里插入图片描述

立创商城搜索对应的原件看对应的数据手册

1.6.1 STM32F4标准库程序

  • iic.h
#ifndef __IICTEST_H
#define __IICTEST_H

#ifdef __cplusplus
extern "C"{
#endif

#include "delay.h"
#include "stm32f4xx.h"

//IO方向设置产考F4手册
/**********************************begin**************************************/
#define SDA_In()  {GPIOC->MODER&=~(3<<(7*2));GPIOC->MODER|=0<<7*2;}
#define SDA_Out() {GPIOC->MODER&=~(3<<(7*2));GPIOC->MODER|=1<<7*2;}
/**********************************end************************************/

#define IIC_SCL_PIN																	GPIO_Pin_6
#define IIC_SDA_PIN																	GPIO_Pin_7
#define IIC_GPIO_PORT																GPIOC

#define Delay_ms(x)    															delay_ms(x)
#define Delay_us(x)    															delay_us(x)

//IO操作函数	 
#define IIC_Scl(a)   																GPIO_WriteBit(IIC_GPIO_PORT, IIC_SCL_PIN, a)
#define IIC_Sda(a)  																GPIO_WriteBit(IIC_GPIO_PORT, IIC_SDA_PIN, a)
#define READ_Sda   	  															GPIO_ReadInputDataBit(IIC_GPIO_PORT, IIC_SDA_PIN)

//IIC所有操作函数
void IIC_Init_S(uint32_t RCC_CLK);   												//初始化IIC的IO口				 
void IIC_Start(void);																			//发送IIC开始信号
void IIC_Stop(void);	  																	  //发送IIC停止信号
void IIC_Send_Byte(uint8_t txd);														//IIC发送一个字节
void IIC_Ack(void);																				//IIC发送ACK信号
void IIC_NAck(void);																			  //IIC不发送ACK信号										  
uint8_t  IIC_Wait_Ack(void); 															//IIC等待ACK信号
uint8_t  IIC_Read_B(uint8_t ack);													//IIC读取一个字节
uint32_t  IIC_Read_Byte(uint8_t ack,uint8_t* recvdata,uint8_t num);//IIC读取n个字节

#ifdef __cplusplus
}
#endif
#endif
  • iic.c
#include "iictest.h"
/*----------------------------------*/
/*									*/
/*			初始化IIC				*/
/*									*/
/*----------------------------------*/
void IIC_Init_S(uint32_t RCC_CLK)
{					     
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_AHB1PeriphClockCmd(	RCC_CLK, ENABLE );						
	   
	GPIO_InitStructure.GPIO_Pin = IIC_SDA_PIN|IIC_SCL_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
	GPIO_Init(IIC_GPIO_PORT, &GPIO_InitStructure);
	GPIO_SetBits(IIC_GPIO_PORT,IIC_SCL_PIN|IIC_SDA_PIN);
}

/*----------------------------------*/
/*									*/
/*	     产生IIC起始信号			*/
/*  								*/
/*----------------------------------*/
void IIC_Start(void)
{
	SDA_Out();
	IIC_Sda(1);	  	  
	IIC_Scl(1);
	Delay_us(4);
 	IIC_Sda(0);
	Delay_us(4);
	IIC_Scl(0);
}

/*----------------------------------*/
/*									*/
/*	    	产生IIC停止信号 		*/
/*									*/
/*----------------------------------*/
void IIC_Stop(void)
{
	SDA_Out();
	IIC_Scl(0);
	IIC_Sda(0);
 	Delay_us(4);
	IIC_Scl(1); 
	IIC_Sda(1);
	Delay_us(2);						   	
}

/*----------------------------------*/
/*									*/
/*	       等待应答					*/
/*	返回值	1:接收应答失败			*/
/*			0:接收应答成功			*/
/*----------------------------------*/
uint8_t IIC_Wait_Ack(void)
{
	uint8_t ucErrTime=0;
	SDA_In();      													
	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);
	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(1);
}

/*----------------------------------*/
/*									*/
/*			不产生ACK应答			*/
/*									*/
/*----------------------------------*/	    
void IIC_NAck(void)
{
	IIC_Scl(0);
	SDA_Out();							
  IIC_Sda(1);Delay_us(2);	
	IIC_Scl(1);Delay_us(2);
	IIC_Scl(1);
}		

/*----------------------------------*/
/*									*/
/*	 IIC发送一个字节			    */
/*	    @txd:	要发送的数据		*/
/*	    返回值:1,有应答			*/
/*		    	0,无应答			*/
/*----------------------------------*/		  
void IIC_Send_Byte(uint8_t txd)
{                        
		uint8_t t;   
		SDA_Out(); 	    												
		IIC_Scl(0);															
		for(t=0;t<8;t++)
		{              
			if((txd&0x80)>>7)									
				IIC_Sda(1);
			else
				IIC_Sda(0);
			txd<<=1; 	  											
			Delay_us(2);   														
			IIC_Scl(1);	
			Delay_us(2); 
			IIC_Scl(0);	
			Delay_us(2);
    }	 
} 	


/*----------------------------------*/
/*									*/
/*	IIC读取连续2个字节			        */
/*	    返回值:接收到的数据		*/
/*	    @ ack:	1
,需要应答			*/
/*				0,不需要应答		*/
/*----------------------------------*/		 
	
uint32_t  IIC_Read_Byte(uint8_t ack,uint8_t* recvdata,uint8_t num)
{
	uint32_t    data=0;
	while(num--)
	{
		*recvdata++ = IIC_Read_B(ack);
	}
	return  data;
}

uint8_t  IIC_Read_B(uint8_t ack)
{
	unsigned char i;
	uint8_t receive;
	SDA_In();								
	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();	
  else 
		IIC_Ack(); 	
									
  return receive;
}
  • SHT4.h
#ifndef 	__SHT1000_H
#define 	__SHT1000_H
#include   "delay.h"
#include   "iictest.h"

void SHT45_Init(void);
uint8_t SHT45_ReadPdata(uint8_t ack,uint8_t *arr,float* T,float* H );
extern uint32_t SHT45_Data1[2];
#endif

  • SHT4.c
#include	 "SHT1000.h"

uint32_t SHT45_Data1[2]={0};

void SHT45_Init(void)             //初始化IIC        PC6:SCL     PC7:SDA
{
	IIC_Init_S(RCC_AHB1Periph_GPIOC);
}

/* 读取压力数据寄存器*/ 
uint8_t SHT45_ReadPdata(uint8_t ack,uint8_t *arr,float* T,float* H )
{
	  int32_t CRC1=0XFF;
	  int32_t CRC2=0XFF;
	
		//开启温度转换
		IIC_Start();														
		IIC_Send_Byte (0x88);	//0x44 <<1 +0
		delay_us(2);
		while(IIC_Wait_Ack ()!=0){}; 
		IIC_Send_Byte (0xFD);
		while(IIC_Wait_Ack ()!=0){}; 
		IIC_Stop();
			
		delay_ms(10);
		//读取温度
		IIC_Start();
    IIC_Send_Byte (0x89);	//0x44 <<1 +1
		delay_us(2);
    while(IIC_Wait_Ack()!=0){}; 
    IIC_Read_Byte(ack,arr,6);
		IIC_Stop();
		SHT45_Data1[0] =arr[0]<<8|arr[1];
		*T = (-45 + 175*(SHT45_Data1[0])/65535.0);
    CRC1= arr[2];
		SHT45_Data1[1] =arr[3]<<8|arr[4];
		*H =(-6 + 125 *( SHT45_Data1[1])/65535.0);
		CRC2= arr[5];
    return 1;          
}
  • main.c
uint8_t arr[6]={0};
float T,H;	
int main(void)
{ 
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
	delay_init(168);    //初始化延时函数
	uart_init(115200);	//初始化串口波特率为115200
	
 	LED_Init();			//初始化LED 
	SHT45_Init();
	delay_us(2);
	
  	while(1)
	{
        delay_ms(1000);
        SHT45_ReadPdata(1,arr,&T,&H);
        printf("T:%f....H:%f\r\n",T,H);
	}		
}
  • 效果
    在这里插入图片描述
  • 17
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
ST官方并没有提供SHT40的标准库驱动,但是可以根据SHT40的通信协议自行编写驱动代码。以下是一份基于STM32标准库SHT40驱动代码,仅供参考: ```c #include "stm32f10x.h" #include "delay.h" #include "i2c.h" #include "sht40.h" #define SHT40_ADDRESS 0x44 void SHT40_Init(void) { I2C_Init(); } float SHT40_GetTemperature(void) { uint8_t txBuffer[2]; uint8_t rxBuffer[6]; txBuffer[0] = 0x24; txBuffer[1] = 0x00; I2C_Start(); I2C_SendByte(SHT40_ADDRESS << 1); if(I2C_WaitAck() != 0) { I2C_Stop(); return 0; } I2C_SendByte(txBuffer[0]); I2C_WaitAck(); I2C_SendByte(txBuffer[1]); I2C_WaitAck(); I2C_Stop(); delay_ms(10); I2C_Start(); I2C_SendByte(SHT40_ADDRESS << 1 | 0x01); if(I2C_WaitAck() != 0) { I2C_Stop(); return 0; } for(int i = 0; i < 5; i++) { rxBuffer[i] = I2C_RecvByte(); I2C_Ack(); } rxBuffer[5] = I2C_RecvByte(); I2C_NAck(); I2C_Stop(); uint16_t rawTemp = (rxBuffer[0] << 8) | rxBuffer[1]; float temp = -45 + 175 * ((float)rawTemp / (float)0xFFFF); return temp; } float SHT40_GetHumidity(void) { uint8_t txBuffer[2]; uint8_t rxBuffer[6]; txBuffer[0] = 0x24; txBuffer[1] = 0x00; I2C_Start(); I2C_SendByte(SHT40_ADDRESS << 1); if(I2C_WaitAck() != 0) { I2C_Stop(); return 0; } I2C_SendByte(txBuffer[0]); I2C_WaitAck(); I2C_SendByte(txBuffer[1]); I2C_WaitAck(); I2C_Stop(); delay_ms(10); I2C_Start(); I2C_SendByte(SHT40_ADDRESS << 1 | 0x01); if(I2C_WaitAck() != 0) { I2C_Stop(); return 0; } for(int i = 0; i < 5; i++) { rxBuffer[i] = I2C_RecvByte(); I2C_Ack(); } rxBuffer[5] = I2C_RecvByte(); I2C_NAck(); I2C_Stop(); uint16_t rawHumidity = (rxBuffer[3] << 8) | rxBuffer[4]; float humidity = 100 * ((float)rawHumidity / (float)0xFFFF); return humidity; } ``` 以上代码中,SHT40_Init函数用于初始化I2C接口,SHT40_GetTemperature函数用于获取度值,SHT40_GetHumidity函数用于获取湿度值。注意在使用之前需要先调用SHT40_Init函数初始化I2C接口。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值