冬季 家里太干燥了,所以想做一个自动调节的加湿器,通过管线和ro净水器连上实现自动湿度调节,还不用人工加水。在调试sht10温湿度传感器时卡了两天,网上的程序多少都有点问题没法偷懒了,只好借助逻辑分析仪,重新敲了一遍代码。并验证通过,特来分享。
/******************** **************
* 文件名 :sht10.h
* 描述 : 温湿度传感器 SHT10 驱动
* 实验平台:风驰STM8开发板
* 库版本 :V2.1.0
* 作者 :李宏伟 QQ:120799227
* 博客 :
*修改时间 :2014-11-30
#ifndef SHT10_H
#define SHT10_H
#include "stm8s.h"
#define SHT10_PIN GPIOB
#define SHT10_SCL GPIO_PIN_4
#define SHT10_SDA GPIO_PIN_5
#define SHT10_SCK_1 GPIO_WriteHigh(SHT10_PIN, SHT10_SCL)
#define SHT10_SCK_0 GPIO_WriteLow(SHT10_PIN, SHT10_SCL)
#define SHT10_DATA_1 GPIO_WriteHigh(SHT10_PIN, SHT10_SDA)
#define SHT10_DATA_0 GPIO_WriteLow(SHT10_PIN, SHT10_SDA)
#define SHT10_DATA_IN GPIO_ReadInputPin(SHT10_PIN, SHT10_SDA)
#define SET_SHT10_SCL_Out GPIO_Init(SHT10_PIN, SHT10_SCL, GPIO_MODE_OUT_PP_LOW_SLOW)
#define SET_SHT10_DATA_Out GPIO_Init(SHT10_PIN, SHT10_SDA, GPIO_MODE_OUT_PP_HIGH_SLOW)
#define SET_SHT10_DATA_IN GPIO_Init(SHT10_PIN, SHT10_SDA, GPIO_MODE_IN_FL_NO_IT)
#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
#define TEMP 0
#define HUMI 1
extern u8 bit;
static void delay_us(u8 time);
void sht10_rst();
void sht10_star();
char sht10_regrst(void);
char s_write_byte(unsigned char value);
char s_read_byte(unsigned char ack);
void calc_sth11(float *p_humidity ,float *p_temperature);
int s_measure(unsigned char mode);
#endif
/******************** **************
* 文件名 :sht10.c.c
* 描述 : 温湿度传感器 SHT10 驱动
* 实验平台:风驰STM8开发板
* 库版本 :V2.1.0
* 作者 :李宏伟 QQ:120799227
* 博客 :
*修改时间 :2014-11-30
*******************************************************************************/
#include "sht10.h"
static void delay_us(u8 time);
static void delay_us(u8 time)
{
u8 i=0;
do
{
for(i=0;i<9;i++) /*2个时钟周期*/
nop(); /*1个时钟周期*/
}while(time--);
}
//********************************************
//寄存器复位
//***********************************************
char sht10_regrst(void)
// resets the sensor by a softreset
{
unsigned char error=0;
sht10_rst(); //启动连接复位
error+=s_write_byte(RESET); //发送复位命令
return error; //error=1 通讯错误
}
//********************************************
//线路复位
//***********************************************
void sht10_rst()
{
unsigned char i;
SET_SHT10_DATA_Out;
SHT10_DATA_1;
SHT10_SCK_0;
delay_us(1);
//准备
for(i=0;i<9;i++) //DATA保持高,SCK时钟触发9次,发送启动传输,通迅即复位
{
SHT10_SCK_1;
delay_us(1);
SHT10_SCK_0;
delay_us(1);
}
//sht10_star(); //启动传输
}
//********************************************
//启动传输
//***********************************************
void sht10_star()
{
SET_SHT10_DATA_Out;
SHT10_DATA_1;
SHT10_SCK_0;
delay_us(1);
SHT10_SCK_1;
delay_us(1);
SHT10_DATA_0;
delay_us(1);
SHT10_SCK_0;
delay_us(1);
SHT10_SCK_1;
delay_us(1);
SHT10_DATA_1;
delay_us(1);
SHT10_SCK_0;
}
//********************************
//写入一个字节的命令,并且检查传感器是否正确接收了这个数据,返回值为0表示正确接收
//*******************************
char s_write_byte(unsigned char value)
{
unsigned char i;
char error;
//SET_SHT10_DATA_Out;
for (i=0x80;i>0;i>>=1) //发送8位数据,丛机将在上升沿读取数据
{
if(i&value)
SHT10_DATA_1;
else
SHT10_DATA_0;
delay_us(1);
SHT10_SCK_1;
delay_us(1);
SHT10_SCK_0;
}
SET_SHT10_DATA_IN;
SHT10_DATA_1;
delay_us(1);
SHT10_SCK_1;
delay_us(1);
error = (SHT10_DATA_IN?1:0);
delay_us(1);
SHT10_SCK_0;
//SET_SHT10_DATA_Out;
return error;
}
//********************************************
//读一个字节的数据,并且向传感器发出一个字节的“已接收”信号
//********************************************
char s_read_byte(unsigned char ack)
{
unsigned char i,val=0;
SET_SHT10_DATA_IN;
SHT10_DATA_1;
SHT10_SCK_0;
for (i=0x80;i>0;i>>=1) //接收8位数据
{
SHT10_SCK_1;
delay_us(2);
if (SHT10_DATA_IN)
val=(val | i); //read bit
SHT10_SCK_0;
delay_us(5);
}
SET_SHT10_DATA_Out; //发送一个ack位(0),表示是否接收到数据
if(ack)
SHT10_DATA_1;
else
SHT10_DATA_0;
delay_us(2);
SHT10_SCK_1;
delay_us(5);
SHT10_SCK_0;
delay_us(5);
SET_SHT10_DATA_IN;
SHT10_DATA_1;
return val;
}
//***************************************************
//温湿度的计算和修正
//************************************************
void calc_sth11(float *p_humidity ,float *p_temperature)
{
const float C1=-4.0; // for 12 Bit
const float C2=+0.0405; // for 12 Bit
const float C3=-0.0000028; // for 12 Bit
const float T1=+0.01; // for 14 Bit @ 5V
const float T2=+0.00008; // for 14 Bit @ 5V
float rh=*p_humidity; // rh: Humidity [Ticks] 12 Bit
float t=*p_temperature; // t: Temperature [Ticks] 14 Bit
float rh_lin; // rh_lin: Humidity linear
float rh_true; // rh_true: Temperature compensated humidity
float t_C; // t_C : Temperature
t_C=t*0.01 - 39.7; //calc. temperature from ticks
rh_lin=C3*rh*rh + C2*rh + C1; //calc. humidity from ticks to [%RH]
rh_true=(t_C-25)*(T1+T2*rh)+rh_lin; //calc. temperature compensated humidity [%RH]
if(rh_true>100)rh_true=100; //cut if the value is outside of
if(rh_true<0.1)rh_true=0.1; //the physical possible range
*p_temperature=t_C; //return temperature
*p_humidity=rh_true; //return humidity[%RH]
}
//************************************************
// makes a measurement (humidity/temperature) with checksum
//测量一次温度/湿度,无校验
//参数:0表示温度,1表示湿度
//**************************************************
int s_measure(unsigned char mode)
{
unsigned char a,b;
unsigned int i;
sht10_star(); //启动传输
switch(mode) //发送开始测量命令
{
case 0 : s_write_byte(MEASURE_TEMP); break;
case 1 : s_write_byte(MEASURE_HUMI); break;
default : break;
}
SET_SHT10_DATA_IN;
for (i=0;i<65535;i++)
{
if(SHT10_DATA_IN==0)
break; //??????
else
{
sht10_regrst();
return (((int)a)<<8)+b;
}
}
//读取两个字节的数据
a=s_read_byte(0);
b=s_read_byte(0);
s_read_byte(1);
return (((int)a)<<8)+b;
}
转载
|