标题:
SHT11温湿度传感器仿真和代码
[打印本页]
作者:
takahs62
时间:
2017-4-30 14:07
标题:
SHT11温湿度传感器仿真和代码
基于SHT11的温湿度传感器的仿真,有需要的下载
0.png
(33.12 KB, 下载次数: 68)
下载附件
2017-4-30 17:18 上传
0.png
(77.44 KB, 下载次数: 74)
下载附件
2017-4-30 17:17 上传
单片机源代码:
#include <reg52.h> //头文件
#include <intrins.h>
#include <stdio.h> //
#include <math.h> //Keil library
//**************************************
sbit DATA =P1^1;//数据
sbit SCK=P1^0;//时钟
#define TEMP_ML 0x03 //000 0001 1 温度命令
#define HUMI_ML 0x05 //000 0010 1 温度命令
unsigned char error ;//全局错误变量
unsigned char ack ;//全局应答变量
//float temp_zi ;//全局应答变量
//float humi_zi ;//全局应答变量
unsigned char temp_h ;//全局应答变量
unsigned char temp_LL ;//全局应答变量
#define uchar unsigned char //定义一下方便使用
#define uint unsigned int
#define ulong unsigned long
unsigned int recs=0;//接收次数
const unsigned char X_WD[11]="当前温度:+-";
const unsigned char X_SD[10]="当前湿度:";
const unsigned char S_WD[11]="报警温度:+-";
const unsigned char S_SD[10]="报警湿度:";
const unsigned char SHUO[15]="0123456789.%RH";
const unsigned char DU_ZHI[6]="℃ ";
int xts_zi=0 ;//温度值
int xtg_zi=0 ;//温度个位值
int xtd_zi=0 ;//温度点值
int xss_zi=0 ;//湿度值
int xsg_zi=0 ;//湿度个位值
int xsd_zi=0 ;//湿度点值
int sts_zi=6 ;//温度值
int stg_zi=0 ;//温度个位值
int std_zi=0 ;//温度点值
int sss_zi=9 ;//湿度值
int ssg_zi=0 ;//湿度个位值
int ssd_zi=0 ;//湿度点值
int szf=1 ;//设正负
int xzf=1 ;//显正负
//**************************************
sbit E_CLK =P0^7;//起始信号
sbit RW_SID=P0^6;//H:读 L:写
sbit RS_CS =P0^5;// H:数据 L:命令
sbit soud =P0^0;// 声音
//*******************************基本驱动程
void busyaaa_check(void)
{
uchar keyx;
P2=0XFF;
while(1)
{
RS_CS=0;//命令
RW_SID=1;//读
E_CLK=1;
keyx=P2;
E_CLK=0;
if((keyx&0X80)==0X00)
break;
}
}
void wcom(unsigned char com)//并口写命令
{
busyaaa_check();//忙检测
RS_CS=0; //以命令方式
RW_SID=0;//写
E_CLK=1;//使能信号开始
//nop();
P2=com;//送出数据
//_nop_();
E_CLK=0;//不使能
}
void wdata(unsigned char dat)//并口写数据
{
busyaaa_check();//忙检测
RS_CS=1;//以数据方式
RW_SID=0;//写
E_CLK=1;//使能
// nop();
P2=dat;//写入数据
// nop();//延时
E_CLK=0;//不使能
}
//
//**************************系统初始化
//**************************
void initlcd_char(void)
{
wcom(0x30);//基本指令
wcom(0x0C);//0000,1100 游标显示关 整体显示开
// wcom(0x01);//0000,0001 清除显示RAM
wcom(0x02);//0000,0010 显示RAM 地址归位
wcom(0x80);//1000,0000 设定显示RAM 地址到地址计数器
wcom(0x06);//0000 0110 右移位
wcom(0x0c);//0000 1100开显示
}
//****清屏******************
void clear(void)
{
wcom(0x30);//基本指令
wcom(0x01);//清屏
}
//****************************调用字库显示汉字
//***************************************
//printf 函数用到的函数。要在STDIO.H 中将原有的PUTCHAR 函数屏蔽。
//写汉字要在基本指令集下进行。
void putchara(unsigned char cc)
{
switch(cc)
{
case 'c' : //clear
wcom(0x01);
break ;
case 'f' : //first line
wcom(0x80);
break ;
case 's' : //second line
wcom(0x90);
break ;
case 't' : //third line
wcom(0x88);
break ;
case 'd' : //fourth line
wcom(0x98);
break ;
default :
wdata(cc); //data
break;
}
}
//--显示字---
xian_zhi_t()
{
int i;
for (i=0;i<9;i++)
wdata(X_WD[i]);
if(xzf==1)
wdata(X_WD[9]);
else
wdata(X_WD[10]);
wdata(SHUO[xts_zi]);//十位
wdata(SHUO[xtg_zi]);//个位
wdata(SHUO[10]);//点
wdata(SHUO[xtd_zi]);//点值
for (i=0;i<2;i++)
wdata(DU_ZHI[i]);
}
/////////////////
xian_zhi_s()
{
int i;
for (i=0;i<9;i++)
wdata(X_SD[i]);
wdata(SHUO[xss_zi]);//十位
wdata(SHUO[xsg_zi]);//个位
wdata(SHUO[10]);//点
wdata(SHUO[xsd_zi]);//点值
for (i=11;i<14;i++) //RH
wdata(SHUO[i]);
}
//--设定---
set_zhi_t()
{
int i;
for (i=0;i<9;i++)
wdata(S_WD[i]);
if(szf==1)
wdata(S_WD[9]);
else
wdata(S_WD[10]);
wdata(SHUO[sts_zi]);//十位
wdata(SHUO[stg_zi]);//个位
wdata(SHUO[10]);//点
wdata(SHUO[std_zi]);//点值
for (i=0;i<2;i++)
wdata(DU_ZHI[i]);
}
//////////////
set_zhi_s()
{
int i;
for (i=0;i<9;i++)
wdata(S_SD[i]);
wdata(SHUO[sss_zi]);//十位
wdata(SHUO[ssg_zi]);//个位
wdata(SHUO[10]);//点
wdata(SHUO[ssd_zi]);//点值
for (i=11;i<14;i++) //RH
wdata(SHUO[i]);
}
/////////////////
//////////////////////
char read() //读一个字节 返回应答信号
//----------------------------------------------------------------------------------
// reads a byte form the Sensibus and gives an acknowledge in case of "ack=1"
{
unsigned char i,val=0;
temp_LL=0;
temp_h=0;
DATA=1; //释放数据总线
for (i=0x80;i>0;i/=2) //位移8位
{ SCK=1; //上升沿读入
if (DATA) val=(val | i); //确定值
SCK=0;
}
DATA=0; //读应答信号,有应答为1,为应答为0 通过CPU下拉为应答
SCK=1; //第9个脉冲
_nop_(); _nop_(); _nop_(); //pulswith approx. 5 us
SCK=0;
DATA=1; //释放数据总线
temp_h=val;
val=0;
////低8位/////////////////////////////
DATA=1; //释放数据总线
for (i=0x80;i>0;i/=2) //位移8位
{ SCK=1; //上升沿读入
if (DATA) val=(val | i); //确定值
SCK=0;
}
DATA=1;//0; //不需要应答 通过CPU下拉为应答
SCK=1; //第9个脉冲
_nop_(); _nop_(); _nop_(); //pulswith approx. 5 us
SCK=0;
DATA=1; //释放数据总线
temp_LL=val;
}
////////////
char write(unsigned char value) //写一个字节 返回应答信号
//---------------------------------------------------------
{
unsigned char i ;
ack=0;
for (i=0x80;i>0;i/=2) //释放数据总线
{ if (i & value) DATA=1; //写入值
else DATA=0;
SCK=1; //上升沿写入
_nop_(); _nop_(); _nop_(); //延时
SCK=0;
}
DATA=1; //释放数据总线
SCK=1; //第9个脉冲
if (DATA==1) ack=1;
//读应答信号
SCK=0;
return ack; //error=1 表示没有应答
}
////////
void start(void) //启动
//--------------------------------------------------------
{
DATA=1; SCK=0; //数据为1,SCK=0
_nop_();
SCK=1; //第一个脉冲
_nop_();
DATA=0; //数据跌落
_nop_ ();
SCK=0; //完成一个脉冲
_nop_(); _nop_(); _nop_();
SCK=1; //再一个脉冲
_nop_();
DATA=1; //数据变为1
_nop_();
SCK=0; //完成该脉冲
}
//////////////////////////////////
void sht_rest(void) //复位
{
unsigned char i;
DATA=1; SCK=0; //数据为1 时钟为0
for(i=0;i<9;i++) //9 个脉冲为 复位
{ SCK=1;
SCK=0;
}
start(); //启动
}
////////////////////////////////
///////
//测量温度或者是温度,返回校验值
text_a(unsigned char ml)
{
unsigned int i;
start(); //启动
write(ml);//写入测温度
if (ack==1)
{
sht_rest() ;//复位
write(ml);//写入测温度
}
//判断是否处于忙
// DATA=1;//释放数据总线
for (i=0;i<65535;i++) if(DATA==0) break;
read();//读温度
}
///////
text_jishuan_temp11()
{
error=0;
ack=0;
sht_rest() ;//复位
text_a(TEMP_ML);
text_jishuan_temp();
text_a(HUMI_ML);
text_jishuan_humi();
}
/////
//////////////
text_jishuan_temp()
{
float aa=0,bb=0,temp_zi;
int abcd=0;
aa=(float)temp_h*256+(float)temp_LL;
temp_zi=0.01*aa-40;
//
xzf=1;
if (temp_zi<0)
{ xzf=0;
temp_zi=-temp_zi ;
}
temp_zi=temp_zi*10;
abcd=(int)temp_zi;
xts_zi=abcd/100;
abcd=abcd%100;
xtg_zi=abcd/10;
abcd=abcd%10;
xtd_zi=abcd/1;
}
/////////////
text_jishuan_humi()
{
float aa=0,bb=0,humi_zi;
int abcd=0;
aa=(float)temp_h*256+(float)temp_LL;
bb=aa*aa*2.8/1000000;
aa=0.0405*aa;
aa=aa-4-bb;
humi_zi=aa;
//
humi_zi=humi_zi*10;
abcd=(int)humi_zi;
xss_zi=abcd/100;
abcd=abcd%100;
xsg_zi=abcd/10;
abcd=abcd%10;
xsd_zi=abcd/1;
}
////
//-----显示---
xianshi()
{
putchara('f');//在第一行显示
xian_zhi_t();
putchara('s');//在第二行显示
xian_zhi_s();
putchara('t');//在第三行显示
set_zhi_t();
putchara('d');//在第四行显示
set_zhi_s();
}
/////////////////////////////////
///////////////////////////////////////////
///////////////////////////////////////////
////接收给值/////
void rece(int cc)
{
switch(cc)
{
case 1 : //clear
{ if (SBUF==0XCC) break;
else
{recs=0; //判断头对不对
break;
}
}
case 2 : //clear
szf=(int) SBUF;
break;
case 3 : //clear
sts_zi=(int) SBUF;
break;
case 4 : //clear
stg_zi=(int) SBUF;
break;
case 5 : //clear
std_zi=(int) SBUF;
break;
case 6 : //clear
{ if (SBUF==0xdd) break;
else
{recs=recs-6;
break;
}
}
case 7 : //clear
sss_zi=(int) SBUF;
break;
case 8 : //clear
ssg_zi=(int) SBUF;
break;
case 9 : //clear
ssd_zi=(int) SBUF;
break;
}
}
///////////////////////////////
void text_232_main()
{
TI=0; //清发送完标志
SBUF=0xaa; //AA头码
while(!TI); //等发送完
TI=0;
SBUF=(char) xzf ;//发送正负
while(!TI); //等发送完
TI=0;
SBUF=(char) xts_zi ;//发送正负
while(!TI); //等发送完
TI=0;
SBUF=(char) xtg_zi ;//发送正负
while(!TI); //等发送完
TI=0;
SBUF=(char) xtd_zi ;//发送正负
while(!TI); //等发送完
TI=0;
SBUF=0xbb ;//发送正负
while(!TI); //等发送完
TI=0;
SBUF=(char) xss_zi ;//发送正负
while(!TI); //等发送完
TI=0;
SBUF=(char) xsg_zi ;//发送正负
while(!TI); //等发送完
TI=0;
SBUF=(char) xsd_zi ;//发送正负
while(!TI); //等发送完
TI=0;
}
///////////////
void intrr() interrupt 4 //接收和发送中断
{
char temp;
if(RI)
{
RI=0;
recs++;
rece(recs); //接收给值
while(recs==9) recs=0;
temp=SBUF;
P2=temp;
}
if(TI)
{
P0=SBUF ;
}
}
//初始化串行口
void csh()
{
SCON=0X50; //允许接收 工作方式1
TI=0; //清发送完成标志
RI=0; //清接收完成标志
PCON=0; //波特率不加倍
TH1=0xFD; //初始波特率的值
TL1=0XFD;
TMOD=0X20; //定时1工作方式1,自动装载定时器值
EA=1; //允许总中断
ET1=0; //不允许定时器0中断
ES=1; //允许串口中断
TR1=1; //启动TM1
}
/////////////////////////////////
//////////
text_baojing()//报警
{
int temp1=0,temp2=0;
temp1=xss_zi*100+xsg_zi*10+xsd_zi;
temp2=sss_zi*100+ssg_zi*10+ssd_zi;
while ((temp1-temp2)>0)
{ speek_cl();
break;
}
while (xzf>szf) //当显示为正,设定为负,立即报
{ speek_cl();
break;
}
temp1=xts_zi*100+xtg_zi*10+xtd_zi;
temp2=sts_zi*100+stg_zi*10+std_zi;
if ((xzf>0)&&(szf>0)) //如果显示大于0,设定也大于0
{
while ((temp1-temp2)>0)
{
speek_cl();
break;
}
}
else
{
while ((temp2-temp1)>0)
{
speek_cl();
break;
}
}
}
////////
///////////////////////////////
/////////////////////////////////
speek_cl()
{
int i=0,j=0;
for(i=0;i<500;i++)
{ soud=!soud ;
for(j=0;j<30;j++);
}
}
///////////////////////
main()
{
…………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
下载:
SHT11温湿度传感器仿真.rar
(76.65 KB, 下载次数: 148)
2017-4-30 14:06 上传
点击文件名下载附件
Proteus
下载积分: 黑币 -5
作者:
江青月明
时间:
2017-5-16 15:02
楼主好样的!!!
作者:
kkr
时间:
2017-6-22 17:14
楼主有电路分析论文吗?
作者:
fortuneyang
时间:
2019-4-12 23:49
谢谢楼主分享!
作者:
1511wgg
时间:
2019-5-31 03:37
怎么都是半截的 啊
作者:
a7938216
时间:
2019-11-18 12:43
楼主有电路图的解释吗
作者:
a7938216
时间:
2019-11-21 15:55
有没有电路分析的文档啊
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1