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

📄 readtemp.c

📁 绝对原创
💻 C
字号:

/*************************************************************************************************************
*	函数名称 :
*	功能描述 :
*	实际参数 :
*	返回值   :
*	说明     :
**************************************************************************************************************/
   
	#include "define.h"    
	
	uchar Road_Dat ;							// 路数
	uchar Read_Number ;							// 读温度次数
	uchar Relay_Number = 0 ;					// 每通一个继电器,读温度次数
	uchar Old_Read_Number = 0 ;					
	
	uint  xdata All_Temp0[5][12] ;				// 5段温度,每段12个数值(求平均,头尾去掉两个)
	uint  xdata All_Temp1[5][12] ;				
	
	uchar xdata Thermocouple_Open[10] ;			// 5路热电偶断开标志

	uint  xdata Fact_Temp[10] ;					// 5路最终平均后的实际温度		
	
	uint  xdata New_Temp[10] ;					// 瞬间值(最新读出的温度值)
	
/*************************************************************************************************************
*	函数名称 :
*	功能描述 :
*	实际参数 :
*	返回值   :	平均后的实际温度值
*	说明     :	排序,从小到大,在求平均值,
**************************************************************************************************************/
	
	uint FactTempDat(uint *addata,uchar a)						
	{				
		uchar i,j ;
		uint t ;												// 排序中的暂存器
		uint average_data = 0 ;							

		for(i = 0;i < a;i++)
		{
			for(j = 0;j < (a -1)-i;j++)
			{			
				if(addata[j] > addata[j + 1])
				{	
					t = addata[j];
					addata[j] = addata[j + 1];
					addata[j + 1] = t;
				}
			}
		} 

		for (i = CLE_TEMPDAT;i < (a - CLE_TEMPDAT);i++)			// 去掉头尾CLE_TEMPDAT个数值求平均值
		{
			average_data += *(addata + i) ;						// 求和
		}		

		j = (a - (CLE_TEMPDAT * 2)) ;
		t = average_data / j ;
		if ((average_data%j) >= (j >> 1))						// 四舍五入
			t++ ;
	
		addata[3] = t ;											// 在下次求平均用
		for(i = 0;i < 6;i++)
		{
			addata[a-1-i] =  addata[a-4-i] ;					// 把排列在中间的数值移到后面,为下次求平均用
		}
		return(t) ;		
	}
/*************************************************************************************************************
*	函数名称 :
*	功能描述 :
*	实际参数 :
*	返回值   :
*	说明     :	读出MAX6675温度数据,低0位是热电藕开路标志,1为开路,低1,2为小数点,其余换算出来的就是十进制数
**************************************************************************************************************/
			 
    uint Read_Max6675(void)
   	{      	
       	uchar c ;
		uint temp_dat = 0 ;				/* 存储读取的温度 */       

       	SCK = 1 ;                     	/* 下降沿输出数据 */
      	_nop_() ;
       
       	SCK = 0 ;
       	_nop_() ;
                           			 	/* 第一位为0,输出数据高位开始 */
       	for(c=0;c<14;c++)              	/* 读出14个数据高位在前 */
       	{
         	temp_dat <<= 1 ;
         	if(SO == 1)
           		temp_dat |= 0x01 ;

         	SCK = 1 ;                    /* 下降沿输出数据 */
         	_nop_() ;       

         	SCK = 0 ;
	        _nop_() ;       
       	}
        SCK = 1 ;
        _nop_() ;         

        if((temp_dat & 0x01) == 1)  	/* 断线检测 */
           temp_dat = 0x01 ;    		// 断线,温度为0度
   
		return(temp_dat) ;
     }

/*************************************************************************************************************
*	函数名称 : void NewTemp(uint temp0_dat,uint temp1_dat)
*	功能描述 :
*	实际参数 :
*	返回值   :
*	说明     : 求瞬间温度,每次继电器打通的平均值(每打通一次,读两次温度,才换下个继电器)
**************************************************************************************************************/
	
	void NewTemp(uint temp0_dat,uint temp1_dat)
	{
		uint temp_dat ;	
		uchar d ;

		// 第一个MAX6675
		if (!(temp0_dat & 0x0001))
		{		
			temp_dat = (All_Temp0[Road_Dat][Read_Number] + All_Temp0[Road_Dat][Read_Number - 1]) ;					// 放大十倍,0.25度
			temp_dat >>= 1 ;					   			// 去掉断线标志(保留了小数点位,所以实际的温度为增大了4倍)
			New_Temp[Road_Dat] =  temp_dat / 2 ; 			// 此温度值是大了4倍
			if (Thermocouple_Open[Road_Dat] == 0x22)
	    		Thermocouple_Open[Road_Dat] = 0x00  ;		// 没断线标志,0x00为不加热,0x11为加热
		}
		else
		{
			New_Temp[Road_Dat] = 0 ;						// 有断线,温度为0 	
	
			Thermocouple_Open[Road_Dat] = 0x22 ;			// 断线标志,为0x22

			for (d = 0;d < 12;d++)
				All_Temp0[Road_Dat][d] = 0 ;				// 全清零
		}

		// 第二个MAX6675
		if (!(temp1_dat & 0x0001))
		{			
			temp_dat = (All_Temp1[Road_Dat][Read_Number] + All_Temp1[Road_Dat][Read_Number - 1]) ;					// 放大十倍,0.25度
			temp_dat >>= 1 ;		 
 		    New_Temp[Road_Dat + 5] = temp_dat / 2 ;
			if (Thermocouple_Open[Road_Dat + 5] == 0x22)  ;	// 没断线标志,为0
				Thermocouple_Open[Road_Dat + 5] = 0x00 ;
		}
		else
		{
			New_Temp[Road_Dat + 5] = 0 ;	
		
			Thermocouple_Open[Road_Dat + 5] = 0x22  ;			// 断线标志,为0x22

			for (d = 0;d < 12;d++)
				All_Temp1[Road_Dat][d] = 0 ;				    // 全清零
		}		 
	}

/*************************************************************************************************************
*	函数名称 :
*	功能描述 :
*	实际参数 :
*	返回值   :
*	说明     :	读出MAX6675温度数据
**************************************************************************************************************/
				 
    void ReadTempDat(void)
   	{  
    	uchar p2_dat ;
		uint temp_dat0,temp_dat1 ;
	
		CS0 = 0 ;                     					// 停止第一个MAX6675转换 
		temp_dat0 = Read_Max6675() ;
		CS0 = 1 ;
		_nop_() ;

		CS1 = 0 ;										// 停止第二组MAX6675转换 
		temp_dat1 = Read_Max6675() ;

	    CS0 = 0 ; 	   	  								// 两路终止转换	

		All_Temp0[Road_Dat][Read_Number] = temp_dat0 >> 1 ;	// 第一个MAX6675温度值(从MAX6675读出来的温度是带小数点2位和1位断线标志的)
		All_Temp1[Road_Dat][Read_Number] = temp_dat1 >> 1 ;	// 第二个MAX6675温度值	

		Relay_Number++ ;								// 每通一次继电器读温度次数(现在规定位2次)	
		if (Relay_Number > 1)
		{
			Relay_Number = CLEAR ;						// 清读温度次数

			p2_dat = P2 & 0x7c ;						// 判断现在接通的是哪个继电器(用第二组温度判断)

			P2 &= 0x03 ;								// 释放所有继电器
			P1 &= 0xf0 ;

			if (Read_Number >= 5)						// 读完6次温度新值(平均值)
			{
				Fact_Temp[Road_Dat] = FactTempDat(&All_Temp0[Road_Dat][0],12) ;	
				if (Road_AdhystSign[Road_Dat])
				{
					if (Fact_Temp[Road_Dat] > Road_AdjustDat[Road_Dat])					// 当前值大于修正值
						Fact_Temp[Road_Dat] -= Road_AdjustDat[Road_Dat] ;
					else
						Fact_Temp[Road_Dat] = 0 ;
				}
				else
					Fact_Temp[Road_Dat] += Road_AdjustDat[Road_Dat] ;
								
				Fact_Temp[Road_Dat + 5] = FactTempDat(&All_Temp1[Road_Dat][0],12) ;
				if (Road_AdhystSign[Road_Dat + 5])
				{
					if (Fact_Temp[Road_Dat + 5] > Road_AdjustDat[Road_Dat + 5])			// 当前值大于修正值
						Fact_Temp[Road_Dat + 5] -= Road_AdjustDat[Road_Dat + 5] ;
					else
						Fact_Temp[Road_Dat + 5] = 0 ;
				}
				else
					Fact_Temp[Road_Dat + 5] += Road_AdjustDat[Road_Dat + 5] ;
				
				if (Road_Dat == 4)
				{
					Send_DatBag[5] = 0xd0 ;								// 数据代码
					Send_DatBag[4] = 0x00 ;
					Send_DatBag[3] = BCD((SiteFack_Temp >> 2)) ;	// 有两位是小数点				
					Send_DatBag[2] = Send_DatBag[4] ;					// 重发数据包
					Send_DatBag[1] = Send_DatBag[3] ;				
					Send_DatBag[0] = 0xff ;								// 结束标志

					Breed_Dat = 1 ;										// 发送下一组数据
					Send_Counter = 6 ;									// 一帧6个数据					
					SBUF = Send_DatBag[Send_Counter - 1] ;		
					Send_Counter-- ;
				}
			}
	
			NewTemp(temp_dat0,temp_dat1) ;					// 读完两次后求瞬间值,在控温里要用来比较
															// 延时,为隔离相邻两段温度干扰	
			switch(p2_dat)
			{
				case 0x40:							
							Road_Dat = 1 ;					// 路数值,(在储存温度值用)	
							Temp_Relay1	= ON ;				// 接通第下一个继电器	
							Temp_Relay6 = ON ;
							break ;
		
				case 0x20:						
							Road_Dat = 2 ;					// 路数值,(在储存温度值用)	
							Temp_Relay2	= ON ;				// 接通第下一个继电器	
							Temp_Relay7 = ON ;
							break ;
				
				case 0x10:
						
							Road_Dat = 3 ;					// 路数值,(在储存温度值用)	
							Temp_Relay3	= ON ;				// 接通第下一个继电器	
							Temp_Relay8 = ON ;
							break ;
		
				case 0x08:						
							Road_Dat = 4 ;					// 路数值,(在储存温度值用)
							Temp_Relay4	= ON ;				// 接通第下一个继电器	
							Temp_Relay9 = ON ;
							break ;
		
				case 0x04:  						
							Road_Dat = 0 ;					// 路数值,(在储存温度值用)
							Temp_Relay0	= ON ;				// 接通第下一个继电器	
							Temp_Relay5 = ON ;	

							Old_Read_Number += 2 ;	
							
							if (Old_Read_Number >= 6)
								Old_Read_Number = 0 ;
						
							break ;
				default:
							break ;
			}
			Read_Number = Old_Read_Number ; 			// 为本下一次
		}
		else 
		{
			Read_Number++ ;
		}	
	}

/*************************************************************************************************************
*	函数名称 :
*	功能描述 :
*	实际参数 :
*	返回值   :
*	说明     :	处理温度数据
**************************************************************************************************************/

	void NeatenTemp(void)
	{
		if (Int0_Time >= READ_TIME)						// 4 X 0.055 = 0.22s
		{
			Int0_Time = CLEAR ;							// 清读MAX6675定时时间中断标志
			ReadTempDat() ;								// 读温度数据

			CS0 = ON ;                          		/* 进行温度转换 */
			CS1 = ON ;
			TR0 = ON ;									// 开读MAX6675定时器
		}
	}  

/*************************************************************************************************************
*	函数名称 :
*	功能描述 :
*	实际参数 :
*	返回值   :
*	说明     :
**************************************************************************************************************/
		
   

⌨️ 快捷键说明

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