STM32F103ZE+SHT30检测环境温度与湿度(IIC模拟时序)
一、环境介绍
工程编译软件: 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("设备运行正常....\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 polynomialfor(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;elsereturn 0;}/***************************************************************
* 函数名称: SHT3x_CalcTemperatureC
* 说 明: 温度计算
* 参 数: u16sT:读取到的温度原始数据
* 返 回 值: 计算后的温度数据
***************************************************************/
float SHT3x_CalcTemperatureC(unsigned short u16sT)
{float temperatureC = 0; // variable for resultu16sT &= ~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 resultu16sRH &= ~0x0003; // clear bits [1..0] (status bits)//-- calculate relative humidity [%RH] --humidityRH = (100 * (float)u16sRH / 65535); // RH = rawValue / (2^16-1) * 10return humidityRH;}//读取温湿度数据
void SHT3x_ReadData(float *Humidity,float *Temperature)
{char data[3]; //data array for checksum verificationu8 SHT3X_Data_Buffer[6]; //byte 0,1 is temperature byte 4,5 is humidityu8 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:PB7
SCL:PB6
*/
void IIC_Init(void)
{RCC->APB2ENR|=1<<3;//PBGPIOB->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; //数据线拉高,发送1else IIC_SDA_OUT=0; //数据线拉低,发送0IIC_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;
}
STM32F103ZE+SHT30检测环境温度与湿度(IIC模拟时序)相关推荐
- 基于51单片机+SHT30设计的环境温度与湿度检测设备(IIC模拟时序)
一.项目介绍 当前文章介绍基于51单片机和SHT30传感器设计的环境温度与湿度检测设备.设备采用IIC模拟时序通信协议,能够实时监测环境的温度和湿度,并将数据通过LCD显示屏显示出来:可以广泛应用于室 ...
- STM32L431(CubeMX)使用DHT11读取环境温度与湿度并通过串口打印
STM32L431CubeMX使用DHT11读取环境温度与湿度并通过串口打印 一.开发平台 软件下载 1.keil5 2.CubeMx 二.DHT11介绍 三.新建工程步骤 1.CubeMx 2.Ke ...
- Arduino实验十 利用土壤湿度传感器检测西瓜皮湿度
学习任务: 利用土壤湿度传感器检测西瓜皮湿度 组件: Arduion主板 土壤湿度传感器 I2CLCD1602液晶显示器 面包板 杜邦线 USB数据线 下图是土壤湿度传感器 实验步骤: 1.建立电路 ...
- IIC模拟协议华大单片机移植
IIC模拟协议华大单片机移植 本文所用为 HC32L136K8TA 使用Gpio10== SDA GpioC11==SCL 先把关键性 宏定义说明 //引脚声明 #define SCL_PORT Gp ...
- QN8027 IIC 模拟接口C语言
IIC C语言实现 参考原子哥iic代码 时序图 #include "iic.h"void IIC_Init(void) { USER_GPIO->DATA_OUT |= ( ...
- MAX31855电路和程序,实现SPI和软件模拟时序两种方式读取数据
1. 概述 MAX31855为热电偶至数字输出转换器,内置14位模/数转换器(ADC).器件带有冷端补偿检测和修正.数字控制器.SPI兼容接口,以及相关的控制逻辑,在温度控制器.过程控制或监测系统中设 ...
- 关于IO模拟时序(SPI)的注意事项
原则:有硬件I2C.SPI时尽量用硬件操作,省去IO模拟繁琐的时序调试.但在内部资源不够时就要用IO模拟总线了. 关于短延时:模拟时序时是否需要延时要看MCU与device的相对速度.比如I2C如果4 ...
- 三星K9F1G08U0E(128MB,NAND FLASH) STM32平台驱动程序(模拟时序)
STM32平台下模拟时序驱动K9F1G08U0E,主要目的为了解.学习NAND FLASH的功能特性,没有使用STM32的FSMC(火龙开发板硬件为模拟时序驱动),纯粹自娱自乐,如对你有帮助,不胜荣幸 ...
- 基于51单片机实现模拟IIC总线时序
最近用到测量光线的模块BH1750FVI时需要用到IIC总线操作, 于是就又费功夫学习了下, 基本上算是了解了, 所以呢, 就用51的IO口, 模拟出了总线时序, 并能正确操纵需要用IIC总线访问地一 ...
最新文章
- 【只需简单三个步骤】ACE系统前后端不分离情况下如何增加一个JSP嵌入页面
- SAP 常用业务数据表设计
- IOS流水布局UICollectionView使用FlowLayout进行自由灵活组合
- 【绪论】——声呐概述
- LeetCode 64.最小路径和(动态规划)
- 各种厂商打开bios按键总汇
- Apache Kafka简介与安装(一)
- mysql的模拟数据,员工的模拟数据,sql语句的应用,粘贴即用
- java虚拟机存储空间_配置Java虚拟机内存大小
- 最新PS2022下载含安装操作步骤
- stm32软件模拟i2c通讯读取lm75a温度
- CC2530 IIC 4线驱动中景0.96寸OLED屏显示程序,从c51移植过来的
- ENVI图像处理(1):ENVI影像处理基础
- 模拟实现strlen
- bootstrap按钮组btn-group
- 要成为职业摄影师 你必须知道的10个真相
- Flutter版本 网易云音乐
- eos代码阅读笔记09- 石墨烯架构Graphene
- opencv——角点检测
- 14.PG分区表-传统分区表
热门文章
- qcon_从QCon San Francisco 2008中学到的主要知识点和教训
- 编译报错Building for iOS, but the linked and embedded framework ‘xxx.framework’ was buil......
- 博世传感器调试笔记(一)----加速度传感器BMA253
- 手把手教你如何用Python从PDF文件中导出数据(附链接)
- 【考研】 2021年哈尔滨工业大学计算机考研「初试」经验贴
- 为双系统 Ubuntu grub启动项中添加Windows启动项
- 实时视频应用之QoS关键技术分析
- Java weeb 入门的第一个坑MySql与Navicat的error
- GitHub无法访问下载
- 17种Vue适用于移动端的ui框架