当前位置:网站首页>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;}边栏推荐
- SQL where multiple field filtering
- Deeply cultivate the developer ecosystem, accelerate the innovation and development of AI industry, and Intel brings many partners together
- Digital chemical plants realize the coexistence of advantages of high quality, low cost and fast efficiency
- How to open win11 remote desktop connection? Five methods of win11 Remote Desktop Connection
- 树与图的深度优先遍历模版原理
- 全国气象数据/降雨量分布数据/太阳辐射数据/NPP净初级生产力数据/植被覆盖度数据
- AI表现越差,获得奖金越高?纽约大学博士拿出百万重金,悬赏让大模型表现差劲的任务
- Some understandings about 01 backpacker
- 计数排序基础思路
- Programmers go to work fishing, so play high-end!
猜你喜欢

AI landing new question type RPA + AI =?

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

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

九章云极DataCanvas公司摘获「第五届数字金融创新大赛」最高荣誉!

mpf2_线性规划_CAPM_sharpe_Arbitrage Pricin_Inversion Gauss Jordan_Statsmodel_Pulp_pLU_Cholesky_QR_Jacobi

Lessons and thoughts of the first SQL injection

Network Security Learning - Information Collection

Depth first traversal template principle of tree and graph

Analyse approfondie de kubebuilder

In depth analysis of kubebuilder
随机推荐
Station B boss used my world to create convolutional neural network, Lecun forwarding! Burst the liver for 6 months, playing more than one million
If you ask me about R code debugging, I will tell you head, STR, help
Deeply cultivate the developer ecosystem, accelerate the innovation and development of AI industry, and Intel brings many partners together
R descriptive statistics and hypothesis testing
GPT-3当一作自己研究自己,已投稿,在线蹲一个同行评议
Programmers go to work fishing, so play high-end!
MySQL split method usage
sscanf,sscanf_ S and its related usage "suggested collection"
jvm是什么?jvm调优有哪些目的?
Common Oracle SQL statements
leetcode 53. Maximum subarray maximum subarray sum (medium)
mpf2_线性规划_CAPM_sharpe_Arbitrage Pricin_Inversion Gauss Jordan_Statsmodel_Pulp_pLU_Cholesky_QR_Jacobi
acwing 843. n-皇后问题
Basic idea of counting and sorting
Kivy tutorial of setting the size and background of the form (tutorial includes source code)
The root file system of buildreoot prompts "depmod:applt not found"
Two methods of chromosome coordinate sequencing
Field data acquisition and edge calculation scheme of CNC machine tools
Section 1: (3) logic chip process substrate selection
赠票速抢|行业大咖纵论软件的质量与效能 QECon大会来啦