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

📄 dataproces.c

📁 AD芯片CS5529的驱动程序,包括SPI读写函数,初始化函数,校准函数,转换函数,复位函数等等.
💻 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 + -