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

📄 shtxx_sample_code_ok_01.c

📁 这是单片机驱动温湿度传感器SHT11温湿度传感器的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
    retc=0; 
  	SDA=1;             /*置数据线为输入方式*/
  	for(BitCnt=0;BitCnt<8;BitCnt++)
    {
    	_Nop();           
        SCL=0;       /*置时钟线为低,准备接收数据位*/
        _Nop();
        _Nop();         /*时钟低电平周期大于4.7μs*/
        _Nop();
        _Nop();
        _Nop();
        SCL=1;       /*置时钟线为高使数据线上数据有效*/
        _Nop();
        _Nop();
        retc=retc<<1;
        if(SDA==1)retc=retc+1; /*读数据位,接收的数据位放入retc中 */
        _Nop();
        _Nop(); 
	}
  	SCL=0;    
  	_Nop();
  	_Nop();
  	return(retc);
}


void Ack_I2c(bit a)		//主控器进行应答信号
{
  
  	if(a==0)SDA=0;     /*在此发出应答或非应答信号 */
    else SDA=1;
  	_Nop();
  	_Nop();
  	_Nop();      
  	SCL=1;
    _Nop();
    _Nop();              //时钟低电平周期大于4μ
    _Nop();
    _Nop();
    _Nop();  
 	SCL=0;                /*清时钟线,钳住I2C总线以便继续接收*/
    _Nop();
    _Nop();    
}
//bit ISendStr(uchar sla,uchar suba,uchar *s,uchar no)		//向有子地址器件发送多字节数据函数 
//子地址为8位的数据传送
bit ISendStr_8(uchar add,uchar son_add,uchar dat)		//向子地址为8位的器件发送多字节数据函数 
{
	Start_I2c();               /*启动总线*/
   	SendByte(add);            /*发送器件地址*/
    if(ack==0)return(0);
	SendByte(son_add);            /*发送器件子地址*/
    if(ack==0)return(0);
    SendByte(dat);               /*发送数据*/
    if(ack==0)return(0);
 	Stop_I2c();                 /*结束总线*/ 
  	return(1);
}
//子地址为16位的数据传送
bit ISendStr_16(uchar add,uint son_add,uchar dat)		//向子地址为16位的器件发送多字节数据函数 
{
	Start_I2c();               /*启动总线*/
   	SendByte(add);            /*发送器件地址*/
    if(ack==0)return(0);
   	SendByte(son_add/256);            /*发送器件子地址*/
    if(ack==0)return(0);
	SendByte(son_add%256);            /*发送器件子地址*/
    if(ack==0)return(0);
    SendByte(dat);               /*发送数据*/
    if(ack==0)return(0);
 	Stop_I2c();                 /*结束总线*/ 
  	return(1);
}



//bit IRcvStr(uchar sla,uchar suba,uchar *s,uchar no)		//向有子地址器件读取多字节数据函数
//子地址为8位的数据传送
uchar IRcvStr_8(uchar add,uchar son_add)		//向子地址为8位的器件读取多字节数据函数
{

	uchar i;
   	Start_I2c();               /*启动总线*/
   	SendByte(add);            /*发送器件地址*/
 	SendByte(son_add);            /*发送器件子地址2*/
   	Start_I2c();
   	SendByte(add+0x01);
   	i=RcvByte();
   	Ack_I2c(1);                 /*发送非应位*/
 	Stop_I2c();                    /*结束总线*/ 
 	return (i);
}
//子地址为16位的数据传送
uchar IRcvStr_16(uchar add,uint son_add)		//向子地址为16位的器件读取多字节数据函数
{

	uchar i;
   	Start_I2c();               /*启动总线*/
   	SendByte(add);            /*发送器件地址*/
   	SendByte(son_add/256);            /*发送器件子地址1*/
 	SendByte(son_add%256);            /*发送器件子地址2*/
   	Start_I2c();
   	SendByte(add+0x01);
   	i=RcvByte();
   	Ack_I2c(1);                 /*发送非应位*/
 	Stop_I2c();                    /*结束总线*/ 
 	return (i);
}


//----------------------------------------------------------------------------------
char s_write_byte(unsigned char value)
//----------------------------------------------------------------------------------
// writes a byte on the Sensibus and checks the acknowledge 
{ 
  unsigned char i,error=0;  
  for (i=0x80;i>0;i/=2)             //shift bit for masking
  { if (i & value) DATA=1;          //masking value with i , write to SENSI-BUS
    else DATA=0;                        
    SCK=1;                          //clk for SENSI-BUS
    _nop_();_nop_();_nop_();        //pulswith approx. 5 us  	
    SCK=0;
  }
  DATA=1;                           //release DATA-line
  SCK=1;                            //clk #9 for ack 
  error=DATA;                       //check ack (DATA will be pulled down by SHT11)
  SCK=0;        
  return error;                     //error=1 in case of no acknowledge
}

//----------------------------------------------------------------------------------
char s_read_byte(unsigned char ack)
//----------------------------------------------------------------------------------
// reads a byte form the Sensibus and gives an acknowledge in case of "ack=1" 
{ 
  unsigned char i,val=0;
  DATA=1;                           //release DATA-line
  for (i=0x80;i>0;i/=2)             //shift bit for masking
  { SCK=1;                          //clk for SENSI-BUS
    if (DATA) val=(val | i);        //read bit  
    SCK=0;  					 
  }
  DATA=!ack;                        //in case of "ack==1" pull down DATA-Line
  SCK=1;                            //clk #9 for ack
  _nop_();_nop_();_nop_();          //pulswith approx. 5 us 
  SCK=0;						    
  DATA=1;                           //release DATA-line
  return val;
}

//----------------------------------------------------------------------------------
void s_transstart(void)
//----------------------------------------------------------------------------------
// generates a transmission start 
//       _____         ________
// DATA:      |_______|
//           ___     ___
// SCK : ___|   |___|   |______
{  
   DATA=1; SCK=0;                   //Initial state
   _nop_();
   SCK=1;
   _nop_();
   DATA=0;
   _nop_();
   SCK=0;  
   _nop_();_nop_();_nop_();
   SCK=1;
   _nop_();
   DATA=1;		   
   _nop_();
   SCK=0;		   
}

//----------------------------------------------------------------------------------
void s_connectionreset(void)
//----------------------------------------------------------------------------------
// communication reset: DATA-line=1 and at least 9 SCK cycles followed by transstart
//       _____________________________________________________         ________
// DATA:                                                      |_______|
//          _    _    _    _    _    _    _    _    _        ___     ___
// SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______|   |___|   |______
{  
  unsigned char i; 
  DATA=1; SCK=0;                    //Initial state
  for(i=0;i<9;i++)                  //9 SCK cycles
  { SCK=1;
    SCK=0;
  }
  s_transstart();                   //transmission start
}

//----------------------------------------------------------------------------------
char s_softreset(void)
//----------------------------------------------------------------------------------
// resets the sensor by a softreset 
{ 
  unsigned char error=0;  
  s_connectionreset();              //reset communication
  error+=s_write_byte(RESET);       //send RESET-command to sensor
  return error;                     //error=1 in case of no response form the sensor
}

//----------------------------------------------------------------------------------
char s_read_statusreg(unsigned char *p_value, unsigned char *p_checksum)
//----------------------------------------------------------------------------------
// reads the status register with checksum (8-bit)
{ 
  unsigned char error=0;
  s_transstart();                   //transmission start
  error=s_write_byte(STATUS_REG_R); //send command to sensor
  *p_value=s_read_byte(ACK);        //read status register (8-bit)
  *p_checksum=s_read_byte(noACK);   //read checksum (8-bit)  
  return error;                     //error=1 in case of no response form the sensor
}

//----------------------------------------------------------------------------------
char s_write_statusreg(unsigned char *p_value)
//----------------------------------------------------------------------------------
// writes the status register with checksum (8-bit)
{ 
  unsigned char error=0;
  s_transstart();                   //transmission start
  error+=s_write_byte(STATUS_REG_W);//send command to sensor
  error+=s_write_byte(*p_value);    //send value of status register
  return error;                     //error>=1 in case of no response form the sensor
}
 							   
//----------------------------------------------------------------------------------
char s_measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode)
//----------------------------------------------------------------------------------
// makes a measurement (humidity/temperature) with checksum
{ 
  unsigned error=0;
  unsigned int i;

  s_transstart();                   //transmission start
  switch(mode){                     //send command to sensor
    case TEMP	: error+=s_write_byte(MEASURE_TEMP); break;
    case HUMI	: error+=s_write_byte(MEASURE_HUMI); break;
    default     : break;	 
  }
  for (i=0;i<65535;i++) if(DATA==0) break; //wait until sensor has finished the measurement
  if(DATA) error+=1;                // or timeout (~2 sec.) is reached
  *(p_value)  =s_read_byte(ACK);    //read the first byte (MSB)
  *(p_value+1)=s_read_byte(ACK);    //read the second byte (LSB)
  *p_checksum =s_read_byte(noACK);  //read checksum
  return error;
}

//----------------------------------------------------------------------------------
void init_uart()
//----------------------------------------------------------------------------------
//9600 bps @ 11.059 MHz 
{SCON  = 0x52;    
 TMOD  = 0x20;    
 TCON  = 0x69;	  
 TH1   = 0xfd;    
}

//----------------------------------------------------------------------------------------
void calc_sth11(float *p_humidity ,float *p_temperature)
//----------------------------------------------------------------------------------------
// calculates temperature [癈] and humidity [%RH] 
// input :  humi [Ticks] (12 bit) 
//          temp [Ticks] (14 bit)
// output:  humi [%RH]
//          temp [癈]
{ const float C1=-4.0;              // for 12 Bit
  const float C2=+0.0405;           // for 12 Bit
  const float C3=-0.0000028;        // for 12 Bit
  const float T1=+0.01;             // for 14 Bit @ 5V
  const float T2=+0.00008;           // for 14 Bit @ 5V	

  float rh=*p_humidity;             // rh:      Humidity [Ticks] 12 Bit 
  float t=*p_temperature;           // t:       Temperature [Ticks] 14 Bit
  float rh_lin;                     // rh_lin:  Humidity linear
  float rh_true;                    // rh_true: Temperature compensated humidity
  float t_C;                        // t_C   :  Temperature [癈]

  t_C=t*0.01 - 40;                  //calc. temperature from ticks to [癈]
  rh_lin=C3*rh*rh + C2*rh + C1;     //calc. humidity from ticks to [%RH]
  rh_true=(t_C-25)*(T1+T2*rh)+rh_lin;   //calc. temperature compensated humidity [%RH]
  if(rh_true>100)rh_true=100;       //cut if the value is outside of
  if(rh_true<0.1)rh_true=0.1;       //the physical possible range

  *p_temperature=t_C;               //return temperature [癈]
  *p_humidity=rh_true;              //return humidity[%RH]
}

//--------------------------------------------------------------------
float calc_dewpoint(float h,float t)
//--------------------------------------------------------------------
// calculates dew point
// input:   humidity [%RH], temperature [癈]
// output:  dew point [癈]
{ float logEx,dew_point;
  logEx=0.66077+7.5*t/(237.3+t)+(log10(h)-2);
  dew_point = (logEx - 0.66077)*237.3/(0.66077+7.5-logEx);
  return dew_point;
}

//----------------------------------------------------------------------------------
void main()
//----------------------------------------------------------------------------------
// sample program that shows how to use SHT11 functions
// 1. connection reset 
// 2. measure humidity [ticks](12 bit) and temperature [ticks](14 bit)
// 3. calculate humidity [%RH] and temperature [癈]
// 4. calculate dew point [癈]
// 5. print temperature, humidity, dew point  

{ 
	
	uchar i = 0;
	uchar v = 0;
	uchar keydata = 0;
	uint dat_ad = 0;
	uchar num_ad = 0;
	float dat_ad_xian = 0;
	value humi_val,temp_val;
  float dew_point=0;
  unsigned char error,checksum;
	unsigned int num_i = 0;
//	unsigned int num_i;

	lcd_off();
	lcd_on();
	lcd_ini();
//	lcd_wrc(0x80);
/*
	for(i=0;i<60;i++)
	{
			lcd_wrd(0x00+i);
	}
*/
	delay(100);
	lcd_add(1,1);

	for(i=0;i<4;i++)
	{
		lcd_dis_ch(0xb5,0xa1+i);
	}

//	lcd_dis_ch(0xb5,0xa1);
//	lcd_dis_ch(0xb5,0xa1);
//	lcd_dis_ch(0xb5,0xa1);
	delay(200);
//	i=lcd_read_ac();
//	i=lcd_read_ac();
	i=lcd_read_ac();
//	delay(200);
	lcd_dis_num(i);
	lcd_dis_num(12458);

//	I2C
	WP = 0;

//  write to rom
/*
	lcd_add(3,1);

	i = ISendStr_16(0xa0,0x0000,19);
	lcd_wrd(0x30+i);
*/
/*
	lcd_add(4,1);
	for(v=0x0000;v<8;v++)
	{
		i = 0;
		while(i == 0)
		{
			i = ISendStr_16(0xa0,v,3*v);
		}
		lcd_wrd(0x30+(uchar)i);	
	}
*/

// read rom   set address
/*
	lcd_add(3,1);
	for(v=0x0000;v<8;v++)
	{
		i = IRcvStr_16(0xa0,v);
//		lcd_wrc(0x88+2*v);
		lcd_dis_num(i);
	}
*/

//	set_time(30,13,21,1,12,3,7);		//时钟设置sec, min, hr, dy, dt, mn, yr


//ad中断相关
/*
//	IE = IE&0X81;		//1000 0001
	EA = 0;
	EX0 = 1;
//	TCON
	IT0 = 1;
*/

  	init_uart();
  	s_connectionreset();
	while(1)
	{
	error=0;
	lcd_add(2,1);
	lcd_dis_num(error);
    error+=s_measure((unsigned char*) &humi_val.i,&checksum,HUMI);  //measure humidity
	lcd_add(2,4);
	lcd_dis_num(error);
    error+=s_measure((unsigned char*) &temp_val.i,&checksum,TEMP);  //measure temperature
	lcd_add(2,7);
	lcd_dis_num(error);
   	if(error!=0)
	{
		s_connectionreset();                 //in case of an error: connection reset
		lcd_add(3,1);
		lcd_dis_num(error);
	}
	else
	{
		humi_val.f=(float)humi_val.i;                   //converts integer to float
		temp_val.f=(float)temp_val.i;                   //converts integer to float
		calc_sth11(&humi_val.f,&temp_val.f);            //calculate humidity, temperature
//		dew_point=calc_dewpoint(humi_val.f,temp_val.f); //calculate dew point
//      printf("temp:%5.1fC humi:%5.1f%% dew point:%5.1fC\n",temp_val.f,humi_val.f,dew_point);
	lcd_add(3,1);
	lcd_dis_num((uint)temp_val.f);
	lcd_add(3,4);
	lcd_dis_num((uint)humi_val.f);

	}
    //----------wait approx. 0.8s to avoid heating up SHTxx------------------------------      
//    for (i=0;i<40000;i++);     //(be sure that the compiler doesn't eliminate this line!)
	ldelay(200);
	ldelay(200);

//-----------------------------------------------------------------------------------                       
	

//		lcd_dis_time();		//时钟显示函数
//测试n次
//		i = ad_ce_n();
//		ldelay(80);

/*
//ad测试
		dat_ad = ad_ce();
		lcd_en();
		lcd_add(2,1);
		lcd_dis_num(dat_ad);
		dat_ad_xian = (float)(dat_ad*1.28/2.048);
		lcd_dis_num((uint)dat_ad_xian);
		ldelay(80);


/*
//ad读
		if(sta == 0)
		{
			P0 = 0XFF;
			delay(50);

			if(sta == 0)
			{
//				P0 = 0XFF;
				lben = 0;
				hben = 1;
				ad_en();
				_nop_();
				i = P0;
				ce = 1;
				_nop_();

				hben = 0;
				lben = 1;
				ad_en();
				_nop_();
				v = P0&0x0f;

				lcd_en();
				lcd_add(2,1);
				lcd_dis_num(v);
				lcd_dis_num(i);
				
				
				dat_ad = v*256+i;
				lcd_dis_num(dat_ad);

				dat_ad_xian = (float)(dat_ad*1.28/2.048);
// 				dat_ad_xian = (float)(dat_ad/2.048);

				lcd_dis_num((uint)dat_ad_xian);

//				v = P0&0X30;
//				v = v>>4;
//				lcd_dis_num(v);

				ldelay(80);
			}
		
		}
//ad读结束
*/

/*		keydata = key_data();
		lcd_add(4,7);
		switch(keydata)
		{
			case 0:
			{
				v = 3;
				lcd_dis_num(v);
				break;
			}
			case 1:
			{
				v = 4;
				lcd_dis_num(v);
				break;
			}
			case 2:
			{
				v = 5;
				lcd_dis_num(v);
				break;
			}
			case 3:
			{
				v = 6;
				lcd_dis_num(v);
				break;
			}
			case 4:
			{
				v = 2;
				lcd_dis_num(v);
				break;
			}
			case 5:
			{
				v = 7;
				lcd_dis_num(v);
				break;
			}
			case 6:
			{
				v = 8;
				lcd_dis_num(v);
				break;
			}
			case 7:
			{
				v = 9;
				lcd_dis_num(v);
				break;
			}
			case 8:
			{
				v = 1;
				lcd_dis_num(v);
				break;
			}
			case 9:
			{
				v = 10;
				lcd_dis_num(v);
				break;
			}
			case 10:
			{
				v = 11;
				lcd_dis_num(v);
				break;
			}
			case 11:
			{
				v = 12;
				lcd_dis_num(v);
				break;
			}
			case 12:
			{
				v = 0;
				lcd_dis_num(v);
				break;
			}
			case 13:
			{
				v = 13;
				lcd_dis_num(v);
				break;
			}
			case 14:
			{
				v = 14;
				lcd_dis_num(v);
				break;
			}
			case 15:
			{
				v = 15;
				lcd_dis_num(v);
				break;
			}
			default:
			{
				v = 16;
				lcd_dis_num(v);
				break;
			}
		}
*/
	
   	}
} 

⌨️ 快捷键说明

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