📄 dataproces.c
字号:
/*========================================================/
/ /
/ Copyright (C), 2001-2005, Pangu Automation. Co., Ltd. /
/ FileName: DataProces.c /
/ Author: Zheng M.D. /
/ Version: 1.0 /
/ Date: 2005.11.12 /
/ Description: pH计数据处理 /
/ Modify: /
/ /
/========================================================*/
#include <reg52.h>
#include "include\time.h"
#include "include\DataProces.h"
#include "include\CS5529.h"
CALIPARAM idata pHCaliParam;
TRANSMISSION idata TransData;
extern bit bCaling;
extern bit __CS5529_DATA_OF;
extern unsigned char CS5529_DataReg[3];
short idata ChannelADCode[5][4] = {0}; //AD采样滤波缓冲通道一
static unsigned char idata MistakeCount[5] = {0}; //AD采样无效记次
unsigned char code ChannelCode[6]={0x03,0xC0,0xC1,0xC4,0x03,0x43}; //通道选择号
float code pt1000Table[11]={1000.000,//0度对应的电阻值
1039.022,//10度对应的电阻值
1077.928,//20
1116.718,//30
1155.392,//40
1193.951,//50
1232.392,//60
1270.718,//70
1308.928,//80
1347.022,//90
1385.000};//100
/*************************************************
//函 数 名:SelectSignalAndGain
//功 能:选择输入通道和对应的放大倍数
//输入参数:channel(unsigned cha);
//返 回 值:无
//备 注:
*************************************************/
void SelectSignalAndGain(unsigned char channel)
{
unsigned char SelCode=ChannelCode[channel];
unsigned char i;
if((pHCaliParam.Mode==0x03)||(pHCaliParam.Mode==0x01))
{
//if(channel==ChannelCode[0]||channel==ChannelCode[4])
//{
SelCode=ChannelCode[5];
//}
}
for(i = 0; i < 8; i++)
{
if(SelCode & 0x80)
__SELSDA = 1;
else
__SELSDA = 0;
//加入延时(注:光耦521传输速度10K)
delay_us(30);
__SELCLK = 0;
delay_us(30);
__SELCLK = 1;
SelCode <<= 1;
}
}
/*************************************************
//函 数 名: DoADFilterMain()
//功 能: 滤波,获得AD原码
//输入参数: 无
//返 回 值: 无
*************************************************/
void DoADFilterMain(unsigned char channel )
{
short uData=0;
long average;
unsigned char i;
uData=(short)CS5529_DataReg[0]*256+CS5529_DataReg[1];
if(_CS5529_DATA_OF==0)
{ //如果本次数据与上回数据相差50以上,则为无效,
if(((uData - ChannelADCode[channel][0] )> 50) || ((ChannelADCode[channel][0] - uData) > 50))
{
MistakeCount[channel]++; //错误累加
if(MistakeCount[channel] >= 2) //如果错误次数>=2则,认为这个数据是有效的,
{
MistakeCount[channel] = 0; //清除错误次数累加
for(i=0; i < 4; i++ )
{
ChannelADCode[channel][i] = uData;
}
}
}
else
{
ChannelADCode[channel][3] = ChannelADCode[channel][2]; //数据向后移
ChannelADCode[channel][2] = ChannelADCode[channel][1];
ChannelADCode[channel][1] = uData;
average = (long)ChannelADCode[channel][3] + (long)ChannelADCode[channel][2] +
(long)ChannelADCode[channel][1];
average /= 3;//取平均值
ChannelADCode[channel][0] = (short) average;
pHCaliParam.ADValue=ChannelADCode[channel][0];
}
}
}
/*************************************************
//函 数 名:LimitrCod
//功 能:限制编码(0~30000)
//输入参数:yard(long*)
//返 回 值:无
//备 注:
************************************************
void LimitrCode(long* yard)
{
if(*yard > 30000)
*yard = 30000;
if(*yard < 0)
*yard = 0;
}
*/
void LimitrCodeF(float* yard)
{
if(*yard > 30000)
*yard = 30000;
if(*yard < 0)
*yard = 0;
}
/*************************************************
//函 数 名: GetStdValue()
//功 能: 得到0~30000标量化的实时值
//输入参数: channel(通道)
//返 回 值: 无
*************************************************/
/***********************************************************************
;------------------------------------------------
/***********************************************************************
;------------------------------------------------
;DO_TYPER 处理电阻信号
pt100
350为标定电阻值
;VALUE = ((NOW_M - NOW_Z) - 2 * (NOW_S - NOW_Z))*10000/(K - NOW_M) * 30000 / 350
;************************************************************************
;* K 系数计算
;*
;* ((NOW_M - NOW_Z) - 2 * (NOW_S - NOW_Z))*10000 //10000的意思是10K电阻
;* K = ------------------------------------------------- + NOW_M //
;* 350
;*
;************************************************************************
pt1000
1400为标定电阻值
;VALUE = ((NOW_M - NOW_Z) - 2 * (NOW_S - NOW_Z))*10000/(K - NOW_M) * 30000 / 1400
;************************************************************************
;* K 系数计算
;*
;* ((NOW_M - NOW_Z) - 2 * (NOW_S - NOW_Z))*10000 //10000的意思是10K电阻
;* K = ------------------------------------------------- + NOW_M //
;* 1400
;
;实际的电阻值(不转换成0~30000码值)
VALUE = ((NOW_M - NOW_Z) - 2 * (NOW_S - NOW_Z))*10000/(K - NOW_M)
;************************************************************************
*/
void GetStdValue(unsigned char channel)
{
float ftemp;
//long Percent;
switch(channel)
{
case 0x00: //pH
if(pHCaliParam.Mode==0x00)
{
ftemp =((float)ChannelADCode[0][0] - (float)pHCaliParam.pHOnlineLower) * 30000.0 /
((float)pHCaliParam.pHOnlineUpper - (float)pHCaliParam.pHOnlineLower);
//if(bCaling==0)//如果处理标定状态就不将电压信号换算成pH信号
//{
ftemp=(ftemp-15000.0)/30000.0;
ftemp=7.0 - ftemp*5039.4/(273.0+(float)TransData.Pt1000Percent/300.0); //自动温度补偿
ftemp=ftemp/14.0*30000.0;
//}
}
else if(pHCaliParam.Mode==0x02)
{
ftemp =((float)ChannelADCode[0][0] - (float)pHCaliParam.pHOnlineLower) * 30000.0 /
((float)pHCaliParam.pHOnlineUpper - (float)pHCaliParam.pHOnlineLower);
//if(bCaling==0)//如果处理标定状态就不将电压信号换算成pH信号
//{
ftemp=(ftemp-15000.0)/30000.0;
ftemp=7.0 - ftemp*5039.4/(273.0+(float)TransData.Pt1000Percent/300.0); //手动温度补偿
ftemp=ftemp/14.0*30000.0;
//}
}
else if((pHCaliParam.Mode==0x03)||(pHCaliParam.Mode==0x01))
{
ftemp =((float)ChannelADCode[0][0] - (float)pHCaliParam.OrpOnlineLower) * 30000.0 /
((float)pHCaliParam.OrpOnlineUpper - (float)pHCaliParam.OrpOnlineLower);
}
LimitrCodeF(&ftemp);
TransData.pHPercent=(short)ftemp;
break;
case 0x03: //pt1000
if(pHCaliParam.Mode == 0x00) //如果为自动补偿计算pt1000所指示的温度值
{
//计算实际电阻值
ftemp =(float)((float)(ChannelADCode[1][0] - ChannelADCode[3][0]) - 2 *
(float)(ChannelADCode[2][0] - ChannelADCode[3][0]))
* 10000.0/(float)(pHCaliParam.Pt1000 - ChannelADCode[1][0]);
//根据电阻值进行线性插值求得温度
if(ftemp<=pt1000Table[0]) //t<0
{
ftemp=0.0;
}
else if(ftemp<=pt1000Table[1]) //0<t<=10
{
ftemp=(ftemp-pt1000Table[0])/(pt1000Table[1]-pt1000Table[0])*10.0;
}
else if(ftemp<=pt1000Table[2]) //10<t<=20
{
ftemp=(ftemp-pt1000Table[1])/(pt1000Table[2]-pt1000Table[1])*10.0+10.0;
}
else if(ftemp<=pt1000Table[3]) //20<t<=30
{
ftemp=(ftemp-pt1000Table[2])/(pt1000Table[3]-pt1000Table[2])*10.0+20.0;
}
else if(ftemp<=pt1000Table[4]) //30<t<=40
{
ftemp=(ftemp-pt1000Table[3])/(pt1000Table[4]-pt1000Table[3])*10.0+30.0;
}
else if(ftemp<=pt1000Table[5]) //40<t<=50
{
ftemp=(ftemp-pt1000Table[4])/(pt1000Table[5]-pt1000Table[4])*10.0+40.0;
}
else if(ftemp<=pt1000Table[6]) //50<t<=60
{
ftemp=(ftemp-pt1000Table[5])/(pt1000Table[6]-pt1000Table[5])*10.0+50.0;
}
else if(ftemp<=pt1000Table[7]) //60<t<=70
{
ftemp=(ftemp-pt1000Table[6])/(pt1000Table[7]-pt1000Table[6])*10.0+60.0;
}
else if(ftemp<=pt1000Table[8]) //70<t<=80
{
ftemp=(ftemp-pt1000Table[7])/(pt1000Table[8]-pt1000Table[7])*10.0+70.0;
}
else if(ftemp<=pt1000Table[9]) //80<t<=90
{
ftemp=(ftemp-pt1000Table[8])/(pt1000Table[9]-pt1000Table[8])*10.0+80.0;
}
else if(ftemp<=pt1000Table[10]) //90<t<=100
{
ftemp=(ftemp-pt1000Table[9])/(pt1000Table[10]-pt1000Table[9])*10.0+90.0;
}
else //t>100
{
ftemp=100.0;
}
ftemp=ftemp*300.0;
LimitrCodeF(&ftemp);
TransData.Pt1000Percent = (short) ftemp;
}
else //其它则使用手动设定值
{
TransData.Pt1000Percent = pHCaliParam.ManualTemp*30;
}
break;
}
}
/*************************************************
//函 数 名:ProcessADInput()
//功 能:选择通道,采样,滤波,获取0~30000标称值
//输入参数:无
//返 回 值:无
//备 注:
*************************************************/
void ProcessADInput(unsigned char ch)
{
unsigned char temp;
CS5529_SingleConversion(); //采样
temp=ch+1;
if(temp>4)
{
temp=0;
}
SelectSignalAndGain(temp); //选择下一通道
DoADFilterMain(ch);//虑波
GetStdValue(ch); //获得标准化的AD码值
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -