STM32F1 & SHT3x温湿度模块

7 篇文章 0 订阅
2 篇文章 0 订阅

STM32F1 & SHT3x温湿度模块

提示:以下程序是基于STM32F103和SHT3x系列硬件



一、STM32CubeMX工程配置

说明:本例程采用模拟IIC,所以需要把相应IO配置为推完输出,默认为高电平
在这里插入图片描述

二、程序&说明

1.模拟IIC程序

myiic.c

#include "myiic.h"
#include "delay.h"

//产生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,接收应答成功
uint8_t IIC_Wait_Ack(void)
{
	uint8_t 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(uint8_t txd)
{                        
	uint8_t 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   
uint8_t 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;
}

myiic.h

#ifndef _MYIIC_H
#define _MYIIC_H

#include "delay.h"
#include "main.h"

//IO方向设置
#define SDA_IN()  {GPIOB->CRH&=0XFFFFFFF0;GPIOB->CRH|=(uint32_t)8<<0;}	//PB7输入模式
#define SDA_OUT() {GPIOB->CRH&=0XFFFFFFF0;GPIOB->CRH|=(uint32_t)3<<0;} 	//PB7输出模式

//IO操作
#define IIC_SCL(n)  (n ? HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_SET) : HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_RESET)) //SCL
#define IIC_SDA(n)  (n ? HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_SET) : HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_RESET)) //SDA
#define READ_SDA    HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_8)					//输入SDA

//IIC所有操作函数
void IIC_Init(void);                //初始化IIC的IO口(无需调用)				 
void IIC_Start(void);				//发送IIC开始信号
void IIC_Stop(void);	  			//发送IIC停止信号
void IIC_Send_Byte(uint8_t txd);			//IIC发送一个字节
uint8_t IIC_Read_Byte(unsigned char ack);//IIC读取一个字节
uint8_t IIC_Wait_Ack(void); 				//IIC等待ACK信号
void IIC_Ack(void);					//IIC发送ACK信号
void IIC_NAck(void);				//IIC不发送ACK信号

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

以上底层是基于STM32F103,若要使用在STM32其他系列上请自行移植
提示:需要修改delay.hdelay.c文件,注意时序,并且更改myiic.h中的引脚配置,如下图(注::F4和F1的IO方向设置寄存器不一样,请自行查看数据手册进行修改)
在这里插入图片描述

2,SHT3x底层

sht3x.c

#include "sht3x.h"
#include "myiic.h"

_TW data_process;  //定义温湿度结构体

static void SHT3x_WriteCommand(uint16_t COMMAND);	//SHT30命令写入

void SHT3x_Init(void)		//SHT30初始化
{
	IIC_Start();
	IIC_Send_Byte(SHTx_Device_ADDR << 1 | Write_DATA);	//写入地址和写命令
	SHT3x_WriteCommand(PERI_HIGH_1_CMD);								//设置为周期读取频率为1hz
	IIC_Stop();
}

static void SHT3x_WriteCommand(uint16_t COMMAND)	//SHT30命令写入
{
	IIC_Wait_Ack();
	IIC_Send_Byte(COMMAND >> 8);		//传输高8位
	IIC_Wait_Ack();
	IIC_Send_Byte(COMMAND & 0xFF);	//传输低8位
	IIC_Wait_Ack();
}

void SHT3x_READ_TEMP_Humi(uint16_t *dat)	//SHT3x读取数据
{
	IIC_Start();
	IIC_Send_Byte(SHTx_Device_ADDR << 1 | Write_DATA); //写入地址和写命令
	SHT3x_WriteCommand(READOUT_FOR_PERIODIC_MODE);		 //读取周期测量寄存器中的值
	
	//下面是开始读取数据,其中的指针dat存放结果,前三个存放温度值,后三个是湿度值,在前三个温度值里面,
	//dat[0]是温度的高八位,dat[1]是低八位,dat[2]是CRC校验
   
	IIC_Start();
	IIC_Send_Byte(SHTx_Device_ADDR << 1 | Read_DATA);	//写入地址和读命令
	IIC_Wait_Ack();

	//前五次读取都要发送ack信号,最后一次就不用发了。
	dat[0] = IIC_Read_Byte(1);	//温度的高八位
	dat[1] = IIC_Read_Byte(1);	//温度的低八位
	dat[2] = IIC_Read_Byte(1);	//温度的CRC位
	
	dat[3] = IIC_Read_Byte(1);	//湿度的高八位
	dat[4] = IIC_Read_Byte(1);	//湿度的低八位
	dat[5] = IIC_Read_Byte(0);	//湿度的CRC位
	IIC_Stop();
}

/*	
	CRC校验函数(是确保通信过程中数据传输没问题的,没有缺少任何数据,
	当我们接收到数据后,按照一定的方式计算一个crc校验码,
	经过和提供的crc校验码进行比较,如果两个码一样,那么数据就是没问题的。)
*/
int CRC8_Compute(uint8_t *check_data, uint8_t num_of_data)
{
	uint8_t bit;        // bit mask
	uint8_t crc = 0xFF; // calculated checksum
	uint8_t byteCtr;    // byte counter

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

int SHT3x_CRC8_Check(uint8_t *p,uint8_t num_of_data,uint8_t CrcData)
{
  uint8_t crc;
  crc = CRC8_Compute(p, num_of_data);// calculates 8-Bit checksum
 if(crc != CrcData) 
 {   
     return 1;           
 }
 return 0;
}

uint8_t SHT3x_Data_Process(void)	//温湿度测量函数
{
	uint8_t temporary[3];
  uint16_t data;
  uint8_t crc_result;
  
  SHT3x_READ_TEMP_Humi(data_process.sht30_data_buffer);
  //先处理温度的相关数据,位于数组的前三个
  temporary[0]=data_process.sht30_data_buffer[0];
  temporary[1]=data_process.sht30_data_buffer[1];
  temporary[2]=data_process.sht30_data_buffer[2];
  //crc校验
  crc_result=SHT3x_CRC8_Check(temporary,2,temporary[2]);
  //crc校验要是不成功就返回1,同时不会更新温度值
  if(crc_result==0)
  {
		//把2个8位数据拼接为一个16位的数据
		data=((uint16_t)temporary[0] << 8) | temporary[1];
		//温度转换,将16位温度数据转化为10进制的温度数据,这里保留了一位小数,data_process.SHT30_temperature这是一个全局变量
		data_process.SHT30_temperature = ((175.0f * ((float)data) / 65535.0f - 45.0f) *1.0f);
  }
  else
  {
		return 1;
  }
  temporary[0]=data_process.sht30_data_buffer[3];
  temporary[1]=data_process.sht30_data_buffer[4];
  temporary[2]=data_process.sht30_data_buffer[5];
  //crc校验
  crc_result=SHT3x_CRC8_Check(temporary,2,temporary[2]);
  if(crc_result==0)
  {
		//参考上面温度的代码
		data=((uint16_t)temporary[0] << 8) | temporary[1];
		//湿度转换,将16位温度数据转化为10进制的温度数据,这里保留了一位小数,data_process.SHT30_temperature这是一个全局变量
		data_process.SHT30_humidity = ((100.0f * (float)data / 65535.0f) *1.0f); 
		return 0;
  }
  else
  {
		return 2;
  }
}

sht3x.h

#ifndef __SHT3x_H
#define __SHT3x_H 			   

#include "stm32f1xx_hal.h"
#include "myiic.h"
#include "usart.h"

typedef enum{
	
	SHTx_Device_ADDR		=	0x44,		//设备地址
	Write_DATA 					= 0x00,		//写数据/命令
	Read_DATA 					= 0x01,		//读数据/命令

	SOFT_RESET_CMD = 0x30A2,			//软件复位命令
	
	/* 单次测量模式 */
	CLOCK_HIGH_ENABLED_CMD    = 0x2C06,
	CLOCK_MEDIUM_ENABLED_CMD  = 0x2C0D,
	CLOCK_LOW_ENABLED_CMD     = 0x2C10,
	CLOCK_HIGH_DISABLED_CMD   = 0x2400,
	CLOCK_MEDIUM_DISABLED_CMD = 0x240B,
	CLOCK_LOW_DISABLED_CMD    = 0x2416,

	/* 周期测量模式	*/
	PERI_HIGH_0_5_CMD   	= 0x2032,
	PERI_MEDIUM_0_5_CMD 	= 0x2024,
	PERI_LOW_0_5_CMD    	= 0x202F,
	
	PERI_HIGH_1_CMD     	= 0x2130,
	PERI_MEDIUM_1_CMD   	= 0x2126,
	PERI_LOW_1_CMD      	= 0x212D,		//1s测量一次(1Hz)
	
	PERI_HIGH_2_CMD     	= 0x2236,
	PERI_MEDIUM_2_CMD   	= 0x2220,
	PERI_LOW_2_CMD      	= 0x222B,
	
	PERI_HIGH_4_CMD     	= 0x2334,
	PERI_MEDIUM_4_CMD   	= 0x2322,
	PERI_LOW_4_CMD      	= 0x2329,
	
	PERI_HIGH_10_CMD    	= 0x2737,
	PERI_MEDIUM_10_CMD  	= 0x2721,
	PERI_LOW_10_CMD     	= 0x272A,	//1s测量10次(10Hz)
	
	HEATER_ENABLED_CMD		= 0x306D,	//加热器使能
	HEATER_DISABLED_CMD		= 0x3066,	//加热器失能
	
	READ_STATUS_CMD				= 0xF32D,	//读取状态寄存器
	CLEAR_STATUS_CMD			= 0x3041,	//清除状态寄存器

	READOUT_FOR_PERIODIC_MODE = 0xE000,	// 周期测量模式读取数据命令
}SHT30_CMD;

typedef struct
{
	unsigned short int sht30_data_buffer[6];
	float SHT30_temperature;	//温度
	float SHT30_humidity;			//湿度
	
}_TW;

extern _TW data_process;  //定义温湿度结构体

void SHT3x_Init(void);										//SHT30初始化
void SHT3x_READ_TEMP_Humi(uint16_t *dat);	//写一个命令给SHT30,并读取数据
uint8_t SHT3x_Data_Process(void);					//温湿度测量函数

// CRC校验函数
int  CRC8_Compute(uint8_t *check_data, uint8_t num_of_data);
int SHT3x_CRC8_Check(uint8_t *p,uint8_t num_of_data,uint8_t CrcData);

#endif 

3,使用说明

  • 调用SHT3x_Init初始化函数
  • 周期调用SHT3x_Data_Process数据测量函数
  • 所需数据在结构体data_process
  • 5
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: STM32F1 SHT30参考例程是一段用于基于STM32F1系列微控制器驱动SHT30温湿度传感器的示例代码。这个例程旨在帮助开发人员快速理解和使用SHT30传感器,并为他们提供一个起点来集成传感器到其STM32F1项目中。 这个参考例程通常包括以下内容: 1. 引入必要的头文件:例程通常会引入一些必要的头文件,以获得对STM32F1系列微控制器和SHT30传感器的访问权限。 2. 初始化操作:例程会包含一段代码用于初始化STM32F1和SHT30传感器,包括配置管脚、串口或I2C总线等。 3. 读取传感器数据:代码示例通常会展示如何通过STM32F1从SHT30读取温度和湿度数据,并将其保存到适当的变量中。 4. 数据处理和显示:例程还可能包括一些数据处理和显示的代码,用于对传感器数据进行处理,计算或显示,例如在显示屏上或通过串口输出。 5. 错误处理:参考示例代码通常会包含一些错误处理的代码,以处理在访问SHT30传感器时可能发生的错误或异常情况。 需要注意的是,SHT30传感器的具体规格和功能可能会因厂商和芯片型号的不同而有所差异。因此,不同厂商的SHT30传感器可能需要略微不同的例程。开发人员在使用参考例程时应注意相关文档和参考资料,以确保正确地集成SHT30传感器到他们的STM32F1项目中。 总的来说,STM32F1 SHT30参考例程是一段提供给开发人员的示例代码,用于帮助他们理解和使用SHT30传感器,以及将其集成到STM32F1项目中。 ### 回答2: STM32F1系列是意法半导体(STMicroelectronics)推出的一款32位微控制器,提供了广泛的功能和性能。而SHT30是一种数字温湿度传感器,具有高精度和可靠性。在使用STM32F1与SHT30配合时,可以利用STM32F1的参考例程来简化开发过程。 参考例程是由STMicroelectronics官方提供的示例代码,用于快速入门和学习如何使用STM32F1与SHT30进行通信和数据获取。这些例程通常包含以下几个主要方面: 1. 引脚配置:根据具体的STM32F1开发板硬件连接情况,配置相应的引脚,确保STM32F1与SHT30正确连接。 2. 寄存器配置:针对STM32F1的特性,对相关的寄存器进行配置,确保与SHT30的通信和数据读取正常进行。 3. I2C通信设置:SHT30是通过I2C总线与STM32F1进行通信的,参考例程会包括相关的I2C通信初始化和配置,确保可以正常建立通信连接。 4. 数据读取与处理:通过对SHT30的寄存器操作,可以获取其测得的温度和湿度数据。参考例程会提供相应的代码,用于读取和处理SHT30传感器发送的原始数据,将其转化为可用的温湿度数值。 5. 错误处理与调试:参考例程还会包含错误处理和调试信息的相关代码,用于检测可能出现的错误,并提供相应的解决方案。 通过使用STM32F1与SHT30的参考例程,开发者可以快速入门并了解如何进行基于STM32F1的温湿度传感器应用开发。同时,可以根据实际需求进行相应的修改和扩展,以满足特定项目的要求。总的来说,参考例程为开发者提供了一个快速上手和学习的起点,有助于加快开发进度,提高开发效率。 ### 回答3: STM32F1系列微控制器是一款性能稳定、功能丰富的芯片,适用于各种应用场景。SHT30是一款数字湿度和温度传感器,具有高精度和快速响应的特点。对于STM32F1集成SHT30的参考例程可以具体如下进行设计。 首先,需要设置STM32F1的GPIO引脚来与SHT30进行通信。可以选择两个GPIO引脚分别作为SHT30的数据线和时钟线。 其次,需要编写初始化函数来配置GPIO引脚和I2C总线相关的寄存器。这样可以保证STM32F1与SHT30之间的正常通信。 然后,需要编写读写函数来实现与SHT30的数据交换。可以利用STM32F1的I2C模块来与SHT30进行通信。通过I2C总线发送指令给SHT30,如读取湿度值、温度值等,然后将返回的数据保存在变量中。 接下来,可以编写一个主函数来调用上述的初始化函数和读写函数。通过调用读写函数可以获取SHT30传感器的湿度和温度值,并通过串口或者其他方式将这些数据输出。 最后,为了保证传感器的稳定和可靠性,需要进行数据处理和错误处理。可以对从SHT30读取的湿度和温度值进行转换和校验,保证数据的准确性。同时,在遇到异常情况时,需要进行相应的错误处理,比如重新初始化传感器或者报错提示。 总结而言,STM32F1与SHT30的参考例程需要包括初始化函数、读写函数、主函数以及数据处理和错误处理。通过编写这些函数,可以实现STM32F1与SHT30的正常通信和数据获取,从而在实际应用中得到湿度和温度的准确信息。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值