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

📄 arm_sht.c

📁 我写的基于NXP ARM7的SHTx.x 温湿度传感器程序
💻 C
字号:
/***************************************************	
	2007/2/10
	Liu Guobing
****************************************************/
// 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  

#include "ARM_SHT.h"


fp32 Temp_Value,Humi_Value;			//温湿度值,可与外围接口
uint32 SHT_Step=0;					//温湿度测量步骤控制

//-----------------------------------------------------------------------------------------
//温度,湿度测量部分
//-----------------------------------------------------------------------------------
uint8 s_write_byte(uint8 value)
//----------------------------------------------------------------------------------
// writes a byte on the Sensibus and checks the acknowledge 
{ 
	uint8 i,error=0;  
	for (i=0x80;i>0;i/=2) {			//shift bit for masking
		if (i & value) {			//masking value with i , write to SENSI-BUS
			SHT_DATA_SET();
		}         
		else {
			SHT_DATA_CLR();
		}                        
		SHT_SCK_SET();					//clk for SENSI-BUS
		Delay_us(_SHT_Shout_Time_);		//pulswith approx. 5 us  	
		SHT_SCK_CLR();
		Delay_us(_SHT_Shout_Time_);
	}
	SHT_DATA_SET();						//release SHT_DATA-line
	Delay_us(_SHT_Shout_Time_);
	SHT_SCK_SET();						//clk #9 for ack 
	Delay_us(_SHT_Shout_Time_);
	//error=SHT_DATA;					//check ack (SHT_DATA will be pulled down by SHT11)
	SHT_DATA_In();
	if(Read_SHT_DATA()) {
		error=true;
	}
	else {
		error=false;
	}
	SHT_DATA_Out();
	Delay_us(_SHT_Shout_Time_);
	SHT_SCK_CLR();
	return error;					//error=1 in case of no acknowledge
	Delay_us(_SHT_Shout_Time_);
}


//----------------------------------------------------------------------------------
uint8 s_read_byte(uint8 ack)
//----------------------------------------------------------------------------------
// reads a byte form the Sensibus and gives an acknowledge in case of "ack=1" 
{ 
	uint8 i,val=0;
	SHT_DATA_SET();						//release SHT_DATA-line
	SHT_DATA_In();						//SHT_DATA input
	Delay_us(_SHT_Shout_Time_);
	for (i=0x80;i>0;i/=2) {			//shift bit for masking
		SHT_SCK_SET();					//clk for SENSI-BUS
		Delay_us(_SHT_Shout_Time_);
		if (Read_SHT_DATA()) {
			val=(val | i);			//read bit
		}  
		SHT_SCK_CLR();  		
		Delay_us(_SHT_Shout_Time_);			 
	}
	//SHT_DATA=!ack;					//in case of "ack==1" pull down SHT_DATA-Line
	if(ack) {
		SHT_DATA_CLR();
	}
	else {
		SHT_DATA_SET();
	}
	SHT_DATA_Out();
	Delay_us(_SHT_Shout_Time_);
	SHT_SCK_SET();						//clk #9 for ack
	Delay_us(_SHT_Shout_Time_);			//pulswith approx. 5 us 
	SHT_SCK_CLR();						    
	Delay_us(_SHT_Shout_Time_);
	SHT_DATA_SET();						//release SHT_DATA-line
	return val;
}


//----------------------------------------------------------------------------------
void s_transstart(void)
//----------------------------------------------------------------------------------
// generates a transmission start 
//       	 _____         ________
// SHT_DATA:      |_______|
//          	 ___     ___
// SHT_SCK : ___|   |___|   |______
{  
	SHT_DATA_SET(); 				//Initial state
	Delay_us(_SHT_Shout_Time_);
	SHT_SCK_CLR();			
	Delay_us(_SHT_Shout_Time_);
	SHT_SCK_SET();
	Delay_us(_SHT_Shout_Time_);
	SHT_DATA_CLR();
	Delay_us(_SHT_Shout_Time_);
	SHT_SCK_CLR();  
	Delay_us(_SHT_Shout_Time_);
	SHT_SCK_SET();
	Delay_us(_SHT_Shout_Time_);
	SHT_DATA_SET();		  
	Delay_us(_SHT_Shout_Time_);
	SHT_SCK_CLR();		   
}

//----------------------------------------------------------------------------------
void s_connectionreset(void)
//----------------------------------------------------------------------------------
// communication reset: SHT_DATA-line=1 and at least 9 SHT_SCK cycles followed by transstart
//       _____________________________________________________         ________
// SHT_DATA:                                                  |_______|
//              _    _    _    _    _    _    _    _    _        ___     ___
// SHT_SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______|   |___|   |______
{  
	uint8 i; 
	SHT_DATA_SET();
	Delay_us(_SHT_Shout_Time_);
	SHT_SCK_CLR();					//Initial state
	Delay_us(_SHT_Shout_Time_);
	for(i=0;i<9;i++) {				//9 SHT_SCK cycles
		SHT_SCK_SET();
		Delay_us(_SHT_Shout_Time_);
		SHT_SCK_CLR();
		Delay_us(_SHT_Shout_Time_);
	}
	s_transstart();					//transmission start
}

//----------------------------------------------------------------------------------
uint8 s_softreset(void)
//----------------------------------------------------------------------------------
// resets the sensor by a softreset 
{ 
	uint8 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
}

//----------------------------------------------------------------------------------
uint8 s_read_statusreg(uint8 *p_value, uint8 *p_checksum)
//----------------------------------------------------------------------------------
// reads the status register with checksum (8-bit)
{ 
	uint8 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
}

//----------------------------------------------------------------------------------
uint8 s_write_statusreg(uint8 *p_value)
//----------------------------------------------------------------------------------
// writes the status register with checksum (8-bit)
{ 
	uint8 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
}



//----------------------------------------------------------------------------------------
void calc_sth11(fp32 *p_humidity ,fp32 *p_temperature) {
//----------------------------------------------------------------------------------------
// calculates temperature [癈] and humidity [%RH] 
// input :  humi [Ticks] (12 bit) 
//          temp [Ticks] (14 bit)
// output:  humi [%RH]
//          temp [癈]

// 温湿度转换公式
//Temperature = d1+d2 * temp[Ticks]
//RH_lin = c1 + c2*SO + c3 * humi[Ticks]
//RH_true = (T - 25)*(t + t * humi[Ticks] ) + RH_lin

	const fp32 C1=-4.0;				// for 12 Bit
	const fp32 C2=+0.0405;			// for 12 Bit
	const fp32 C3=-0.0000028;		// for 12 Bit
	const fp32 T1=+0.01;			// for 14 Bit @ 5V
	const fp32 T2=+0.00008;			// for 14 Bit @ 5V	
	
	fp32 rh=*p_humidity;			// rh:      Humidity [Ticks] 12 Bit 
	fp32 t=*p_temperature;			// t:       Temperature [Ticks] 14 Bit
	fp32 rh_lin;					// rh_lin:  Humidity linear
	fp32 rh_true;					// rh_true: Temperature compensated humidity
	fp32 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]
}


//清除与温湿度有关的所有显示
void SHT_Display_Disable(void)			//关闭温湿度显示
{				
	LCD_Show_Logo(L_RH, false);			//关闭与体温显示相关的Logo
	LCD_Show_Logo(L_P4, false);			//温度显示小数点
	LCD_Show_Logo(L_P5, false);			//温度符号显示
	LCD_Show_Logo(L_P6, false);
	LCD_Show_Logo(L_P7, false);
	LCD_Show_Logo(L_29A, false);

	LCD_Show_Number(N_C1, 10);			//关闭与体温显示相关的数字位
	LCD_Show_Number(N_C2, 10);
	LCD_Show_Number(N_C3, 10);
	LCD_Show_Number(N_R1, 10);
	LCD_Show_Number(N_R2, 10);
	 
	return;
}
	
//显示温湿度函数
//--------------------------------------------------------------------
void SHT_Display(fp32 * SHT_RH, fp32 * SHT_TC)
{
	if((*SHT_TC >= 100)||(*SHT_TC <= -10)) return;	//数据过滤,不可大于100或小于-10

	if(*SHT_TC >= 0.1) {
		LCD_Show_Number(N_C1, (uint8)(*SHT_TC/10));
		LCD_Show_Number(N_C2, ((uint8)(*SHT_TC))%10);
		LCD_Show_Number(N_C3, ((uint8)((*SHT_TC)*10))%10);
	}
	else if(*SHT_TC <= -0.1) {			//当前温度小于0度时
		LCD_Show_Number(N_C1, LCD_N_Bar);//显示 "-"
		LCD_Show_Number(N_C2, (uint8)(*SHT_TC));
		LCD_Show_Number(N_C3, ((uint8)((*SHT_TC)*10)));
	}
	else {								//当前温度为0度时
		LCD_Show_Number(N_C1, 10);		//第一位不显示,即最终显示 0.0 C
		LCD_Show_Number(N_C2, 0);
		LCD_Show_Number(N_C3, 0);
	}
	
	LCD_Show_Logo(L_P4, true);			//温度显示小数点
	LCD_Show_Logo(L_P5, true);			//温度符号显示

	if((*SHT_RH>=100)||(*SHT_RH<0)) return;	//湿度数据过滤,应该可以不用

	LCD_Show_Number(N_R1, (uint8)(*SHT_RH/10));
	LCD_Show_Number(N_R2, ((uint8)(*SHT_RH))%10);
	
	if(*SHT_RH>0.5) {					//判断是否显示小数位 ".5"
		LCD_Show_Logo(L_29A, true);
	}
	else {
		LCD_Show_Logo(L_29A, false);
	}
	
	LCD_Show_Logo(L_RH, true);			//湿度 “RH ” Logo
	LCD_Show_Logo(L_P6, true);			//湿度显示小数点
	LCD_Show_Logo(L_P7, true);			//湿度 "%" Logo

	return;
}


//温湿度测量主函数
void SHT_Measure(void)
{
	uint32 error=0;
	uint32 Temp_CheckSum,Humi_CheckSum;

	switch(SHT_Step)					//温湿度测量步聚控制
	{
		case 0: {						//发送测量温度命令
			SHT_SCK_Out();
			SHT_DATA_Out();
			Delay_us(_SHT_Shout_Time_);
			s_transstart();							//transmission start
			error+=s_write_byte(MEASURE_TEMP);		//send command to sensor
			SHT_Overtime_Time=_SHT_Overtime_Time_;
			SHT_DATA_In();
			SHT_Step+=10;
			break;
		}
		
		case 10: {						//等待温度测量结束发送湿度测量命令
			if(!Read_SHT_DATA()) {
				Temp_Value = s_read_byte(ACK)<<8;	//读取温度数字值
				Temp_Value += s_read_byte(ACK);
				Temp_CheckSum = s_read_byte(noACK);
				SHT_DATA_Out();
				s_transstart();						//transmission start
				error+=s_write_byte(MEASURE_HUMI);	//send command to sensor
				SHT_Overtime_Time=_SHT_Overtime_Time_;
				SHT_DATA_In();
				SHT_Step+=10;
			}
			else {						//判断接收温度是否超时
				if(!SHT_Overtime_Time) {
					COM_PutCR();					//串口输出超时字符,调试用
					UART0_SendByte('S');
					UART0_SendByte('H');
					UART0_SendByte('T');
					UART0_SendByte(' ');
					UART0_SendByte('O');
					UART0_SendByte('T');

					SHT_Step=0;
					SHT_Measure_Time=_SHT_Measure_Time_;
					//...
				}
			}
			break;
		}

		case 20: {						//等待湿度测量结束,并计算显示温湿度值
			if(!Read_SHT_DATA()) {
				Humi_Value = s_read_byte(ACK)<<8;	//读取温度数字值
				Humi_Value += s_read_byte(ACK);
				Humi_CheckSum = s_read_byte(noACK);

				SHT_SCK_In();						//数字端口恢复初始状态
				SHT_DATA_In();

				calc_sth11(&Humi_Value,&Temp_Value);//calculate humidity, temperature
				SHT_Display(&Humi_Value,&Temp_Value);

				SHT_Step=0;
				SHT_Measure_Time=_SHT_Measure_Time_;
			}
			else {						//超时判断
				if(!SHT_Overtime_Time) {
					COM_PutCR();					//串口输出超时字符,调试用
					UART0_SendByte('S');
					UART0_SendByte('H');
					UART0_SendByte('T');
					UART0_SendByte(' ');
					UART0_SendByte('O');
					UART0_SendByte('T');

					SHT_Step=0;
					SHT_Measure_Time=_SHT_Measure_Time_;
					//...
				}
			}
			break;
		}
	}

	if(error!=0) {						//如前面出现通信错误则发关软复位指令
		SHT_SCK_Out();
		SHT_DATA_Out();
		s_connectionreset();
		SHT_SCK_In();
		SHT_DATA_In();
		SHT_Step=0;
		SHT_Measure_Time=_SHT_Measure_Time_;
		error=0;
	}
	return;
}


#if 0
	const fp32 C1=-4.0;				// for 12 Bit
	const fp32 C2=+0.0405;			// for 12 Bit
	const fp32 C3=-0.0000028;		// for 12 Bit
	const fp32 T1=+0.01;			// for 14 Bit @ 5V
	const fp32 T2=+0.00008;			// for 14 Bit @ 5V	
	
	fp32 rh=*p_humidity;			// rh:      Humidity [Ticks] 12 Bit 
	fp32 t=*p_temperature;			// t:       Temperature [Ticks] 14 Bit
	fp32 rh_lin;					// rh_lin:  Humidity linear
	fp32 rh_true;					// rh_true: Temperature compensated humidity
	fp32 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]
#endif

	

#if 0
	const uint32 C1=40000000;		//-4.0 * 10000000
	const uint32 C2=405000;
	const uint32 C3=28;
	const uint32 T1=0.01;
	const uint32 T2=0.00008;
	//const uint32 T1=100000;
	//const uint32 T2=800;

	uint32 t,t_C;
	uint32 rh,rh_lin_high,rh_lin_low,rh_true;

	t=Temp_Value*10000-40*100;
	Temp_Value = t/100;
	Temp_Value_Decimal = t%100;

	rh=Humi_Value*C2-Humi_Value*Humi_Value*C3-C1;
	rh_true=(Temp_Value-25)*()
	
	rh_lin_high = rh/10000000;
	rh_lin_low = rh%10000000;

#endif


#if 0
//--------------------------------------------------------------------
fp32 calc_dewpoint(fp32 h,fp32 t) {
//--------------------------------------------------------------------
// calculates dew point
// input:   humidity [%RH], temperature [癈]
// output:  dew point [癈]
	fp32 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;
}
#endif

/*********************************************************************************************************
**                            End Of File
********************************************************************************************************/

⌨️ 快捷键说明

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