⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sht-owni-1.3.c

📁 温湿度传感器 sht11 仿真程序下载
💻 C
字号:
 #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()
{

   int  i;

 	csh();	   //初始化串口
    while(1)
	{

   		 text_jishuan_temp11();
   initlcd_char();//初始化
   clear();      //清屏
   xianshi();
    text_232_main();
	   text_baojing();//报警
  	 for (i=0;i<100;i++); //延时
   
  
   }
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -