当前位置:网站首页>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介绍


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

这是SHT30的7位IIC设备地址:
三、设备运行效果
这是串口打印的数据:


四、设备代码
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;}边栏推荐
- Analyse approfondie de kubebuilder
- Depth first traversal template principle of tree and graph
- How to conduct website testing of software testing? Test strategy let's go!
- Can I specify a path in an attribute to map a property in my class to a child property in my JSON?
- mpf2_线性规划_CAPM_sharpe_Arbitrage Pricin_Inversion Gauss Jordan_Statsmodel_Pulp_pLU_Cholesky_QR_Jacobi
- Flex layout and usage
- What is JVM? What are the purposes of JVM tuning?
- 5G VoNR+之IMS Data Channel概念
- System framework of PureMVC
- Meow, come, come: do you really know if, if else
猜你喜欢

Read of shell internal value command

Break the memory wall with CPU scheme? Learn from PayPal to expand the capacity of aoteng, and the volume of missed fraud transactions can be reduced to 1/30

Depth first traversal template principle of tree and graph

Chapter 9 Yunji datacanvas was rated as 36 krypton "the hard core technology enterprise most concerned by investors"

Network Security Learning - Information Collection

acwing 843. N-queen problem

C # use Siemens S7 protocol to read and write PLC DB block

Field data acquisition and edge calculation scheme of CNC machine tools
![[hand torn STL] list](/img/aa/7060ab20b41936419041067cf9daed.jpg)
[hand torn STL] list

Programmers go to work fishing, so play high-end!
随机推荐
acwing 843. N-queen problem
架构实战训练营|课后作业|模块 6
Jetson nano配置pytorch深度学习环境//待完善
leetcode 53. Maximum Subarray 最大子数组和(中等)
Deeply cultivate the developer ecosystem, accelerate the innovation and development of AI industry, and Intel brings many partners together
acwing 843. n-皇后问题
The root file system of buildreoot prompts "depmod:applt not found"
On the 110th anniversary of Turing's birth, has the prediction of intelligent machine come true?
程序员上班摸鱼,这么玩才高端!
Read of shell internal value command
R language principal component PCA, factor analysis, clustering analysis of regional economy analysis of Chongqing Economic Indicators
The worse the AI performance, the higher the bonus? Doctor of New York University offered a reward for the task of making the big model perform poorly
Factor analysis r practice (with R installation tutorial and code)
Flex layout and usage
广告归因:买量如何做价值衡量?
ESG Global Leaders Summit | Intel Wang Rui: coping with global climate challenges with the power of science and technology
Run the command once per second in Bash- Run command every second in Bash?
[practice leads to truth] is the introduction of import and require really the same as what is said on the Internet
软件测试之网站测试如何进行?测试小攻略走起!
AI表现越差,获得奖金越高?纽约大学博士拿出百万重金,悬赏让大模型表现差劲的任务