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

📄 serialcom.c

📁 AD芯片CS5529的驱动程序,包括SPI读写函数,初始化函数,校准函数,转换函数,复位函数等等.
💻 C
字号:
/*========================================================/
/														  /
/ Copyright (C), 2001-2005, Pangu Automation. Co., Ltd.	  /	
/ FileName:		SerialComm								  /
/ Author:		Zheng M.D.							  	  /
/ Version:		1.0										  /
/ Date:			2005.11.25								  /
/ Description:	pH计通信程序							  /
/ Modify:												  /
/														  /
/========================================================*/
#include <reg52.h>
#include "include\DataProces.h"
#include "include\serialcom.h"
#include "include\X5045.h"
#include "include\CS5529.h"
#include "include\time.h"

//extern uchar	ChannelSType[3];

extern CALIPARAM 	idata 	pHCaliParam;						
extern TRANSMISSION idata 	TransData;
extern short		idata 	ChannelADCode[5][4];

//------------内部变量-----------------
unsigned char	idata cCommBuffer[COMM_MAX];
unsigned char	idata cUartLen;
bit		bFlagWriteConfig;
bit		bFlagDataConfig;
bit		bCaling;
bit		bDoubleCali;
bit		bCalied;
short	spH7AD;
short	spH4AD;
/*************************************************
//函 数 名:	cal_crc()
//功    能:	CRC-16校验
//输入参数:	*ptr(数据头指针),len(校验数据长度)
//返 回 值:	crc(校验结果)
*************************************************/
static	unsigned short cal_crc(unsigned char *ptr, unsigned char len) 
{
	unsigned char	i, j, sdata, tmp;
	unsigned short	crc;
	crc = 0xFFFF;
	if(len == 0)
		return crc;
	for(i = 0; i < len; i++)
	{
		sdata =  *(ptr + i);
		for(j = 0; j < 8; j++)
		{
			tmp = crc % 2 + sdata % 2;
			crc = crc / 2;
			sdata = sdata / 2;
			if(tmp == 1)
			    crc = crc^0xA001;
		}
	}
	return	crc;
}

/*************************************************
//函 数 名:	UartReceive()
//功    能:	通讯接收
//输入参数:	无
//返 回 值:	0(接收失败),1(接收成功)
*************************************************/
static bit	UartReceive(void)
{
	unsigned char	i;	
	RI = 0;
	cCommBuffer[0] = SBUF;	
	//地址错误
	if(cCommBuffer[0] != ADDRESS)
	{
		cUartLen = 0;
		return	0;
	}
	//初始长度
	cUartLen = 1;
	//接收数据,
	for(i = 0; i <= 100; i++)
	{
		//接收到的数据长度必须小于缓冲区长度
		if(RI & cUartLen < COMM_MAX)
		{
			RI = 0;
			i = 0;
			cCommBuffer[cUartLen] = SBUF;
			cUartLen ++;
		}		
		//通讯等待延时
		delay_us(2);
	}	
	//判断接收数据长度
	if(cUartLen > 5)
		return	1;
	else
		return	0;
}

/*************************************************
//函 数 名:	UartTransmit()
//功    能:	通讯发送
//输入参数:	无
//返 回 值:	0(发送失败),1(发送成功)
*************************************************/
static bit	UartTransmit(void)
{
	char i = 0;
	TI = 0;
	//停止接收数据
	REN = 0;
	
	//发送长度不对
	if(cUartLen < 5)
		return 0;	
	//发送首字节
	SBUF = cCommBuffer[0];
	i ++;
	cUartLen --;
	//发送到字节完成
	while(cUartLen != 0)
	{
		//等待一个字节发送完成
		while(TI)
		{
			TI = 0;
			SBUF = cCommBuffer[i];
			i++;	
			cUartLen --;
		}		
		//通讯等待延时
		delay_us(3);
	}
	return	1;
}

/*************************************************
//函 数 名:	Do03Command()
//功    能:	执行03命令,从仪表寄存器读连续数据
//输入参数:	无
//返 回 值:	0(错误),1(成功)
*************************************************/
static	bit	Do03Command(void)
{
	unsigned char	pos, len, i;
	unsigned short	crc;	
	//数据偏移量
	pos	= cCommBuffer[3];
	//数据长度
	len = cCommBuffer[5];

	//读取数据超出范围
	if(len > 30)
	{
		cCommBuffer[0] = ADDRESS;
		cCommBuffer[1] = 0x83;					//出错码
		cCommBuffer[2] = 0x02;					//非法的寄存器

		//CRC校验计算
		crc = cal_crc(&cCommBuffer, 3);
		cCommBuffer[3] = (unsigned char)(crc / 256);
		cCommBuffer[4] = (unsigned char)(crc % 256);

		//发送总字节数
		cUartLen = 5;

		return 0;
	}
	else
	{	
		cCommBuffer[0] = ADDRESS;					//地址
		cCommBuffer[1] = 0x03;						//命令
		cCommBuffer[2] = len;						//数据长度
		//三个通道实时的百分量
		if(pos == 0x32)
		{
			for(i = 0; i < 3; i++)
			{
				cCommBuffer[3 + 2 * i] = *(&TransData.pHPercent +i ) &0xff;
				cCommBuffer[4 + 2 * i] = *(&TransData.pHPercent +i ) >> 8;
			}
			for(i = 0; i < len - 6; i ++)
			{
				cCommBuffer[i + 9] = 0;
			}
			 //__RUN = ~__RUN;
		}
		//标定的码值
		if((pos >= 0x42) && (pos < 0x80))
		{
			for(i = 0; i < len; i++)
			{
				cCommBuffer[3 + i] =*((unsigned char*)&pHCaliParam+pos - 0x42 +  i);
			}
		}
		//AD原码
		if(pos >= 0x80)
		{
			for(i = 0; i < len; i++)
			{
				cCommBuffer[3 + i] = *((unsigned char*)ChannelADCode + pos - 0x80 + i );
			}
			//__RUN = ~__RUN; 
		}
		//__RUN = ~__RUN;
		//CRC校验计算
		crc = cal_crc(&cCommBuffer, len + 3);
		cCommBuffer[len + 3] = (unsigned char)(crc / 256);
		cCommBuffer[len + 4] = (unsigned char)(crc % 256);
			//FlashLed(2); 
		//发送总字节数
		cUartLen = 3 + len + 2;
	
		return	1;
	}
}

/*************************************************
//函 数 名:	Do10Command()
//功    能:	执行10命令,写连续数据到AD板存器
//输入参数:	无
//返 回 值:	0(错误),1(成功)
*************************************************/
static	bit	Do10Command(void)
{
	unsigned char	pos, len, i;
	unsigned short	crc;	
	unsigned char* ptr = (unsigned char*) &pHCaliParam;
	//数据偏移量
	pos	= cCommBuffer[3];
	//数据长度
	len = cCommBuffer[6];
	//上位机写标定码值
	if((pos >= 0x42) && (pos < (0x42+sizeof(CALIPARAM))) && (len <= sizeof(CALIPARAM)))
	{
		//写入数据
		for(i = 0; i < len; i ++)
		{
			*(ptr + i +pos - 0x42) = cCommBuffer[i + 7];
		}
		bFlagWriteConfig = 1;
	}
	//非法写入
	else{
		return 0;
	}			
	//CRC校验计算
	crc = cal_crc(&cCommBuffer, 6);
	cCommBuffer[6] = (unsigned char)(crc / 256);
	cCommBuffer[7] = (unsigned char)(crc % 256);

	//发送总字节数
	cUartLen = 8;
	return	1;
	
}

/*************************************************
//函 数 名:	Do20Command()
//功    能:	执行20命令,标定操作
//输入参数:	无
//返 回 值:	0(错误),1(成功)
************************************************
static	bit	Do20Command(void)
{
 	unsigned char	cmd;
	//float ftemp,ftemp2,ftemp3,ftemp4;
	//short temp;
	cmd=cCommBuffer[7];
	switch(cmd)
	{
		case 0x10:					//读电压值,标定开始后传送给主机mV信号
			bCaling=1;
			break; 

		case 0x11:				   	//下传pH=7.00标准溶液在特定温度的pH值
			spH7AD=ChannelADCode[0][0];	
			bDoubleCali=0;
			bCalied=1;
			break;

		case 0x12:					//读电压值,标定开始后传送给主机mV信号
			bCaling=1;
			break;
			
		case 0x13:				   	//下传pH=4.01标准溶液在特定温度的pH值
			bDoubleCali=1;
			spH4AD=ChannelADCode[0][0];
			bCalied=1;
			break;

		case 0x08:				  	//恢复出厂标定
			if(pHCaliParam.Mode==MODE_ORP)
			{
				pHCaliParam.OrpOnlineUpper=pHCaliParam.OrpUpper;
				pHCaliParam.OrpOnlineLower=pHCaliParam.OrpLower;
			}
			else
			{
				pHCaliParam.pHOnlineUpper=pHCaliParam.pHUpper;
				pHCaliParam.pHOnlineLower=pHCaliParam.pHLower;
			}
			bFlagWriteConfig=1;
			break;

		case 0x00:
							//结束标定
			DoCali();		//计算标定结果
			break;
	}
	__RUN = ~__RUN;
	cUartLen=10;
	return 1;
}*/

/*************************************************
//函 数 名:	Do66Command()
//功    能:	执行66命令,标定命令
//输入参数:	无
//返 回 值:	0(错误),1(成功)
************************************************
static bit Do66Command(void)
{
	unsigned char	pos, len, i;
	unsigned char* 	ptr;
	unsigned short	crc;
	
	//数据首地址
	ptr = (unsigned char*) &pHCaliParam;
	//数据偏移量
	pos	= cCommBuffer[3];
	//数据长度
	len = cCommBuffer[6];


	//读取数据超出范围
	if((pos + len) > sizeof(CALIPARAM))
	{
		cCommBuffer[0] = ADDRESS;
		cCommBuffer[1] = 0x83;					//出错码
		cCommBuffer[2] = 0x02;					//非法的寄存器

		//CRC校验计算
		crc = cal_crc(&cCommBuffer, 3);
		cCommBuffer[3] = (char)(crc / 256);
		cCommBuffer[4] = (char)(crc % 256);

		//发送总字节数
		cUartLen = 5;
		return 0;
	}
	else
	{
		//写入数据
		for(i = 0; i < len; i ++)
		{
			*(ptr + pos + i) = cCommBuffer[i + 7];
		}
	
		//CRC校验计算
		crc = cal_crc(&cCommBuffer, 6);
		cCommBuffer[6] = (char)(crc / 256);
		cCommBuffer[7] = (char)(crc % 256);
	
		//发送总字节数
		cUartLen = 8;

		return	1;
	}	
}*/
/*************************************************
//函 数 名:	InitUart0()
//功    能:	串口0初始化程序
//输入参数:	无
//返 回 值:	无
*************************************************/
static	bit	AnalyseData(void)
{
	unsigned short	crc;
	 
	//step 1	CRC校验检查
	crc = 0x0100 * cCommBuffer[cUartLen - 2] + cCommBuffer[cUartLen - 1];
	if(crc != cal_crc(cCommBuffer, cUartLen - 2))
	{
		return 0;
	}	
	//step 2	Do Command
	if(cCommBuffer[1] == 0x03)					//从仪表寄存器读连续数据
	{
		if(Do03Command())
		{	  
	    	return 1;
		}
	}

	else if(cCommBuffer[1] == 0x10)				//写连续数据到仪表寄存器,并保存组态参数
	{
		if(Do10Command())
		{
												//保存组态参数标志,在主循环中完成
	
			return 1;
		}
	}			
	else
		return 0;
}

/*************************************************
//函 数 名:	ResetReceive()
//功    能:	接收初始化程序
//输入参数:	无
//返 回 值:	无
*************************************************/
static	void	ResetReceive(void)
{
	TI = 0;
	RI = 0;
	REN = 1;
}

/*************************************************
//函 数 名:	InitUart0()
//功    能:	串口0初始化程序
//输入参数:	无
//返 回 值:	无
*************************************************/
void	InitUart0(void)
{
	SCON = 0x90;								//MODE 2,固定波特率=Fosc/64,地址无效,允许接收
	PCON = 0x00;								// /64 PCON=0x80 /32
	ES	= 1;									//通讯中断允许
}

/*************************************************
//函 数 名:	uart0()
//功    能:	串口0通讯程序
//输入参数:	无
//返 回 值:	无
*************************************************/
void	uart0(void)	interrupt	INTERRUPT_UART_0
{	 
	//接收数据
	if(!UartReceive())
	{
		//接收复位
		ResetReceive();
		return;
	} 
	//进行数据处理和命令执行
	if(!AnalyseData())
		return;
	//发送数据
	UartTransmit();
	//接收复位
	ResetReceive();	 
	return;
}


/*************************************************
//函 数 名:	SaveCaliParam
//功    能:	保存标定参数
//输入参数:	无
//返 回 值:	无
*************************************************/
void SaveCaliParam(void)
{
	if(bFlagWriteConfig)//如果写标定位为1则保存标定值
	{
		bFlagWriteConfig = 0;
		PutCaliParam();		//存标定参数
	}
}

⌨️ 快捷键说明

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