📄 readtemp.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 + -