SHT10型温湿度传感器工作时序分析及驱动程序与Proteus仿真的实现
一、传感器概述
SHT10型传感器属于SHT1×系列(其他常用型号还有SHT11、SHT15),SHT1×属于Sensirion温湿度传感器家族中的贴片封装系列。传感器将传感元件和信号处理电路集成在一块微型电路板上,输出完全标定的数字信号。传感器采用专利的CMOSens技术,确保产品具有极高的可靠性与卓越的长期稳定性。传感器包括一个电容性聚合体测湿敏感元件、一个用能隙材料制成的测温元件以及串行接口电路实现无缝连接。因此,该产品具有品质优越、响应迅速、抗干扰能力强、性价比高等优点。本篇博文将详细分析传感器的工作时序并根据时序编写驱动程序。最终,该驱动程序将通过Proteus仿真软件进行仿真验证。
二、传感器尺寸
三、接口定义及电源引脚
(一)接口定义
(二)电源引脚
SHT10的供电电压范围为2.3-5.5V,建议供电电压为3.3V。在电源引脚(VDD与GND)之间必须加一个100nF的电容,用于去耦滤波(在仿真中可加可不加)
SHT10的串行接口,在传感器信号的读取及电源损耗方面,都做了优化处理;传感器不能按照I2C协议进行编址,但是,如果I2C总线上没有挂在别的原件则传感器可以挂载到I2C总线上,但是单片机与传感器之间的通信协议不能采用I2C协议,而是要在按照传感器的协议进行信息交互。
四、传感器电气特性
传感器的电气特性(如:高/低电平、输入/输出电压等)受供电电压的影响,下表中的参数在没有特殊说明情况下均代表在5V供电条件下的参数。
下列时序图中,加粗的DATA线由传感器控制,普通的DATA线由单片机控制,有效时间由SCK的时序决定。尤其要注意的是,数据读取的有效时间为前一个切换的下降沿。
五、传感器的通讯过程及对应的驱动程序
(一)启动传感器
首先,选择供电电压后将传感器通电,商店速率不能低于1V/ms。通电后传感器需要有11ms进入休眠状态,在此之前,不允许单片机对传感器发送任何命令。
在休眠状态之后,要用一组“启动传输”时序。来完成数据传输的初始化。该”启动传输”时序包括:当SCK时钟为高电平时,DATA由高电平反转为低电平,随后是在SCK高电平时DATA由低电平反转为高电平。具体时序图如下:
由上述时序图,可以得到“启动传输”的驱动程序如下:
void Start(void)
{sck=0;//电平初始化dat=1;_nop_();sck=1;//第一次电平跳变_nop_();dat=0;_nop_();sck=0;_nop_();sck=1;//第二次电平跳变_nop_();dat=1;_nop_();sck=0;_nop_();
}
(二)命令集及“写一字节”程序
在启动程序之后,后续命令包括三个地址位(目前只支持000)和五个命令位。SHT10会以下述方式表示已正确接收指令:在第八个SCK的下降沿之后将DATA下拉为低电平作为ACK位,并在第九个SCK时钟的下降沿之后释放DATA(恢复高电平)。SHT10的命令集如下图所示。
根据已知命令集,即可通过单总线向传感器发送命令。发送湿度测量命令的工作时序如下图所示:
通过上述时序图所展示的“发送一字节”的工作时序,在“发送一字节数据”的驱动程序中可以采取的思路为:数据线先传送高位后传送低位,取位的方式为mask=0x80与命令值value进行“相与”,之后通过mask<<=1配合循环操作,即可实现将命令值由高位向低位逐位取出。在每取出value的一位后,首先延时一个_op_() (在12MHz的工作频率下为1us),使DATA引脚能够建立起稳定的电平,然后使sck产生上升沿并延时两个_nop_(),使传感器读入DATA引脚的数据,然后再恢复sck引脚的低电平,依次循环八次,使传感器读入一字节的命令数据。在读完八位数据之后,使SCK变高电平并检测DATA引脚是否拉低,以检测传感器是否发出了确认信息ACK。然后,再将SCK恢复为低电平。具体驱动程序如下:
uchar Write_byte(uchar value)//先传送高位
{uchar i;for(i=0;i<8;i++){if(value&0x80){dat=1;}else{dat=0;}_nop_();//建立数据线电平sck=1;//sck产生上升沿_nop_();_nop_();sck=0;//恢复sck的低电平_nop_();value<<=1;}sck=1;//第八个下降沿后(即产生第九个上升沿)判断数据线电平_nop_();if(dat==0)//如果数据线被拉低,说明传感器响应了{sck=0;//恢复sck的低电平_nop_();return 1; }sck=0;//恢复sck的低电平_nop_();return 0;
}
(三)“读一字节”驱动程序
在发布完一组测量命令之后,单片机要等待测量结束,这个过程大约需要10/80/120ms,分别对应8/12/14bit测量,确切时间由内部晶振速度决定,最多有-30%的变化。SHT10通过下拉DATA至电平并进入空闲模式表示测量结束。单片机在再次触发SCK时钟前必须等待这个“数据备妥”信号来读出数据。(默认温度测量14bit,湿度测量12bit),另外,还有一字节的CRC,用于循环冗余校验。湿度测量时序图如下:
根据上述湿度测量时序图可以类推温度测量时序图(区别在于默认情况下温度值比湿度值多2bit),并由时序图可写出具体控制时序,如下:
uchar Read_byte(uchar ack)
{uchar i,value,mask=0x80;for(i=0;i<8;i++){sck=1;_nop_();if(dat==1){value|=mask;}else{value&=(~mask);}sck=0;_nop_();mask>>=1;} if(ack==0)//单片机应答{dat=0;}else{dat=1;}_nop_();//建立应答/非应答信号电平sck=1;_nop_();sck=0;_nop_();dat=1;//释放数据线return value;
}
六、测量结果转换
测量结果转换过程中使用的参数与供电电压有关,总控制程序中的转换代码仅适用于5V供电时进行转换,其他工作电压下的转换关系如下图所示:
七、总控制程序
/*单片机采用AT89C52工作频率为12MHz,显示单元采用LCD1602液晶屏*/
#include<reg52.h>
#include<intrins.h>typedef unsigned char uchar;
typedef unsigned int uint;/**************************全局变量区******************************/
uchar str[4];//储存转换值对应的字符串
int T,Hum;//温湿度值
/**************************位定义区*******************************/
sbit RS=P3^3;
sbit RW=P3^4;
sbit E=P3^5;
sbit sck=P3^0;
sbit dat=P3^1;/**************************子函数声明区**************************/
void Delay(uint n);//延时子函数
void Delay1ms(uint t);//毫秒级延时子函数void Start(void);//发送一组“启动传输”的时序以完成数据传输的初始化
uchar Write_byte(uchar value);//向传感器写入一个字节
uchar Read_byte(uchar ack);//从传感器读出一个字节(0为应答,1为不应答)
int Get_Tep(void);//读取温度子函数
int Get_Hum(void);//读取湿度子函数
void Change(int x);//把整型数值x转换为字符串void Write_com(uchar com);//写命令子函数
void Write_dat(uchar dat);//写数据子函数
void Init_1602();//LCD1602初始化子函数
void Show(uchar x,uchar y,uchar *str);//LCD1602显示子函数/
/
void main()
{Init_1602();//LCD1602初始化Delay1ms(11);//上电后度过11ms的休眠状态Start();//唤醒T=Get_Tep();//获取温度值Start();//再次唤醒Hum=Get_Hum();//获取湿度值Change(Hum);//把湿度值转换为字符串Show(1,1,"Hum:");//显示湿度值Show(1,5,str);Change(T);//把温度值转换为字符串Show(2,1,"Temp:");//显示温度值Show(2,6,str);while(1);
}
/
/
/*********************************延时函数体*****************************/
void Delay(uint n) //延时函数
{ uint x,y; for(x=n;x>0;x--) for(y=110;y>0;y--);
}
void Delay1ms(uint t) //毫秒级延时子函数
{uchar a,b;uint i;for(i=0;i<t;i++){for(b=199;b>0;b--)for(a=1;a>0;a--);}
}
/********************************启动传输函数体***************************/
void Start(void)
{sck=0;//电平初始化dat=1;_nop_();sck=1;//第一次电平跳变_nop_();dat=0;_nop_();sck=0;_nop_();sck=1;//第二次电平跳变_nop_();dat=1;_nop_();sck=0;_nop_();
}
/********************************写入一字节函数体************************/
uchar Write_byte(uchar value)//先传送高位
{uchar i;for(i=0;i<8;i++){if(value&0x80){dat=1;}else{dat=0;}_nop_();//建立数据线电平sck=1;//sck产生上升沿_nop_();_nop_();sck=0;//恢复sck的低电平_nop_();value<<=1;}sck=1;//第八个下降沿后(即产生第九个上升沿)判断数据线电平_nop_();if(dat==0)//如果数据线被拉低,说明传感器响应了{sck=0;//恢复sck的低电平_nop_();return 1; }sck=0;//恢复sck的低电平_nop_();return 0;
}
/********************************读出一字节函数体************************/
uchar Read_byte(uchar ack)
{uchar i,value,mask=0x80;for(i=0;i<8;i++){sck=1;_nop_();if(dat==1){value|=mask;}else{value&=(~mask);}sck=0;_nop_();mask>>=1;} if(ack==0)//单片机应答{dat=0;}else{dat=1;}_nop_();//建立应答/非应答信号电平sck=1;_nop_();sck=0;_nop_();dat=1;//释放数据线return value;
}
/**********************************获取温度函数体**************************/
int Get_Tep()
{int result_l,result_h,check,result;float tempt;Write_byte(0x03);//读温度命令while(dat);//等到传感器转换完数据后把数据线主动拉低result_h=Read_byte(0);//读转换值高八位并应答result_l=Read_byte(0);//读转换值低八位并应答check=Read_byte(1);//读校验位并非应答result=result_h*256+result_l;tempt=0.01*result-40.1;//计算温度值(5V供电)result=tempt;//对温度值进行四舍五入if(tempt-result>=0.5){result+=1;}return result;
}
/**********************************获取温度函数体**************************/
int Get_Hum()
{int result_l,result_h,check,result;float tempt;float t1=0.01f,t2=0.00008f,c1=-2.0468f,c2=0.0367f,c3=-1.5955e-6f;Write_byte(0x05);//读湿度命令while(dat);//等到传感器转换完数据后把数据线主动拉低result_h=Read_byte(0);//读转换值高八位并应答result_l=Read_byte(0);//读转换值低八位并应答check=Read_byte(1);//读校验位并非应答result=result_h*256+result_l;tempt=(T-25)*(t1+t2*result)+(c1+c2*result+c3*result*result)-6;result=tempt;//对湿度值进行四舍五入if(tempt-result>=0.5){result+=1;}return result;
}
/******************************把整型数据转换为字符串**********************/
void Change(int x)
{str[0]=x/100+48;str[1]=(x/10)%10+48;str[2]=x%10+48;str[3]='\0';
}/********************************写命令函数体****************************/
void Write_com(uchar com)
{RS=0;P2=com;Delay(5);E=1;Delay(5);E=0;
}
/********************************写数据函数体****************************/
void Write_dat(uchar dat)
{RS=1;P2=dat;Delay(5); E=1;Delay(5);E=0;
}
/*****************************LCD1602初始化函数体*************************/
void Init_1602()
{uchar i=0;RW=0;Write_com(0x38);//屏幕初始化Write_com(0x0c);//打开显示 无光标 无光标闪烁Write_com(0x06);//当读或写一个字符是指针后一一位Write_com(0x01);//清屏Write_com(0x80);//设置位置
}
/*******************************显示内容函数体**************************/
void Show(uchar x,uchar y,uchar *str)
{unsigned char addr;if (x==1){addr=0x00+y-1; //从第一行、第y列开始显示}else{addr=0x40+y-1; //第二行、第y列开始显示} Write_com(addr+0x80);while (*str!='\0'){Write_dat(*str++);}}
八、Proteus仿真图的连接及结果
左肩理想右肩担当,君子不怨永远不会停下脚步!
SHT10型温湿度传感器工作时序分析及驱动程序与Proteus仿真的实现相关推荐
- DHT11型温湿度传感器的使用(附源码)
一.产品概述 DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器.它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性与卓越的长期稳定性.传感器包括一个电阻式感 ...
- 基于STM32的DHT11温湿度传感器设计
文章目录 前言 一.DHT11温湿度传感器是什么? 二.DHT11驱动程序详解 1.相关宏定义 2.输入输出GPIO配置 2.GPIO初始化设计 3.检测DHT11是否正常工作 4.读取DHT11数据 ...
- adc0808温度换算公式_温湿度传感器的三种模拟量换算关系
气候的变化常常会导致空气当中的湿度以及温度随之而产生相应的变化,如果想及时感知空气中温湿度的变化,那就需要温湿度传感器.在日常生活中,温湿度传感器种类有很多,按照数据上传方式分有RS485型温湿度传感 ...
- 温湿度传感器不同输出方式的优异对比
温湿度传感器装有湿敏和热敏元件,多以温湿度一体式的探头作为测温元件,将温度和湿度信号采集出来,经过稳压滤波.运算放大.非线性校正.V/I转换.恒流及反向保护等电路处理后,转换成与温度和湿度成线性关系的 ...
- DHT11(ASAIR)温湿度传感器的使用(软件)
** 关于DHT11(ASAIR)温湿度传感器的使用(软件) ** 前言 此次在学习中使用到的是ASAIR公司生产的DHT11型温湿度传感器,说明书可前往ASAIR官网下载. 网址:DHT11官方网页 ...
- 温度自动控制系统c语言,基于STC89C52RC单片机的大棚温湿度自动控制系统毕业论文+外文翻译及原文+C程序+proteus仿真文件+Altium Designer原理图...
大棚温湿度自动控制系统设计 摘 要:本设计是基于STC89C52RC单片机的大棚温湿度自动控制系统,采用SHT10作为温湿度传感器,LCD1602液晶屏进行显示.SHT10使用类似于I2C总线的时序 ...
- linux sht11驱动,SHT11.h下载 温湿度传感器SHT11的驱动程序,提供了外界调用接口函数...
/******************************************************************* *[文 件 名]:SHT11.h ...
- 湿度检测仪输入示数计算机编程,温湿度传感器DHT11驱动程序 - 全文
温湿度传感器DHT11驱动程序 - 全文 来源:网络整理 作者:2018年01月22日 16:52 [导读] 本文开始介绍了驱动程序的定义与驱动程序的作用,其次介绍了DHT11温湿度传感器特性.引脚说 ...
- 总结——调试STM32F103ZET6及外围传感器_电路图设计问题+SHT10温湿度传感器
总结--调试STM32F103ZET6及外围传感器_电路图设计问题+SHT10温湿度传感器http://blog.csdn.net/gsh_hello_world/article/details/53 ...
最新文章
- Android下基于SDL的位图渲染(一)
- 直播实录QA | 王赟Maigo分享“知识连成一片”是怎样一种体验
- 模拟使用Flume监听日志变化,并且把增量的日志文件写入到hdfs中
- Widget(桌面插件)
- stm32 NVIC EXTI
- linux 查看命令帮助,Linux中查看帮助相关的命令整理
- visual studio 2012如何彻底删除TFS上的团队项目
- iOS 推送功能打包后获取不到deviceToken
- oracle solaris 10 系统 下载,更新 Oracle Solaris 11 系统中的软件
- sqliteman安装时出现The following packages have unmet dependencies: libqtgui4 : Depends: libpng12-0错误
- Objective-C 程序设计(第4版)
- 如何使用快应用内置地图查看、导航位置
- 【教程】非常好用!一键彻底关闭Win10自带Windows Defender杀毒软件
- 在android中在屏幕密度为160,在 android 中,在屏幕密度为160时,1pt 大概等于多少sp...
- yum clean all 是什么意思
- m8+android固件,M8完美Android 2.2 LBE A11版固件发布
- 腾讯副总裁姚星离职创业!一手筹建AI Lab,张潼张正友都曾向他汇报
- matlab如何打开dcm_MatLab 与 visual studio 混合编程环境配置
- Android App耗电分析
- qlib格式的可转债数据:正股价,转股价的整合
热门文章
- 三角形外接球万能公式_三棱锥外接球半径公式
- Android 仿朋友圈,文字图片视频多条目,自动播放暂停
- javaweb图片路径问题
- 卷积神经网络与神经网络,卷积神经网络基础知识
- 完整的js写的省市级的程序
- Typecho博客评论生成随机用户头像
- git push 报错 Empty reply from server 或 Failed to connect to github.com port 443: Time out
- HardSwish和HardSigmoid的关系
- 今天和几个朋友交流个人品牌的看法
- matlab里trim函数,matlab 中trim函数总出现Index exceeds matrix dimensions,求大神帮忙解决...