www.pudn.com > SHT11.rar > SHT-OWNI-1.3.c, change:2007-11-29,size:12523b


 #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++); //延时 
    
   
   } 
}