STM32 采集SHT10传感器数据(非float)
来源:互联网 发布:config.inc.php下载 编辑:程序博客网 时间:2024/05/24 15:41
本来想在网上直接load一个sht10驱动就直接能用用了,没想到太天真了。
非但没有stm32L0cube这个库的程序而且大部分还是使用浮点运算的,你妹的,stm32好多都是不支持浮点运算的呀。所以只好自己搞了。
以下为sth10常规的时序,抠出来的没啥好说
1、接口定义:
SHT10的接口定义如下图所示:
如上图所示,1脚为GND,4脚为VDD。它的供电电压范围为2.4~5.5V,建议的电压为3.3V,在电源引脚(VDD、GND)之间必须加上一个0.1uf的电容,应于去耦滤波用。它的2脚DATA为数据引脚,3脚SCK为时钟控制引脚,没有发现这两个引脚很像IIC所使用的引脚功能?没错,这个传感器确实可以认为是IIC接口,但是又有却别。该传感器不能按照IIC的协议编址,但是,如果IIC总线上没有挂接别的元件,传感器可以直接连到IIC总线上,但是单片机必须按照传感器的协议工作。传感器与单片机的接线如下图所示:
2、传感器的通讯
2.1、“启动传输”时序
用一组“启动传输”时序来完成数据传输的初始化。它包括:当SCK时钟高电平时DATA翻转为低电平,紧接着SCK变成低电平,随后是在SCK时钟高电平,随后是在SCK时钟高电平DATA翻转位高电平。时序如下:
2.2、复位时序
如果与SHT1x 通讯中断,可通过下列信号时序复位:当DATA 保持高电平时,触发SCK 时钟9 次或更多。时序图如下:
2.3、命令集
传感器的命令包含三个地址位(目前只支持000,这就是他只能挂接在空闲的IIC总线上的原因)和五个命令位。。SHT1x 会以下述方式表示已正确地接收到指令:在第8 个SCK 时钟的下降沿之后,将DATA 下拉为低电平(ACK 位)。在第9 个SCK 时钟的下降沿之后,释放DATA(恢复高电平)。命令集如下:
2.4、温湿度测量
发布一组测量命令(‘00000101’表示相对湿度RH,‘00000011’表示温度T)后,控制器要等待测量结束。这个过程需要大约20/80/320ms,分别对应8/12/14bit 测量。确切的时间随内部晶振速度,最多可能有-30%的变化。。SHT1x 通过下拉DATA 至低电平并进入空闲模式,表示测量的结束。控制器在再次触发SCK 时钟前,必须等待这个“数据备妥”信号来读出数据。检测数据可以先被存储,这样控制器可以继续执行其它任务在需要时再读出数据。
在收到CRC 的确认位之后,表明通讯结束。如果不使用CRC-8 校验,控制器可以在测量值LSB 后,通过保持ACK高电平终止通讯。在测量和通讯完成后,SHT1x 自动转入休眠模式。
2.5、状态寄存器
SHT1x 的某些高级功能可以通过给状态寄存器发送指令来实现,如选择测量分辨率,电量不足提醒,使用 OTP 加载或启动加热功能等。状态寄存器度、写如下:
状态寄存器的具体描述如下表所示:
测量分辨率:默认分辨率 14bit (温度) 和 12bit (湿度) 可以被降低为 12 和 8bit. 尤其适用于要求测量速度极高或者功耗极低的应用。
电量不足检测功能:在电压不足 2.47V 发出警告。精度为±0.05 V。
加热:可通过向状态寄存器内写入命令启动传感器内部加热器.。加热器可以使传感器的温度高于周围环境 5 – 10°C12 。功耗大约为 8mA @ 5V 。
OPT加载:开启此功能,标定数据将在每次测量前被上传到寄存器。如果不开启此功能,可减少大约 10ms的测量时间。
上面的寄存器如果没有什么特殊要求或应用于特定的场合,则无需配置,选择默认就可以了。
2.6、通讯过程
传感器的通讯过程为:发送”启动传输“时序,初始化传感器——>发送命令——>等待传感器应答,及测量结束——>接收传感器的16位数据值——>接收8为的CRC校验数据——>休眠,等待下一次传输开始。
传输的过程的测量时序可以由下图示意:
上图中 TS = 传输开始, MSB = 高有效字节,LSB =低有效字节, LSb = 低有效位。
下面举个实际测量时的相对湿度测量时序例子。时序如下:
这张图可以知道:我们接收到的数据数值为”0000 0100 0011 0001“ = 1073 = 35.50% RH (位含温度补偿),至于怎么计算的,请接着往下看。
2.7、信号转化
2.7.1 温度的转化
设T 2 1 SOt为从传感器上读出来的测量数值,我们需要用下面的公式将测量数值转换成整整的温度值。
T = d1 + d2 * SOt (其中d1,d2的值根据实际情况选择,选项如下)
2.7.2 湿度的转换
湿度的转换公式如下:。其中湿度的转化参数如下选择:根据采样的精度不同而不同。
99%以上的湿度已经接近饱和必须经过处理显示100%RH13.请注意 湿度传感器对电压无依赖性。测量值与相对湿度的转化如下图所示:
相对湿度根据上面的参数与公式算出来之后,还需要考虑当前环境温度而进行适当的补偿。补偿的公式及其参数选择如下:
/* Define to prevent recursive inclusion -------------------------------------*/#ifndef __SHT10_H#define __SHT10_H/* Includes ------------------------------------------------------------------*/#include "stm32l0xx_hal.h"#include "stm32l0xx_nucleo.h"#define SHT10_DATA_PINGPIO_PIN_6#define SHT10_SCK_PINGPIO_PIN_7#define SHT10_GPIO_PORTGPIOA#define DATA_PIN_HIGH()HAL_GPIO_WritePin(SHT10_GPIO_PORT,SHT10_DATA_PIN,1)#define DATA_PIN_LOW()HAL_GPIO_WritePin(SHT10_GPIO_PORT,SHT10_DATA_PIN,0)#define SCK_PIN_HIGH()HAL_GPIO_WritePin(SHT10_GPIO_PORT,SHT10_SCK_PIN,1)#define SCK_PIN_LOW()HAL_GPIO_WritePin(SHT10_GPIO_PORT,SHT10_SCK_PIN,0)#define DATA_VALUE()HAL_GPIO_ReadPin(SHT10_GPIO_PORT,SHT10_DATA_PIN)extern void SHT10_init(void);extern void GetEnvInfo(uint16_t *humi_val_real,uint16_t *temp_val_real);/* Exported types ------------------------------------------------------------*//* Exported constants --------------------------------------------------------*//* Exported macro ------------------------------------------------------------*//* Exported functions ------------------------------------------------------- */#endif /* __MAIN_H *//************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
c文件
#include "main.h"#include "sht10.h"typedef union { unsigned int i; float f; } value; //----------------------------------------------------------------------------------// modul-var //----------------------------------------------------------------------------------enum {TEMP,HUMI}; #define noACK 0 #define ACK 1 //adr command r/w #define STATUS_REG_W 0x06 //000 0011 0 #define STATUS_REG_R 0x07 //000 0011 1 #define MEASURE_TEMP 0x03 //000 0001 1 #define MEASURE_HUMI 0x05 //000 0010 1 #define RESET 0x1e //000 1111 0 static GPIO_InitTypeDef GPIO_InitSckStruct;static GPIO_InitTypeDef GPIO_InitDataStruct;void SHT10_Dly(void) { uint16_t i; for(i = 500; i > 0; i--); } void SHT10_DATAOut(void) { GPIO_InitDataStruct.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitDataStruct.Pull = GPIO_PULLUP;GPIO_InitDataStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;GPIO_InitDataStruct.Pin = SHT10_DATA_PIN;HAL_GPIO_Init(SHT10_GPIO_PORT, &GPIO_InitDataStruct);} /************************************************************* Function :SHT10_DATAIn Description:设置DATA引脚为输入 Input : none return : none *************************************************************/ void SHT10_DATAIn(void) { //PD0 DATA 浮动输入 GPIO_InitDataStruct.Mode = GPIO_MODE_INPUT;GPIO_InitDataStruct.Pull = GPIO_NOPULL;GPIO_InitDataStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;GPIO_InitDataStruct.Pin = SHT10_DATA_PIN;HAL_GPIO_Init(SHT10_GPIO_PORT, &GPIO_InitDataStruct);} /************************************************************* Function :SHT10_TransStart Description:开始传输信号,时序如下: _____ ________ DATA: |_______| ___ ___ SCK : ___| |___| |______ Input : none return : none *************************************************************/ void SHT10_TransStart(void) { SHT10_DATAOut(); //设置DATA数据线为输出 //SHT10_DATA_H(); DATA_PIN_HIGH(); //SHT10_SCK_L(); SCK_PIN_LOW(); SHT10_Dly(); //SHT10_SCK_H(); SCK_PIN_HIGH(); SHT10_Dly(); //SHT10_DATA_L(); DATA_PIN_LOW(); SHT10_Dly(); //SHT10_SCK_L(); SCK_PIN_LOW(); SHT10_Dly(); //SHT10_SCK_H(); SCK_PIN_HIGH(); SHT10_Dly(); //SHT10_DATA_H(); DATA_PIN_HIGH(); SHT10_Dly(); //SHT10_SCK_L(); SCK_PIN_LOW(); } void SHT10_ConReset(void) { uint8_t i; SHT10_DATAOut(); //SHT10_DATA_H(); DATA_PIN_HIGH(); //SHT10_SCK_L(); SCK_PIN_LOW(); for(i = 0; i < 9; i++) //触发SCK时钟9c次 { //SHT10_SCK_H(); SCK_PIN_HIGH(); SHT10_Dly(); //SHT10_SCK_L(); SCK_PIN_LOW(); SHT10_Dly(); } SHT10_TransStart(); //启动传输 } void SHT10_init(void){GPIO_InitSckStruct.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitSckStruct.Pull = GPIO_PULLUP;GPIO_InitSckStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;GPIO_InitSckStruct.Pin = SHT10_SCK_PIN;HAL_GPIO_Init(SHT10_GPIO_PORT, &GPIO_InitSckStruct);GPIO_InitDataStruct.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitDataStruct.Pull = GPIO_PULLUP;GPIO_InitDataStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;GPIO_InitDataStruct.Pin = SHT10_DATA_PIN;HAL_GPIO_Init(SHT10_GPIO_PORT, &GPIO_InitDataStruct);SHT10_ConReset();}uint8_t SHT10_WriteByte(uint8_t value) { uint8_t i;uint8_t err = 0; SHT10_DATAOut(); //设置DATA数据线为输出 for(i = 0x80; i > 0; i /= 2) //写1个字节 { if(i & value) DATA_PIN_HIGH(); else DATA_PIN_LOW(); SHT10_Dly(); SCK_PIN_HIGH(); SHT10_Dly(); SCK_PIN_LOW(); SHT10_Dly(); } SHT10_DATAIn(); //设置DATA数据线为输入,释放DATA线 SCK_PIN_HIGH(); err = DATA_VALUE(); //读取SHT10的应答位 SCK_PIN_LOW(); return err; } uint8_t SHT10_ReadByte(uint8_t Ack) { uint8_t i;uint8_t val = 0; SHT10_DATAIn(); //设置DATA数据线为输入 for(i = 0x80; i > 0; i /= 2) //读取1字节的数据 { SHT10_Dly(); SCK_PIN_HIGH(); SHT10_Dly(); if(DATA_VALUE()) val = (val | i); SCK_PIN_LOW(); } SHT10_DATAOut(); //设置DATA数据线为输出 if(Ack) DATA_PIN_LOW(); //应答,则会接下去读接下去的数据(校验数据) else DATA_PIN_HIGH(); //不应答,数据至此结束 SHT10_Dly(); SCK_PIN_HIGH(); SHT10_Dly(); SCK_PIN_LOW(); SHT10_Dly(); return val; //返回读到的值 } uint8_t SHT10_Measure(uint16_t *p_value, uint8_t *p_checksum, uint8_t mode) {uint8_t err = 0; uint32_t i; uint8_t value_H = 0; uint8_t value_L = 0; SHT10_TransStart(); //开始传输 switch(mode) { case TEMP: //测量温度 err += SHT10_WriteByte(MEASURE_TEMP);//写MEASURE_TEMP测量温度命令 break; case HUMI: err += SHT10_WriteByte(MEASURE_HUMI);//写MEASURE_HUMI测量湿度命令 break; default: break; } SHT10_DATAIn(); for(i = 0; i < 72000000; i++) //等待DATA信号被拉低 { if(DATA_VALUE() == 0) break; //检测到DATA被拉低了,跳出循环 } if(DATA_VALUE() == 1) //如果等待超时了 err += 1; //HAL_Delay(20); value_H = SHT10_ReadByte(ACK); value_L = SHT10_ReadByte(ACK); *p_checksum = SHT10_ReadByte(noACK); //读取校验数据 *p_value = (value_H << 8) | value_L; return err; }int getTemprature(void){uint16_t temp_val = 0;uint8_t checksum = 0; SHT10_Measure(&temp_val, &checksum, TEMP);return (int)(temp_val/100-40);}int getHumidity(void){int realHumi=0;uint16_t humi_val = 0;uint8_t checksum = 0; SHT10_Measure(&humi_val, &checksum, HUMI);realHumi = ((humi_val*405/10000)+(((humi_val*humi_val)*28)/1000000)-4);if(realHumi > 100){realHumi = 100;}else if(realHumi < 0){realHumi = 0;}return realHumi;}#if 1void GetEnvInfo(uint16_t *humi_val_real,uint16_t *temp_val_real){*humi_val_real = getHumidity();*temp_val_real = getTemprature(); } #endif
使用的话,先调用SHT10_init,然后调用GetEnvInfo即可。我是用的是pa6,pa7作为模拟io口实际使用可任君选择。(另外说下,我是用的是STM32L0系列的库,使用的芯片是stm32L071RB)。
- STM32 采集SHT10传感器数据(非float)
- STM32 SHT10温湿度传感器的信号采集
- ESP8266采集SHT10温湿度
- MSP430 Launchpad MSP430g2452 SHT10 温湿度传感器
- 基于加速度传感器智能穿戴:数据采集
- 多客户端传感器数据采集系统
- 传感器采集的数据有多重要
- STM32串口接收粉尘传感器数据
- STM32串口获取氨气传感器数据
- STM32 SD卡 记录传感器数据
- 基于stm32的环境数据采集项目
- STM32通过SPI采集DT50 ADS8320数据
- STM32读取MQ4传感器、DHT11温湿度传感器、GP2Y1014AU0F夏普光学灰尘传感器数据
- Arduino 中多传感器数据采集的写法
- ZigBee无线传感器网络远程数据采集系统设计
- Predix之玩转树莓派(2) 从传感器采集数据
- 激光传感器采集数据的障碍物特征提取
- 总结——调试STM32F103ZET6及外围传感器_电路图设计问题+SHT10温湿度传感器
- 大数据储存安全的重要性
- java 设计模式学习前篇--设计模式理解
- python中数组去重
- 我生成参数而我们是不是填错了哪里啊!怎么搞都没有成功!有大神能帮帮我吗??
- 28个Java常用的工具类之交易前置系统专用工具类
- STM32 采集SHT10传感器数据(非float)
- group by 和 order by
- HashMap实现原理分析
- 使用C语言生成bitmap
- 角点检测方法
- Expecting "jsp:param" standard action with "name" and "value" attributes解决方案
- 关于KMP算法(模块匹配)的实现
- MySQL性能分析及explain的使用
- 0基础UI设计的人如何快速入门