单点温湿度采集LCD显示Word下载.docx
《单点温湿度采集LCD显示Word下载.docx》由会员分享,可在线阅读,更多相关《单点温湿度采集LCD显示Word下载.docx(21页珍藏版)》请在冰点文库上搜索。
R/W为读写信号线,高电平时进行读操作,低电平时进行写操作。
当RS和R/W共同为低电平时可以写入指令或者显示地址,当RS为低电平R/W为高电平时可以读忙信号,当RS为高电平R/W为低电平时可以写入数据。
第6脚:
E端为使能端,当E端由高电平跳变成低电平时,液晶模块执行命令。
第7~14脚:
D0~D7为8位双向数据线。
1602字符型液晶基本指令
序号
指令
RS
R/W
DB7
DB6
DB5
DB4
DB3
DB2
DB1
DB0
1
清显示
2
光标返回
﹣
3
置输入模式
I/D
S
4
显示开/关控制
D
C
B
5
光标或字符移位
S/C
R/L
6
功能设置
L
N
F
7
设置字符发生存储器地址
字符发生存储器地址
8
设置数据存储器地址
显示数据存储器地址
9
读忙标志或地址
BF
计数器地址
10
写数据到RAM
要写的数据内容
11
从RAM读数据
读出的数据内容
电路说明:
LCD1602数据引脚依次与P0口相应位相接,实现控制命令、温湿度数据传输。
第3脚为液晶显示器对比度调整端直接接地时对比度高可能会产生“鬼影”,故使其通过一个10K的电位器接地,调整为合适的对比度。
设计选用的芯片为两行显示,第一行显示:
“TEMP:
C”,第二行显示:
“HUMI:
RH”,显示范围均为000.0~999.9。
图3、显示电路
5.3温湿度采集电路
SHT11温湿度传感器引脚说明如下:
(1)GND:
接地端;
(2)DATA:
双向串行数据线;
(3)SCK:
串行时钟输入;
(4)VDD电源端:
0.4~5.5V电源端;
(5~8)NC:
空管脚。
参数计算:
(1)湿度值输出
SHT11可通过I2C总线直接输出数字量湿度值,其输出特性呈一定的非线性,为了补偿湿度传感器的非线性,可按如下公式修正湿度值:
RHlinear=c1+c2SORH+c3SORH2
式中,SORH为传感器相对湿度测量值,系数取值如下:
12位:
SORH:
c1=-4,c2=0.0405,c3=-2.8×
10-6
8位:
c1=-4,c2=0.648,c3=-7.2×
10-4
(2)温度值输出
由于SHT11温度传感器的线性非常好,故可用下列公式将温度数字输出转换成实际温度值:
T=d1+d2SOT
当电源电压为5V,且温度传感器的分辨率为14位时,d1=-40d2=0.01,当温度传感器的分辨率为12位时,d1=-40d2=0.04。
(3)露点计算
空气的露点值可根据相对湿度和温度值来得出,具体的计算公式如下:
LogEW=(0.66077+7.5T/(237.3+T)+[log10(RH)-2]
Dp=[(0.66077-logEW)×
237.3]/(logEW-8.16077)
SHT11传感器用户命令:
命
令
编
码
说
明
测量温度
00011
温度测量
测量湿度
00101
湿度测量
读寄存器状态
00111
“读”状态寄存器
写寄存器状态
00110
“写”状态寄存器
软启动
11110
重启芯片,清除状态记录器的错误记录11毫秒后进入下一个命令
(1)传输开始
初始化传输时,应首先发出“传输开始”命令,该命令可在SCK为高时使DATA由高电平变为低电平,并在下一个SCK为高时将DATA升高。
接下来的命令顺序包含三个地址位(目前只支持“000”)和5个命令位,当DATA脚的ack位处于低电位时,表示SHT11正确收到命令。
(2)连接复位顺序
如果与SHT11传感器的通讯中断,下列信号顺序会使串口复位:
即当DATA线处于高电平时,触发SCK9次以上(含9次),此后应接着发一个“传输开始”命令。
SHT11状态寄存器类型及说明:
位
类型
缺
省
保留
读
工检限(低电压检查)
X
只用于试验,不可以使用
读/写
加热
关
不从OTP重下载
重下载
'
1'
=8位相对湿度,12位温度分辨率。
0'
=12位相对湿度,14位温度分辨率
12位相对湿度,14位温度
单片机上电复位后,单片机按照一定时钟频率从P1.6口发出用户命令,SHT11根据命令向P1.7口串行输出温度和湿度数据。
图4、温湿度采集电路
6、主流程图
7、体会与感想
这是这次课程设计中独立完成项目,相对于前一个公共项目,独立完成的题目要求更高了。
上一次只设计了硬件图没有进行仿真和实物制作,这次不仅要求程序仿真而且鼓励做出硬件图。
在这次课程设计中,我对于proteus的使用更加熟练了,经过自己努力和同学的帮助顺利完成了硬件图和仿真。
下面谈一下我在设计中遇到的问题。
首先是元件选择。
经过多方查阅资料确定了温湿度传感器型号SHT11,但是在老师给的proteus中元件库中不含有所需元件,这让我很是头疼。
最后有同学说自己下载的proteus7.7版本中有所需元件,才解决了这个问题。
设计中的其他部分比较好做,程序也顺利的编译通过,但是把HEX文件下载到元件中仿真时却总是出现错误。
查资料,问同学,最终才知道是自己把元件的<
TEXT>
更改过才出现问题的。
我先是把元件的“ExcludefromSimulation”选项勾上,这样仿真就不会报错了,但是却不会正常仿真,最后我把所有报错的元件删除重新连了一遍就不再会报错了,问了同学才知道元件的说明部分不可以随意改动的,它与元件功能实现有关。
这次课程设计让我受益匪浅,不仅使我熟练掌握了proteus的用法,而且学到了很多知识,锻炼了动手能力和编程能力,在实践中加深了对单片机功能的认识。
附1、硬件原理图
附2、程序清单
#include<
reg52.h>
#include<
intrins.h>
#defineucharunsignedchar
#defineuintunsignedint
#definenoACK0//继续传输数据,用于判断是否结束通讯
#defineACK1//结束数据传输;
//SHT11地址命令读1/写0
#defineMEASURE_TEMP0x03//00000011
#defineMEASURE_HUMI0x05//00000101
#defineRESET0x1e//00011110
enum{TEMP,HUMI};
//测量模式:
温度/湿度
sbitLcdRs=P2^4;
sbitLcdRw=P2^5;
sbitLcdEn=P2^6;
sfrDBPort=0x80;
//P0
sbitSCK=P3^0;
sbitDATA=P3^1;
chars_write_byte(ucharvalue)//SHT11写字节程序
{
uchari,error=0;
for(i=0x80;
i>
0;
>
=1)//高位为1,循环右移
{
if(i&
value)DATA=1;
//和要发送的数相与,结果为发送的位
elseDATA=0;
SCK=1;
_nop_();
_nop_();
//延时3us
SCK=0;
}
DATA=1;
//释放数据线
SCK=1;
error=DATA;
//检查应答信号,确认通讯正常
_nop_();
SCK=0;
returnerror;
//error=1通讯错误
}
chars_read_byte(ucharack)//SHT11读字节程序
uchari,val=0;
for(i=0x80;
if(DATA)val=(val|i);
//读一位数据线的值
DATA=!
ack;
//如果是校验,读取完后结束通讯;
returnval;
voids_transstart(void)//启动传输SHT11
//generatesatransmissionstart
DATA=1;
//准备
DATA=0;
voids_connectionreset(void)//SHT11连接复位
//communicationreset:
DATA-line=1andatleast9SCKcyclesfollowedbytransstart
uchari;
for(i=0;
i<
9;
i++)//DATA保持高,SCK时钟触发9次,发送启动传输,通迅即复位
s_transstart();
//启动传输
chars_softreset(void)//SHT11软复位程序
//resetsthesensorbyasoftreset
ucharerror=0;
s_connectionreset();
//启动连接复位
error+=s_write_byte(RESET);
//发送复位命令
//温湿度测量
chars_measure(uchar*p_value,uchar*p_checksum,ucharmode)
//进行温度或者湿度转换,由参数mode决定转换内容;
unsignederror=0;
uinti;
switch(mode)//选择发送命令
caseTEMP:
error+=s_write_byte(0x03);
break;
//测量温度
caseHUMI:
error+=s_write_byte(0x05);
//测量湿度
default:
for(i=0;
65535;
i++)if(DATA==0)break;
//等待测量结束
if(DATA)error+=1;
//如果长时间数据线没有拉低,说明测量错误
*(p_value)=s_read_byte(ACK);
//读第一个字节,高字节(MSB)
*(p_value+1)=s_read_byte(ACK);
//读第二个字节,低字节(LSB)
*p_checksum=s_read_byte(noACK);
//readCRC校验码
//error=1通讯错误
//温湿度值标度变换及温度补偿
voidcalc_sth10(float*p_humidity,float*p_temperature)
constfloatC1=-4.0;
//12位湿度精度修正公式
constfloatC2=+0.0405;
constfloatC3=-0.0000028;
constfloatT1=+0.01;
//14位温度精度5V条件修正公式
constfloatT2=+0.00008;
floatrh=*p_humidity;
//rh:
12位湿度
floatt=*p_temperature;
//t:
14位温度
floatrh_lin;
//rh_lin:
湿度linear值
floatrh_true;
//rh_true:
湿度ture值
floatt_C;
//t_C:
温度℃
t_C=t*0.01-40;
//补偿温度
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;
//湿度最大修正
if(rh_true<
0.1)rh_true=0.1;
//湿度最小修正
*p_temperature=t_C;
//返回温度结果
*p_humidity=rh_true;
//返回湿度结果
bitLCD_Bz()//测试LCD忙碌状态
{
bitresult;
LcdRs=0;
LcdRw=1;
LcdEn=1;
result=(bit)(P0&
0x80);
LcdEn=0;
returnresult;
voidLCD_Write(bitstyle,ucharinput)//向LCD写入命令或数据
{//style=0为命令,1为数据
while(LCD_Bz());
LcdRs=style;
LcdRw=0;
DBPort=input;
//注意顺序
//设置LCD模式
voidLCD_SetMode(ucharMode)
LCD_Write(0,Mode);
voidLCD_Initial()//初始化LCD
LCD_Write(0,0x38);
//8位数据端口,2行显示,5*7点阵
LCD_SetMode(0x0c);
//开启显示,无光标
LCD_Write(0,0x01);
//清屏
LCD_SetMode(0x06);
//字符地址递增,画面不动
//液晶字符输入的位置
voidGotoXY(ucharx,uchary)
if(y==0)
LCD_Write(0,0x80|x);
//第一行第x个
if(y==1)
LCD_Write(0,0xc0|x);
//第二行第x个
//将字符输出到液晶显示
voidPrint(uchar*str)
while(*str!
='
\0'
)
{
LCD_Write(1,*str);
str++;
//延时函数
voiddelay(intz)//z为毫秒数
intx,y;
for(x=z;
x>
x--)
for(y=125;
y>
y--);
voidmain()
uinttemp,humi;
uinthumi_val_i,temp_val_i;
//测量结果
floathumi_val_f,temp_val_f;
//修正结果
ucharerror;
//用于检验是否出现错误
ucharchecksum;
//CRC
ucharwendu[6];
//用于记录温度
ucharshidu[6];
//用于记录湿度
LCD_Initial();
//初始化液晶
GotoXY(0,0);
//选择温度显示位置
Print("
TEMP:
%C"
);
//5格空格
GotoXY(0,1);
//选择湿度显示位置
HUMI:
%RH"
//启动连接复位
while
(1)
error=0;
//初始化error=0,即没有错误
error+=s_measure((uchar*)&
temp_val_i,&
checksum,TEMP);
//温度测量
humi_val_i,&
checksum,HUMI);
//湿度测量
if(error!
=0)s_connectionreset();
////如果发生错误,系统复位
else
{
humi_val_f=(float)humi_val_i;
//转换为浮点数
temp_val_f=(float)temp_val_i;
calc_sth10(&
humi_val_f,&
temp_val_f);
//修正相对湿度及温度
temp=temp_val_f*10;
humi=humi_val_f*10;
GotoXY(5,0);
//设置温度显示位置
wendu[0]=temp/1000+'
;
//温度百位
wendu[1]=temp%1000/100+'
//温度十位
wendu[2]=temp%100/10+'
//温度个位
wendu[3]=0x2E;
//小数点
wendu[4]=temp%10+'
//温度小数点后第一位
Print(wendu);
//输出温度
GotoXY(5,1);
//设置湿度显示位置
shidu[0]=humi/1000+'
//湿度百位
shidu[1]=humi%1000/100+'
//湿度十位
shidu[2]=humi%100/10+'
//湿度个位
shidu[3]=0x2E;
shidu[4]=humi%10+'
//湿度小数点后第一位
Print(shidu);
//输出湿度
}
delay(800);
//等待足够长的时间,以现行下一次转换