发布日期:2022-10-09 点击率:49
1、首先完成Proteus的安装以及Arduino库的安装和引入。(参考此前教程)
2、新建一个 Arduino工程。点击左上角的File——New Project,选择Arduino 328开发板。
3、工作区中出现Arduino的原理图。现在开始添加功能电路——添加温度传感器 DHT11。
点击左侧的P,选择元件。
4、在弹出的对话框中,输入DHT11,如下图:
选择右侧的 DHT11,点击右下角的OK
5、回到工作区的原理图位置,空白处点击鼠标左键,出现粉红色的待放置元件,再次点击左键。完成元件的放置。
6、完成DHT11的连线工作。(电源VDD,接地GND,数据DATA)
6.1接电源线。
左侧点击“Terminal Mode”——“Power”
在工作区,放置一个电源端子,并完成与VDD的连线。
6.2 接地。类似于电源端子的连接,“Terminal Mode”——“GROUND”。
6.3 数据接线。选择DEFAULT端子,完成与DATA接线口的连接。如下面两个图。
6.4 修改DEFAULT端子的属性。右键该端子,选择编辑属性。在String处,填写IO2.点确定。
7、增加串口模块。
同样的在设备库中(Pick Devices),搜索 COMPIM
8、放置COMPIM串口模块,并完成连线。如下图。
9、再放置虚拟终端,来观察串口输出的数据。
在左侧工具栏,选择“INSTRUMENTS”——VIRTUAL TERMINAL。
并完成连线如下图。
10、编写Arduino代码。进入Source Code模式,编写如下代码:
11、将课堂发送给大家的DHT11的库文件,解压后放置在Arduino安装目录下的Libraris目录下。(DHT11库文件也可以到FTP上下载)
11.1找到自己的Arduino安装目录。
点击Proteus的System——Compilers Configuration,找到Arduino AVR(Proteus)和Arduino AVR两个。
11.2 将DHT11库文件放到这两个目录的Libraries下。如下图:(两个都放一下)
12、开始编译运行。
点击左下角的三角箭头,开始编译仿真运行。如果代码编译成功,会显示 Compiled Successfully.
13、仿真成功。显示DHT11读取的数据。虚拟终端会显示从串口读来的数据。
14、修改传感器的值,查看读取数据的情况。
首先要关闭仿真。点击左下角的方块键。
然后在设计图中,右键DHT11传感器,点击“编辑属性”Edit Properties
修改其中的Actual Humidity(湿度值)和Actual Temp(温度值),点击“OK”
再次仿真运行,查看结果。
温湿度传感器仿真实验 第1张" title="proteus湿度传感器:Proteus 基于Arduino DHT11温湿度传感器仿真实验 第1张-传感器知识网"/>
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
使用1602显示DHT22的温湿度,精确到小数点的后一位
//
// DHT21使用范例
//单片机 AT89S52 或 STC89C52RC
//功能 串口发送温湿度数据 晶振 11.0592M 波特率 9600
//硬件 P2.0口为通讯口连接DHT22,DHT22的电源和地连接单片机的电源和地,单片机串口加MAX232连接电脑
//
#include
一、传感器概述
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由低电平反转为高电平。具体时序图如下:
由上述时序图,可以得到“启动传输”的驱动程序如下:
(二)命令集及“写一字节”程序
在启动程序之后,后续命令包括三个地址位(目前只支持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恢复为低电平。具体驱动程序如下: (三)“读一字节”驱动程序 在发布完一组测量命令之后,单片机要等待测量结束,这个过程大约需要10/80/120ms,分别对应8/12/14bit测量,确切时间由内部晶振速度决定,最多有-30%的变化。SHT10通过下拉DATA至电平并进入空闲模式表示测量结束。单片机在再次触发SCK时钟前必须等待这个“数据备妥”信号来读出数据。(默认温度测量14bit,湿度测量12bit),另外,还有一字节的CRC,用于循环冗余校验。湿度测量时序图如下: 根据上述湿度测量时序图可以类推温度测量时序图(区别在于默认情况下温度值比湿度值多2bit),并由时序图可写出具体控制时序,如下: ? 六、测量结果转换 测量结果转换过程中使用的参数与供电电压有关,总控制程序中的转换代码仅适用于5V供电时进行转换,其他工作电压下的转换关系如下图所示: ? 七、总控制程序 八、Proteus仿真图的连接及结果 ? ? ? ? 左肩理想右肩担当,君子不怨永远不会停下脚步! ? ? ? ? ? ? ? ? ? ? ?
我最近做项目,接触到了sht11温湿度传感器,分享给大家
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
#include
void LCD_init(void)
{
delay_n10us(10);
LCD_write_command(0x38);//设置8位格式,2行,5x7
delay_n10us(10);
LCD_write_command(0x0c);//整体显示,关光标,不闪烁
delay_n10us(10);
LCD_write_command(0x06);//设定输入方式,增量不移位
delay_n10us(10);
LCD_write_command(0x01);//清除屏幕显示
delay_n10us(100); //延时清屏,延时函数,延时约n个10us
}
void LCD_write_command(uchar dat)
{
delay_n10us(10);
LCD_RS=0; //指令
LCD_RW=0; //写入
LCD_E=1; //允许
LCD_DB=dat;
delay_n10us(10); //实践证明,我的LCD1602上,用for循环1次就能完成普通写指令。
LCD_E=0;
delay_n10us(10); //实践证明,我的LCD1602上,用for循环1次就能完成普通写指令。
}
void LCD_write_data(uchar dat)
{
delay_n10us(10);
LCD_RS=1; //数据
LCD_RW=0; //写入
LCD_E=1; //允许
LCD_DB=dat;
delay_n10us(10);
LCD_E=0;
delay_n10us(10);
}
void LCD_disp_char(uchar x,uchar y,uchar dat)
{
uchar address;
if(y==1)
address=0x80+x;
else
address=0xc0+x;
LCD_write_command(address);
LCD_write_data(dat);
}
void LCD_disp_str(uchar x,uchar y,uchar *str)
{
uchar address;
if(y==1)
address=0x80+x;
else
address=0xc0+x;
LCD_write_command(address);
while(*str!='�')
{
LCD_write_data(*str);
str++;
}
}
void delay_n10us(uint n) //延时n个10us@12M晶振
{
uint i;
for(i=n;i>0;i--)
{
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
}
}
/
void s_transstart(void); //启动传输函数
void s_connectionreset(void); //连接复位函数
char s_write_byte(unsigned char value);//DHT90写函数
char s_read_byte(unsigned char ack); //DHT90读函数
char s_measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode);//测量温湿度函数
void calc_dht90(float *p_humidity ,float *p_temperature);//温湿度补偿
void s_transstart(void)
// generates a transmission start
// _____ ________
// data: |_______|
// ___ ___
// SCK : ___| |___| |______
{
DATA=1; SCK=0; //Initial state
_nop_();
SCK=1;
_nop_();
DATA=0;
_nop_();
SCK=0;
_nop_();_nop_();_nop_();
SCK=1;
_nop_();
DATA=1;
_nop_();
SCK=0;
}
void s_connectionreset(void)
// communication reset: DATA-line=1 and at least 9 SCK cycles followed by transstart
// _____________________________________________________ ________
// data: |_______|
// _ _ _ _ _ _ _ _ _ ___ ___
// SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______| |___| |______
{
unsigned char i;
DATA=1; SCK=0; //Initial state
for(i=0;i
char s_read_byte(unsigned char ack)
// reads a byte form the Sensibus and gives an acknowledge in case of "ack=1"
{
unsigned char i,val=0;
DATA=1; //release DATA-line
for (i=0x80;i>0;i/=2) //shift bit for masking
{ SCK=1; //clk for SENSI-BUS
if (DATA) val=(val | i); //read bit
_nop_();_nop_();_nop_(); //pulswith approx. 3 us
SCK=0;
}
if(ack==1)DATA=0; //in case of "ack==1" pull down DATA-Line
else DATA=1; //如果是校验(ack==0),读取完后结束通讯
_nop_();_nop_();_nop_(); //pulswith approx. 3 us
SCK=1; //clk #9 for ack
_nop_();_nop_();_nop_(); //pulswith approx. 3 us
SCK=0;
_nop_();_nop_();_nop_(); //pulswith approx. 3 us
DATA=1; //release DATA-line
return val;
}
char s_measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode)
// makes a measurement (humidity/temperature) with checksum
{
unsigned error=0;
unsigned int i;
s_transstart(); //transmission start
switch(mode){ //send command to sensor
case TEMP : error+=s_write_byte(MEASURE_TEMP); break;
case HUMI : error+=s_write_byte(MEASURE_HUMI); break;
default : break;
}
for (i=0;i
下一篇: PLC、DCS、FCS三大控
上一篇: 电气控制线路图控制原