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