当前位置:网站首页>STM32F103ZE+SHT30检测环境温度与湿度(IIC模拟时序)

STM32F103ZE+SHT30检测环境温度与湿度(IIC模拟时序)

2022-07-06 22:23:00 华为云

一、环境介绍

工程编译软件: keil5

温湿度传感器: SHT30

MCU : STM32F103ZET6

程序采用模块化编程,iic时序为一个模块(iic.c 和 iic.h),SHT30为一个模块(sht30.c 和 sht30.h);IIC时序采用模拟时序方式实现,IO口都采用宏定义方式,方便快速移植到其他平台使用。

二、SHT30介绍

image.png
image.png

特点:

\1. 湿度和温度传感器
\2. 完全校准、线性化和温度
\3. 补偿数字输出,宽电源电压范围,从2.4 V到5.5 V
\4. I2C接口,通信速度高达1MHz和两个用户可选地址
\5. 典型精度 ± 2%相对湿度和± 0.3°C
\6. 启动和测量时间非常快
\7. 微型8针DFN封装
image.png
image.png

这是SHT30的7位IIC设备地址:
image.png

三、设备运行效果

这是串口打印的数据:
image.png
image.png
image.png

四、设备代码

4.1 main.c

#include "stm32f10x.h"#include "led.h"#include "delay.h"#include "key.h"#include "usart.h"#include "iic.h"#include "sht3x.h"int main(){   float Humidity;   float Temperature;   USART1_Init(115200);   USART1_Printf("设备运行正常....\r\n");   IIC_Init();    Init_SHT30();   while(1)   {       //读取温湿度       SHT3x_ReadData(&Humidity,&Temperature);       USART1_Printf("温度:%0.2f,湿度:%0.2f\r\n",Temperature,Humidity);       delay_ms(1000);   }}

4.2 sht30.c

#include "sht3x.h"const int16_t POLYNOMIAL = 0x131;/**************************************************************** 函数名称: SHT30_reset* 说 明: SHT30复位* 参 数: 无* 返 回 值: 无***************************************************************/void SHT30_reset(void){    u8 r_s;        IIC_Start(); //发送起始信号        IIC_WriteOneByteData(SHT30_AddrW); //写设备地址    r_s=IIC_GetACK();//获取应答    if(r_s)printf("Init_SHT30_error:1\r\n");    IIC_WriteOneByteData(0x30); //写数据    r_s=IIC_GetACK();//获取应答    if(r_s)printf("Init_SHT30_error:2\r\n");        IIC_WriteOneByteData(0xA2); //写数据    r_s=IIC_GetACK();//获取应答    if(r_s)printf("Init_SHT30_error:3\r\n");        IIC_Stop(); //停止信号     delay_ms(50);    }/**************************************************************** 函数名称: Init_SHT30* 说 明: 初始化SHT30,设置测量周期* 参 数: 无* 返 回 值: 无***************************************************************/void Init_SHT30(void){     u8 r_s;        IIC_Start(); //发送起始信号        IIC_WriteOneByteData(SHT30_AddrW); //写设备地址    r_s=IIC_GetACK();//获取应答    if(r_s)printf("Init_SHT30_error:1\r\n");    IIC_WriteOneByteData(0x22); //写数据    r_s=IIC_GetACK();//获取应答    if(r_s)printf("Init_SHT30_error:2\r\n");        IIC_WriteOneByteData(0x36); //写数据    r_s=IIC_GetACK();//获取应答    if(r_s)printf("Init_SHT30_error:3\r\n");        IIC_Stop(); //停止信号         delay_ms(200);}/**************************************************************** 函数名称: SHT3x_CheckCrc* 说 明: 检查数据正确性* 参 数: data:读取到的数据 nbrOfBytes:需要校验的数量 checksum:读取到的校对比验值* 返 回 值: 校验结果,0-成功 1-失败***************************************************************/u8 SHT3x_CheckCrc(char data[], char nbrOfBytes, char checksum){	    char crc = 0xFF;    char bit = 0;    char byteCtr ;	    //calculates 8-Bit checksum with given polynomial    for(byteCtr = 0; byteCtr < nbrOfBytes; ++byteCtr)    {        crc ^= (data[byteCtr]);        for ( bit = 8; bit > 0; --bit)        {            if (crc & 0x80) crc = (crc << 1) ^ POLYNOMIAL;            else crc = (crc << 1);        }    }	    if(crc != checksum)		return 1;    else		return 0;	}/**************************************************************** 函数名称: SHT3x_CalcTemperatureC* 说 明: 温度计算* 参 数: u16sT:读取到的温度原始数据* 返 回 值: 计算后的温度数据***************************************************************/float SHT3x_CalcTemperatureC(unsigned short u16sT){	    float temperatureC = 0;            // variable for result    u16sT &= ~0x0003;           // clear bits [1..0] (status bits)    //-- calculate temperature [℃] --    temperatureC = (175 * (float)u16sT / 65535 - 45); //T = -45 + 175 * rawValue / (2^16-1)	    return temperatureC;	}/**************************************************************** 函数名称: SHT3x_CalcRH* 说 明: 湿度计算* 参 数: u16sRH:读取到的湿度原始数据* 返 回 值: 计算后的湿度数据***************************************************************/float SHT3x_CalcRH(unsigned short u16sRH){	    float humidityRH = 0;              // variable for result	    u16sRH &= ~0x0003;          // clear bits [1..0] (status bits)    //-- calculate relative humidity [%RH] --    humidityRH = (100 * (float)u16sRH / 65535);  // RH = rawValue / (2^16-1) * 10	    return humidityRH;	}//读取温湿度数据void SHT3x_ReadData(float *Humidity,float *Temperature){    char  data[3];    //data array for checksum verification    u8 SHT3X_Data_Buffer[6]; 																		//byte 0,1 is temperature byte 4,5 is humidity    u8 r_s=0;    u8 i;    unsigned short tmp = 0;    uint16_t dat;        IIC_Start(); //发送起始信号        IIC_WriteOneByteData(SHT30_AddrW); //写设备地址    r_s=IIC_GetACK();//获取应答    if(r_s)printf("SHT3X_error:1\r\n");    IIC_WriteOneByteData(0xE0); //写数据    r_s=IIC_GetACK();//获取应答    if(r_s)printf("SHT3X_error:2\r\n");        IIC_WriteOneByteData(0x00); //写数据    r_s=IIC_GetACK();//获取应答    if(r_s)printf("SHT3X_error:3\r\n");        //IIC_Stop(); //停止信号        // DelayMs(30); //等待        //读取sht30传感器数据    IIC_Start(); //发送起始信号    IIC_WriteOneByteData(SHT30_AddrR);    r_s=IIC_GetACK();//获取应答    if(r_s)printf("SHT3X_error:7\r\n");        for(i=0;i<6;i++)    {        SHT3X_Data_Buffer[i]=IIC_ReadOneByteData(); //接收数据        if(i==5)        {             IIC_SendACK(1); //发送非应答信号            break;        }        IIC_SendACK(0); //发送应答信号    }    IIC_Stop(); //停止信号        // /* check tem */    data[0] = SHT3X_Data_Buffer[0];    data[1] = SHT3X_Data_Buffer[1];    data[2] = SHT3X_Data_Buffer[2];    tmp=SHT3x_CheckCrc(data, 2, data[2]);    if( !tmp ) /* value is ture */    {        dat = ((uint16_t)data[0] << 8) | data[1];        *Temperature = SHT3x_CalcTemperatureC( dat );        }    // /* check humidity */    data[0] = SHT3X_Data_Buffer[3];    data[1] = SHT3X_Data_Buffer[4];    data[2] = SHT3X_Data_Buffer[5];    tmp=SHT3x_CheckCrc(data, 2, data[2]);    if( !tmp ) /* value is ture */    {        dat = ((uint16_t)data[0] << 8) | data[1];        *Humidity = SHT3x_CalcRH( dat );        }}

4.3 iic.c

#include "iic.h"/*函数功能:IIC接口初始化硬件连接:SDA:PB7SCL:PB6*/void IIC_Init(void){	RCC->APB2ENR|=1<<3;//PB	GPIOB->CRL&=0x00FFFFFF;	GPIOB->CRL|=0x33000000;	GPIOB->ODR|=0x3<<6;}/*函数功能:IIC总线起始信号*/void IIC_Start(void){    IIC_SDA_OUTMODE(); //初始化SDA为输出模式    IIC_SDA_OUT=1; 		 //数据线拉高    IIC_SCL=1;     		 //时钟线拉高    DelayUs(4);        //电平保持时间    IIC_SDA_OUT=0; 		 //数据线拉低    DelayUs(4);        //电平保持时间    IIC_SCL=0;     		 //时钟线拉低}/*函数功能:IIC总线停止信号*/void IIC_Stop(void){		IIC_SDA_OUTMODE(); //初始化SDA为输出模式		IIC_SDA_OUT=0; 		 //数据线拉低		IIC_SCL=0;     		 //时钟线拉低		DelayUs(4);        //电平保持时间		IIC_SCL=1;     		 //时钟线拉高		DelayUs(4);        //电平保持时间		IIC_SDA_OUT=1; 		 //数据线拉高}/*函数功能:获取应答信号返 回 值:1表示失败,0表示成功*/u8 IIC_GetACK(void){		u8 cnt=0;		IIC_SDA_INPUTMODE();//初始化SDA为输入模式		IIC_SDA_OUT=1; 		  //数据线上拉	  DelayUs(2);         //电平保持时间		IIC_SCL=0;     		  //时钟线拉低,告诉从机,主机需要数据		DelayUs(2);         //电平保持时间,等待从机发送数据	  IIC_SCL=1;     		  //时钟线拉高,告诉从机,主机现在开始读取数据		while(IIC_SDA_IN)   //等待从机应答信号		{				cnt++;				if(cnt>250)return 1;		}		IIC_SCL=0;     		  //时钟线拉低,告诉从机,主机需要数据		return 0;}/*函数功能:主机向从机发送应答信号函数形参:0表示应答,1表示非应答*/void IIC_SendACK(u8 stat){		IIC_SDA_OUTMODE(); //初始化SDA为输出模式		IIC_SCL=0;     		 //时钟线拉低,告诉从机,主机需要发送数据		if(stat)IIC_SDA_OUT=1; //数据线拉高,发送非应答信号		else IIC_SDA_OUT=0; 	 //数据线拉低,发送应答信号		DelayUs(2);            //电平保持时间,等待时钟线稳定		IIC_SCL=1;     		     //时钟线拉高,告诉从机,主机数据发送完毕		DelayUs(2);            //电平保持时间,等待从机接收数据		IIC_SCL=0;     		  	 //时钟线拉低,告诉从机,主机需要数据}/*函数功能:IIC发送1个字节数据函数形参:将要发送的数据*/void IIC_WriteOneByteData(u8 data){		u8 i;		IIC_SDA_OUTMODE(); //初始化SDA为输出模式		IIC_SCL=0;     		 //时钟线拉低,告诉从机,主机需要发送数据		for(i=0;i<8;i++)		{				if(data&0x80)IIC_SDA_OUT=1; //数据线拉高,发送1				else IIC_SDA_OUT=0; 	 //数据线拉低,发送0				IIC_SCL=1;     		     //时钟线拉高,告诉从机,主机数据发送完毕				DelayUs(2);            //电平保持时间,等待从机接收数据				IIC_SCL=0;     		 		 //时钟线拉低,告诉从机,主机需要发送数据				DelayUs(2);            //电平保持时间,等待时钟线稳定				data<<=1;              //先发高位		}}/*函数功能:IIC接收1个字节数据返 回 值:收到的数据*/u8 IIC_ReadOneByteData(void){		u8 i,data;		IIC_SDA_INPUTMODE();//初始化SDA为输入模式	  for(i=0;i<8;i++)	  {			 	IIC_SCL=0;     		  //时钟线拉低,告诉从机,主机需要数据				DelayUs(2);         //电平保持时间,等待从机发送数据				IIC_SCL=1;     		  //时钟线拉高,告诉从机,主机现在正在读取数据				data<<=1;           				if(IIC_SDA_IN)data|=0x01;				DelayUs(2);         //电平保持时间,等待时钟线稳定	  }		IIC_SCL=0;     		  		//时钟线拉低,告诉从机,主机需要数据 (必须拉低,否则将会识别为停止信号)		return data;}
原网站

版权声明
本文为[华为云]所创,转载请带上原文链接,感谢
https://bbs.huaweicloud.com/blogs/363916