7471|11

545

帖子

0

TA的资源

一粒金砂(高级)

楼主
 

LM3S8962驱动SHT11温湿度传感器之二 [复制链接]

   SHT11是瑞士Sensirion公司推出的基于CMOSensTM技术的新型温湿度传感器。该传感器将CMOS芯片技术与传感器技术结合起来,从而发挥出它们强大的优势互补作用。
一、SHT11温湿度传感器的主要特性如下:
●将温湿度传感器、信号放大调理、A/D转换、I2C总线接口全部集成于一芯片(CMOSensTM技术);
●可给出全校准相对湿度及温度值输出;
●带有工业标准的I2C总线数字输出接口;
●具有露点值计算输出功能;
●具有卓越的长期稳定性;
●湿度值输出分辨率为14位,温度值输出分辨率为12位,并可编程为12位和8位;
●小体积(7.65×5.08×23.5mm),可表面贴装;
●具有可靠的CRC数据传输校验功能;
●片内装载的校准系数可保证100%互换性;
●电源电压范围为2.4~5.5V;
●电流消耗,测量时为550μA,平均为28μA,休眠时为3μA。


二 SHT11温湿度传感器采用SMD(LCC)表面贴片封装形式,其引脚说明如下:(1)GND:接地端;(2)DATA:双向串行数据线;(3)SCK:串行时钟输入;(4)VDD电源端:0.4~5.5V电源

端;(5~8)NC:空管脚。


SHT11与LM8962开发板的连接图如下:

1脚接到GND上,2脚接到LM3S8962的I2CSDA上,即PB3管脚,3脚接到LM3S8962的I2CSCl上,即PB2管脚上,4管脚接到+3.3V电源上。

 


三、SHT11的内部结构和工作原理
    温湿度传感器SHT11将温度感测、湿度感测、信号变换、A/D转换和加热器等功能集成到一个芯片上,其内部结构如图2所示。该芯片包括一个电容性聚合体湿度敏感元件和一个用能隙材料制成的温度敏感元件。这两个敏感元件分别将湿度和温度转换成电信号,该电信号首先进入微弱信号放大器进行放大;然后进入一个14位的A/D转换器;最后经过二线串行数字接口输出数字信号。SHT11在出厂前都会在恒湿或恒温环境巾进行校准,校准系数存储在校准寄存器中;在测量过程中,校准系数会自动校准来自传感器的信号。此外,SHT11内部还集成一个加热元件,加热元件接通后能将SHT11的温度升高5℃左右,同时功耗也会有所增加。此功能主要为了比较加热前后的温度和湿度值,能综合验证两个传感器元件的性能。在高湿(>95%RH)环境中,加热传感器可预防传感器结露,同时缩短响应时间,提高精度。加热后SHT11温度升高、相对湿度降低,较加热前,测量值会略有差异。

 

 微处理器是通过二线串行数字接口和SHT11进行通信的。通信协议和通用的I2C总线协议是不兼容的,因此需要用通用微处理器I/O口模拟该通信时序。微处理器对SHT11的控制是通过5个5位命令代码来实现的,命令代码的含义如下表所列:

 

 
 微处理器和温湿度传感器通信采用串行二线接口SCK和DATA,其中SCK为时钟线,DATA为数据线。该二线串行通信协议和I2C协议是不兼容的。在程式开始,微处理器需要用一组"启动传输"时序表示数据

传输的启动,如下图所示。当SCK时钟为高电平时,DATA翻转为低电平;紧接着SCK变为低电平,随后又变为高电平;在SCK时钟为高电平时,DATA再次翻转为高电平。

 

 

四、 SHT11驱动函数:
//1、宏定义,SDA接到PB3,SCL接到PB2上。
#define SHT1x_SDA_SYSCTL           SYSCTL_PERIPH_GPIOB
#define SHT1x_SDA_GPIO_PORT     GPIO_PORTA_BASE
#define SHT1x_SDA_PIN      GPIO_PIN_3

#define SHT1x_SCL_SYSCTL           SYSCTL_PERIPH_GPIOB
#define SHT1x_SCL_GPIO_PORT     GPIO_PORTA_BASE
#define SHT1x_SCL_PIN      GPIO_PIN_2

//控制命令,SHT1x地址位均为 000    地址位      命令 R/W
#define SHT1x_CMD_STATUS_REG_W     0x06    //000     0011  0
#define SHT1x_CMD_STATUS_REG_R     0x07    //000     0011  1
#define SHT1x_CMD_GET_TEMP         0x03    //000     0001  1
#define SHT1x_CMD_GET_HUMI         0x05    //000     0010  1
#define SHT1x_CMD_RESET            0x1E    //000     1111  0

//ACK为低电平有效
#define SHT1x_ACK_YES              0x01
#define SHT1x_ACK_NO               0x00

#define SHT1x_CALC_TEMP         0x01
#define SHT1x_CALC_HUMI      0x02
2、GPIO口初始化函数
static void init_sht1x_dev_pin(void)
{
    SysCtlPeripheralEnable(SHT1x_SDA_SYSCTL);
 GPIODirModeSet(SHT1x_SDA_GPIO_PORT, SHT1x_SDA_PIN, GPIO_DIR_MODE_OUT);
    GPIOPadConfigSet(SHT1x_SDA_GPIO_PORT, SHT1x_SDA_PIN, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD);

    SysCtlPeripheralEnable(SHT1x_SCL_SYSCTL);
 GPIODirModeSet(SHT1x_SCL_GPIO_PORT, SHT1x_SCL_PIN, GPIO_DIR_MODE_OUT);
    GPIOPadConfigSet(SHT1x_SCL_GPIO_PORT, SHT1x_SCL_PIN, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD);

 set_sht1x_sda_output();

 

 

}
//设置SCL为0或1
static void set_sht1x_scl(char flag)
{
 if (0 == flag) {
  GPIOPinWrite(SHT1x_SCL_GPIO_PORT, SHT1x_SCL_PIN, ~SHT1x_SCL_PIN); 
 } else if (1 == flag) {
  GPIOPinWrite(SHT1x_SCL_GPIO_PORT, SHT1x_SCL_PIN, SHT1x_SCL_PIN);   
 }
}
//设置DSA为0或1
static void set_sht1x_sda(char flag)
{
 if (0 == flag) {
  GPIOPinWrite(SHT1x_SDA_GPIO_PORT, SHT1x_SDA_PIN, ~SHT1x_SDA_PIN); 
 } else if (1 == flag) {
  GPIOPinWrite(SHT1x_SDA_GPIO_PORT, SHT1x_SDA_PIN, SHT1x_SDA_PIN);   
 }
}
读取SDA
static int read_sht1x_sda(void)
{
 int proc_result = -1;
 unsigned char tmp_data;
 
 set_sht1x_sda_input();

 tmp_data = GPIOPinRead(SHT1x_SDA_GPIO_PORT,SHT1x_SDA_PIN);
 if (SHT1x_SDA_PIN == tmp_data) {
  proc_result = 1;
 } else {
  proc_result = 0;
 }
 
 set_sht1x_sda_output();

 return (proc_result);
}

static void set_sht1x_sda_output(void)
{
 GPIODirModeSet(SHT1x_SDA_GPIO_PORT, SHT1x_SDA_PIN, GPIO_DIR_MODE_OUT);
    GPIOPadConfigSet(SHT1x_SDA_GPIO_PORT, SHT1x_SDA_PIN, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD); 
}

static void set_sht1x_sda_input(void)
{
 GPIODirModeSet(SHT1x_SDA_GPIO_PORT, SHT1x_SDA_PIN, GPIO_DIR_MODE_IN);
    GPIOPadConfigSet(SHT1x_SDA_GPIO_PORT, SHT1x_SDA_PIN, GPIO_STRENGTH_4MA, GPIO_PIN_TYPE_STD); 
}

//读SHT11状态
int read_sht1x_status(unsigned char *p_value,unsigned char *p_checksum)
{
 int proc_result = -1;
 unsigned char read_st,read_checksum;
 
 //启动操作
 start_sht1x_op();
 //写入读取命令
 proc_result = write_sht1x_byte(SHT1x_CMD_STATUS_REG_R);
    //读取状态
 proc_result = read_sht1x_byte(&read_st,SHT1x_ACK_YES);
    //读取校验值
 proc_result = read_sht1x_byte(&read_checksum,SHT1x_ACK_NO);
   *p_value     = read_st;
   *p_checksum  = read_checksum;

 return (proc_result);
}
写SHT11状态
int write_sht1x_status(unsigned char value)
{
 int proc_result = 0;
 //启动操作
 start_sht1x_op();
 proc_result += write_sht1x_byte(SHT1x_CMD_STATUS_REG_W);
 proc_result += write_sht1x_byte(value);
 return (proc_result);
}
//SHT11复位
void reset_sht1x_connect(void)
{
 int i;

 set_sht1x_sda(1);delay_sht1x_bus(1);
 set_sht1x_scl(0);delay_sht1x_bus(1);
 for (i = 0; i < 9; i++) {
  set_sht1x_scl(1);delay_sht1x_bus(1);
  set_sht1x_scl(0);delay_sht1x_bus(1);
 }

 start_sht1x_op();
}
//软件复位
int reset_sht1x_software(void)
{
 int proc_result = -1;

 reset_sht1x_connect();
 proc_result = write_sht1x_byte(SHT1x_CMD_RESET);  //需要11ms
 return (proc_result);
}
//写一字节
int write_sht1x_byte(unsigned char in_data)
{
 int proc_result = -1;
 int i;
 
 for (i = 0; i < 8; i++) {
  if (0x80 == (in_data & 0x80)) {
   //High
   set_sht1x_sda(1);
  }  else {
   set_sht1x_sda(0);
  }
  delay_sht1x_bus(1);
  in_data = (in_data << 1);
  set_sht1x_scl(1);
  delay_sht1x_bus(1);
  set_sht1x_scl(0);
  }
 
 //释放总线
 set_sht1x_sda(1);
 //给出上升沿,读入ACK
 set_sht1x_scl(1);
 proc_result = read_sht1x_sda();
 if (1 == proc_result) {
  //无效ACK信号
  proc_result = -1;
 }
 set_sht1x_scl(0); 

 return (proc_result);
}
//读一字节
int read_sht1x_byte(unsigned char *p_out_data,unsigned char ack)
{
 int proc_result = -1;
 
 int i;
 unsigned char tmp_data;

    tmp_data = 0x00;
 for (i = 0; i < 8; i++) {
  tmp_data = (tmp_data << 1);
  set_sht1x_scl(1);
  delay_sht1x_bus(1);

  proc_result = read_sht1x_sda();
  if (1 == proc_result) {
   tmp_data |= 0x01;
  }

  set_sht1x_scl(0);
  delay_sht1x_bus(1);
 }
 
   *p_out_data = tmp_data;
    proc_result = read_sht1x_sda();
 if (1 == proc_result) {
  //没有ACK信号
  proc_result = -1;
 }
 
 //释放总线
 set_sht1x_scl(1);delay_sht1x_bus(1);
 set_sht1x_scl(0);delay_sht1x_bus(1);
 set_sht1x_sda(1);delay_sht1x_bus(1);

 return (proc_result);

}
//启动SHT11
static void start_sht1x_op(void)
{
 //初始状态
 set_sht1x_sda(1); delay_sht1x_bus(1);
 set_sht1x_scl(0); delay_sht1x_bus(1);
 //第一个时钟上升沿后数据变为低 
 set_sht1x_scl(1); delay_sht1x_bus(1);
 set_sht1x_sda(0); delay_sht1x_bus(1);
 //时钟下降沿后时钟上升沿
 set_sht1x_scl(0); delay_sht1x_bus(1);
 set_sht1x_scl(1); delay_sht1x_bus(1);
 //数据变为高,时钟下降沿 
 set_sht1x_sda(1); delay_sht1x_bus(1);
 set_sht1x_scl(0); delay_sht1x_bus(1);

//计算温湿度
int calc_sht1x_value(int mode,t_dev_sht1x *p_this)
{
 int proc_result = -1;

 const float T1 = 0.01;
 const float T2 = 0.00008;

 float c1 = -4;
 float c2 = 0.0405;
 float c3 = -0.0000028;
 float rh;
 float t;
 float rh_lin;
 float rh_true;
 float t_c;

 float logex,dew_point;

 //计算温湿度
 rh = p_this->humi;
 t  = p_this->temp;

 t_c     = t*0.01 - 39.6;  //12bit 0.04  14bit 0.01
 rh_lin  = c3*rh*rh + c2*rh + c1;
 rh_true = (t_c - 25)*(T1 + T2*rh) + rh_lin;
 if (rh_true > 100) {
  rh_true = 100;
 } else if (rh_true < 0.1) {
  rh_true = 0.1;
 }
 
 p_this->temp_value = t_c;
 p_this->humi_value = rh_true;
 
 return (proc_result);

}

//读取结果
int get_sht1x_result(int mode,unsigned short *p_value,unsigned char *p_check_sum)
{
 int proc_result = 0;
 int i;
 static unsigned char read1,read2; //optimize
 static unsigned short result_value;
 
 //启动操作
 start_sht1x_op();
 //获取传感器测量数值
 switch (mode) {
  case  SHT1x_CALC_TEMP:
   proc_result += write_sht1x_byte(SHT1x_CMD_GET_TEMP);
   break;
  case  SHT1x_CALC_HUMI:
   proc_result += write_sht1x_byte(SHT1x_CMD_GET_HUMI);
   break;
  default:
   proc_result = -1;
   break;
 }

 //等待测量完成
 for(i = 0; i < 65535; i++) {
  delay_sht1x_bus(1);
  proc_result = read_sht1x_sda();
  if (0 == proc_result) {
   //得到传感器响应
   break;
  } 
 }
 
 if (1 == proc_result) {
  //超时后传感器仍未响应
  proc_result = -1;
 }

 read1 = 0;
 read2 = 0;
 proc_result += read_sht1x_byte(&read1,SHT1x_ACK_YES);  //MSB 
 //read1 = (read1 & 0x0F);
 proc_result += read_sht1x_byte(&read2,SHT1x_ACK_YES);  //LSB
 result_value = read1;
    result_value = (result_value << 8);
    result_value = (result_value | read2);
   *p_value = result_value;
 proc_result += read_sht1x_byte(&read1,SHT1x_ACK_NO);
   *p_check_sum = read1;
    
 return (proc_result);
}

 

 

 

 

最新回复

亲,我的也是这种情况,数据总是不变,而且温度一直是0你解决了吗??   详情 回复 发表于 2014-7-24 11:17
 
点赞 关注

回复
举报

1万

帖子

16

TA的资源

版主

沙发
 

不错顶个

:P
 
个人签名http://shop34182318.taobao.com/
https://shop436095304.taobao.com/?spm=a230r.7195193.1997079397.37.69fe60dfT705yr
 

回复

33

帖子

0

TA的资源

一粒金砂(中级)

板凳
 

不错

楼主辛苦了!!很好,顶一个!!!
 
 
 

回复

77

帖子

0

TA的资源

一粒金砂(初级)

4
 

SHT11程序

好定西,顶个!!!!!
 
 
 

回复

66

帖子

0

TA的资源

一粒金砂(中级)

5
 

有个关键的地方……

delay_sht1x_bus()
这个函数的实现,LZ没贴出来啊……
我认为这里面最关键的就是这个延时了=。=
 
 
 

回复

2641

帖子

0

TA的资源

五彩晶圆(中级)

6
 
感谢楼主分享
 
 
 

回复

16

帖子

0

TA的资源

一粒金砂(中级)

7
 

求助

我下载试用了楼主的程序,有点问题,读出的数据总是0
请问楼主可否将程序发至QQ邮箱或QQ指教?630459987@qq.com

点评

亲,我的也是这种情况,数据总是不变,而且温度一直是0你解决了吗??  详情 回复 发表于 2014-7-24 11:17
 
 
 

回复

245

帖子

0

TA的资源

纯净的硅(初级)

8
 
虽然没用过SHT11这个温湿度传感器,但是感觉和以前玩的DHT11温湿度传感器很相似,向楼主学习下次有空把8962驱动DHT11的源码也给传上来!
 
个人签名学习靠的就是努力,靠的就是坚持……
 
 

回复

35

帖子

0

TA的资源

一粒金砂(中级)

9
 
额。。  不好意思    我是菜鸟,
GPIOPinWrite(SHT1x_SDA_GPIO_PORT, SHT1x_SDA_PIN, ~SHT1x_SDA_PIN)   这句我写的时候就不行呢。。  ?
最后一个不是unsigned char ucVal吗?

点评

GPIOPinWrite(SHT1x_SDA_GPIO_PORT, SHT1x_SDA_PIN, ~SHT1x_SDA_PIN) ; 这句的意思就是将 SHT1x_SDA_PIN 所对应的脚清零。  详情 回复 发表于 2013-6-7 08:56
 
 
 

回复

1803

帖子

0

TA的资源

五彩晶圆(高级)

10
 

回复 9楼 iceman5823 的帖子

GPIOPinWrite(SHT1x_SDA_GPIO_PORT, SHT1x_SDA_PIN, ~SHT1x_SDA_PIN)  ;
这句的意思就是将 SHT1x_SDA_PIN 所对应的脚清零。

点评

谢谢 有些菜。 才开始做这部分。 问下eepROM这部分有做过吗 现在只是想试试能不能写数,然后读出来。现在对于fm24cl64 参数怎么设置? FM24CL64的三个引脚都置高 应该下面这样设置吧?但是我看有  详情 回复 发表于 2013-6-10 15:32
 
 
 

回复

35

帖子

0

TA的资源

一粒金砂(中级)

11
 

回复 10楼 Study_Stellaris 的帖子

谢谢   有些菜。   才开始做这部分。       问下eepROM这部分有做过吗
现在只是想试试能不能写数,然后读出来。现在对于fm24cl64     参数怎么设置?
FM24CL64的三个引脚都置高   应该下面这样设置吧?但是我看有程序配置是 0xAE>>1   为什么呢?
  I2CM_DeviceInitSet(&CAT24C02, 0xAE, 0, 1, cBuf, 100);
我现在读不出那个数来。。。
如果需要发代码,qq联系帮忙下吧  254818628
 
 
 

回复

6

帖子

0

TA的资源

一粒金砂(初级)

12
 
kzdtdyy 发表于 2012-5-28 08:44
我下载试用了楼主的程序,有点问题,读出的数据总是0
请问楼主可否将程序发至QQ邮箱或QQ指教?

亲,我的也是这种情况,数据总是不变,而且温度一直是0你解决了吗??
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/6 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表