本来想在网上直接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 加载或启动加热功能等。状态寄存器度、写如下:
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __SHT10_H
#define __SHT10_H
/* Includes ------------------------------------------------------------------*/
#include "stm32l0xx_hal.h"
#include "stm32l0xx_nucleo.h"
#define SHT10_DATA_PIN GPIO_PIN_6
#define SHT10_SCK_PIN GPIO_PIN_7
#define SHT10_GPIO_PORT GPIOA
#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 1
void GetEnvInfo(uint16_t *humi_val_real,uint16_t *temp_val_real)
{
*humi_val_real = getHumidity();
*temp_val_real = getTemprature();
}
#endif