基于SHT11的温湿度传感器的仿真,有需要的下载
单片机源代码:
- #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)
|