历史上的今天
今天是:2025年10月13日(星期一)
2022年10月13日 | STM32F103ZE+SHT30检测环境温度与湿度(IIC模拟时序)
2022-10-13 来源:csdn
一、环境介绍
工程编译软件: keil5
温湿度传感器: SHT30
MCU : STM32F103ZET6
程序采用模块化编程,iic时序为一个模块(iic.c 和 iic.h),SHT30为一个模块(sht30.c 和 sht30.h);IIC时序采用模拟时序方式实现,IO口都采用宏定义方式,方便快速移植到其他平台使用。
工程源码完整下载地址: https://download.csdn.net/download/xiaolong1126626497/18973724
二、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("设备运行正常....rn");
IIC_Init();
Init_SHT30();
while(1)
{
//读取温湿度
SHT3x_ReadData(&Humidity,&Temperature);
USART1_Printf("温度:%0.2f,湿度:%0.2frn",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:1rn");
IIC_WriteOneByteData(0x30); //写数据
r_s=IIC_GetACK();//获取应答
if(r_s)printf("Init_SHT30_error:2rn");
IIC_WriteOneByteData(0xA2); //写数据
r_s=IIC_GetACK();//获取应答
if(r_s)printf("Init_SHT30_error:3rn");
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:1rn");
IIC_WriteOneByteData(0x22); //写数据
r_s=IIC_GetACK();//获取应答
if(r_s)printf("Init_SHT30_error:2rn");
IIC_WriteOneByteData(0x36); //写数据
r_s=IIC_GetACK();//获取应答
if(r_s)printf("Init_SHT30_error:3rn");
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:1rn");
IIC_WriteOneByteData(0xE0); //写数据
r_s=IIC_GetACK();//获取应答
if(r_s)printf("SHT3X_error:2rn");
IIC_WriteOneByteData(0x00); //写数据
r_s=IIC_GetACK();//获取应答
if(r_s)printf("SHT3X_error:3rn");
//IIC_Stop(); //停止信号
// DelayMs(30); //等待
//读取sht30传感器数据
IIC_Start(); //发送起始信号
IIC_WriteOneByteData(SHT30_AddrR);
r_s=IIC_GetACK();//获取应答
if(r_s)printf("SHT3X_error:7rn");
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:PB7
SCL: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; //时钟线拉高,告诉从机,主机数据发送完毕
史海拾趣
|
2007年9月1日,在南京召开的“2007中国软件产业发展暨企业创新高峰会”上传出信息,今年上半年全国软件产业实现销售收入2601亿元,增长23%,高于电子信息产业18%的增长水平,而其中嵌入式软件增长24%,高于软件产业的增长水平。同时据赛迪顾问研究 ...… 查看全部问答> |
|
请各位大侠们帮助,新装的WIN CE 5.0编译出现Invalid parameters passed to Wince.bat问题,怎么解决呀!急死人了,帮帮 小弟刚接触WIN CE ,刚装的WIN CE5.0安装后,新建工程编译出现Invalid parameters passed to Wince.bat问题,而且左边没有 OSDesign View标签.开始安装时因为有文件有2部分,WIN CE文件没有放在同一目录下,之后我将文件移动到了同一目录下,开始以 ...… 查看全部问答> |
|
在C-SPY,中设断点时, 总出现: Error[130]:"some breakpoint could not be set", 不论在那条语句上设都设不了。 ???????????????? 比其它51系列或者96系列的仿真器来说,C-SPY 的调试简直就是地狱!!!… 查看全部问答> |
|
本帖最后由 paulhyde 于 2014-9-15 03:48 编辑 ulink2 如何给arm板子供电啊?需要怎么设置啊 请问有人知道吗?求教啊 … 查看全部问答> |
|
关于LM3S8962的I2C读取honeywell传感器实验 honeywell新一代的传感器很多是I2C输出。 手头有两个气体流量传感器,于是想在EK-LM3S8962开发板上测试一下。 程序参考周立功的I2C读取LM75A例程,以及本版面的经验贴:https://bbs.eeworld.com.cn/viewthread.php?tid=231364 honeywell ...… 查看全部问答> |
|
codewarrior 在编译时提示警告信息如下:Warning : C1420: Result of function-call is ignored 哪位大哥告诉我一下这是什么意思,怎么解决? 芯片为MC9S08DZ60 [ 本帖最后由 kwq498901 于 2012-3-31 09:29 编辑 ]… 查看全部问答> |











