中科因仑“3+1”工程特种兵精英论坛

标题: 调试通过的sht10湿度传感器 stm8 [打印本页]

作者: 张衍波    时间: 2015-10-7 14:55
标题: 调试通过的sht10湿度传感器 stm8

冬季 家里太干燥了,所以想做一个自动调节的加湿器,通过管线和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;

}
转载






欢迎光临 中科因仑“3+1”工程特种兵精英论坛 (http://bbs.enlern.com/) Powered by Discuz! X3.4