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

📄 zjpro.c

📁 电能表源码
💻 C
字号:
#include "dw8051.h"
#include "zjpro.h"

void Init_Pzj(void)
{	// 接受缓存1初始化
	Ubuff[DEFRBUFF].buffadd = ProBuff;
	Ubuff[DEFRBUFF].bufflen = UBUFFLEN;
	Ubuff[DEFRBUFF].buffplen = 0;
	Ubuff[DEFRBUFF].pbuff = Ubuff[0].buffadd;
//	Ubuff[DEFRBUFF].rpbuff = Ubuff[0].buffadd;
	// 发送缓存初始化
	Ubuff[DEFTBUFF].buffadd = ProBuff;
	Ubuff[DEFTBUFF].bufflen = UBUFFLEN;
	Ubuff[DEFTBUFF].buffplen = 0;
	Ubuff[DEFTBUFF].pbuff = Ubuff[DEFTBUFF].buffadd;
	
	UDS.bits.UMOD = 0;
	MeterCode[0] = 0+0x33;
	MeterCode[1] = 0x12+0x33;
	MeterCode[2] = 0x34+0x33;
	MeterCode[3] = 0x56+0x33;
}

/*
	数据接受--当前默认uart3
*/
char RecvPData(void)
{
	uint8 xdata *point;
	uint8 xdata *p;
	if(UDS.bits.UMOD == 4 || UDS.bits.UMOD == 2)
		return 1;
	point = UARTADDR;		// SBUF3
//	ACC = *point;
//	if(P)
//	{
//		UDS.bits.FByte = 1;			// 字节校验错
//		return -1;
//	}
	p = Ubuff[DEFRBUFF].pbuff;
	*p = *point;
	Ubuff[DEFRBUFF].pbuff++;
	Ubuff[DEFRBUFF].buffplen++;
	if(*p == 0x68 && UDS.bits.UMOD == 0)
	{	// 接受到起始符
		Ubuff[DEFRBUFF].pbuff = Ubuff[DEFRBUFF].buffadd;
		*Ubuff[DEFRBUFF].pbuff = *p;
		Ubuff[DEFRBUFF].pbuff++;			
		Ubuff[DEFRBUFF].buffplen = 1;
		UDS.bits.UMOD = 1;
	}
	else if(*p == 0x16)
	{	// 接受到结束符
		if(UDS.bits.UMOD == 1)	// 并且已经启动了接受
		{
			UDS.bits.UMOD = 4;	// 接受完成
		}
		else					// 否则归零,视为无效数据
		{
			Ubuff[DEFRBUFF].pbuff = Ubuff[DEFRBUFF].buffadd;
			Ubuff[DEFRBUFF].buffplen = 0;				
		}
	}
	return 0;
}

/*
	数据发送--当前默认uart3
*/
void TranPData(void)
{
	uint8 xdata *point;
	uint8 xdata *p;
	
	if(Ubuff[DEFTBUFF].buffplen == 0)
	{
//		UMS.bits.FRBA = 0;			// 发送处理完毕,再次开放缓存用于接受
		Ubuff[DEFTBUFF].pbuff = Ubuff[DEFTBUFF].buffadd;
		Ubuff[DEFTBUFF].buffplen = 0;		
		UDS.bits.UMOD = 0;
		return;
	}
	point = UARTADDR-1;				// SCONx
	p = Ubuff[DEFTBUFF].pbuff;
	ACC = *p;
	*point = *point | ((uint8)P)<<3;// TB8
	point++;						// SBUFx
	*point = *p;
	Ubuff[DEFTBUFF].pbuff++;
	Ubuff[DEFTBUFF].buffplen--;
	UDS.bits.UMOD = 2;
}
/*
	启动数据发送--当前默认uart3
*/
void StartTranUData(uint8 vlen)
{
	uint8 xdata *point;
	uint8 xdata *p;

//	Ubuff[DEFTBUFF].buffadd = TransBuff;
	Ubuff[DEFTBUFF].bufflen = UBUFFLEN;
	Ubuff[DEFTBUFF].buffplen = vlen;
	Ubuff[DEFTBUFF].pbuff = Ubuff[DEFTBUFF].buffadd;
	
	UDS.bits.UMOD = 2;				// 切换成发送模式
	point = UARTADDR-1;				// SCONx 
	p = Ubuff[DEFTBUFF].pbuff;
	ACC = *p;						//
	*point = *point | ((uint8)P)<<3;// TB8
	point++;						// SBUFx
	*point = *p;					
	Ubuff[DEFTBUFF].pbuff++;
	Ubuff[DEFTBUFF].buffplen--;
}
/*
	正常返回
*/
void ReturnPro(uint8 val)
{
	unsigned char i,cs;
//	unsigned char xdata temp;
//	unsigned char xdata *p;

	Ubuff[DEFTBUFF].buffadd = ProBuff;
	Ubuff[DEFTBUFF].bufflen = UBUFFLEN;
	Ubuff[DEFTBUFF].buffplen = 0;
	Ubuff[DEFTBUFF].pbuff = Ubuff[DEFTBUFF].buffadd;

	*(Ubuff[DEFTBUFF].pbuff++) = 0x68;
	*(Ubuff[DEFTBUFF].pbuff++) = 0x99;
	*(Ubuff[DEFTBUFF].pbuff++) = 0x99;
	*(Ubuff[DEFTBUFF].pbuff++) = 0x99;
	*(Ubuff[DEFTBUFF].pbuff++) = 0x99;
	*(Ubuff[DEFTBUFF].pbuff++) = 0x99;
	*(Ubuff[DEFTBUFF].pbuff++) = 0x99;
	*(Ubuff[DEFTBUFF].pbuff++) = 0x68;			// 帧头
	cs = 0x66;
	if(val == 1)
	{// 读返回
		*(Ubuff[DEFTBUFF].pbuff++) = 0x81;				// 控制码
		cs += 0x81;
		*(Ubuff[DEFTBUFF].pbuff++) = InstPro.bufflen+2;	// 长度
		cs += InstPro.bufflen;
		*(Ubuff[DEFTBUFF].pbuff++) = *InterPro.pd;
		cs += *InterPro.pd;
		*(Ubuff[DEFTBUFF].pbuff++) = *(InterPro.pd+1);
		cs += *(InterPro.pd+1);
		for(i = 0; i < InstPro.bufflen; i++)
		{
//			temp = *InstPro.pbuff;
			*Ubuff[DEFTBUFF].pbuff = *InstPro.pbuff+0x33;// 数据
			cs += *InstPro.pbuff+0x33;
			Ubuff[DEFTBUFF].pbuff++;
			InstPro.pbuff++;
		}
		*(Ubuff[DEFTBUFF].pbuff++) = cs;
		*(Ubuff[DEFTBUFF].pbuff++) = 0x16;
		StartTranUData(14+InstPro.bufflen);
	}
	else if(val == 2)
	{// 写返回
		*(Ubuff[DEFTBUFF].pbuff++) = 0x84;				// 控制码
		cs += 0x84;
		*(Ubuff[DEFTBUFF].pbuff++) = 0x00;				// 长度
		cs += 0;
		*(Ubuff[DEFTBUFF].pbuff++) = cs;
		*Ubuff[DEFTBUFF].pbuff = 0x16;
		StartTranUData(12);
	}
	else if(val == 3)
	{// 修改密码返回
		*(Ubuff[DEFTBUFF].pbuff++) = 0x8f;				// 控制码
		cs += 0x8f;
		*(Ubuff[DEFTBUFF].pbuff++) = 0x04;				// 长度
		cs += 0x04;
		*(Ubuff[DEFTBUFF].pbuff++) = MeterCode[0];		// 密码1
		cs += MeterCode[0];
		*(Ubuff[DEFTBUFF].pbuff++) = MeterCode[1];		// 密码2
		cs += MeterCode[1];
		*(Ubuff[DEFTBUFF].pbuff++) = MeterCode[2];		// 密码3
		cs += MeterCode[2];
		*(Ubuff[DEFTBUFF].pbuff++) = MeterCode[3];		// 密码4
		cs += MeterCode[3];
		*(Ubuff[DEFTBUFF].pbuff++) = cs;				// cs
		*Ubuff[DEFTBUFF].pbuff = 0x16;					// end
		StartTranUData(16);		
	}
	else if(val == 4)
	{// 广播校时无返回
		UDS.bits.UMOD = 0;
	}
}
/*
	异常返回
*/
void ReturnErr(uint8 val)
{
	unsigned char cs;

	Ubuff[DEFTBUFF].buffadd = ProBuff;
	Ubuff[DEFTBUFF].bufflen = UBUFFLEN;
	Ubuff[DEFTBUFF].buffplen = 0;
	Ubuff[DEFTBUFF].pbuff = Ubuff[DEFTBUFF].buffadd;

	*(Ubuff[DEFTBUFF].pbuff++) = 0x68;
	*(Ubuff[DEFTBUFF].pbuff++) = 0x99;
	*(Ubuff[DEFTBUFF].pbuff++) = 0x99;
	*(Ubuff[DEFTBUFF].pbuff++) = 0x99;
	*(Ubuff[DEFTBUFF].pbuff++) = 0x99;
	*(Ubuff[DEFTBUFF].pbuff++) = 0x99;
	*(Ubuff[DEFTBUFF].pbuff++) = 0x99;
	*(Ubuff[DEFTBUFF].pbuff++) = 0x68;			// 帧头
	cs = 0x66;
	if(val == 1)
	{// 读返回
		*(Ubuff[DEFTBUFF].pbuff++) = 0xc1;
		cs += 0xc1;
	}
	else if(val == 2)
	{// 写返回
		*(Ubuff[DEFTBUFF].pbuff++) = 0xc4;
		cs += 0xc4;
	}
	*(Ubuff[DEFTBUFF].pbuff++) = 0x01;
	cs += 0x01;
	*(Ubuff[DEFTBUFF].pbuff++) = ERROR_FLG;
	cs += ERROR_FLG;
	*(Ubuff[DEFTBUFF].pbuff++) = cs;
	*Ubuff[DEFTBUFF].pbuff = 0x16;		
	StartTranUData(13);		
}
/*
	645规约解包函数
	返回0表示成功
*/
char DT645(void)
{
	unsigned char cs,i,pi;
	unsigned char xdata *p;
	
	cs = 255;
	p = Ubuff[DEFRBUFF].buffadd;
	for(pi = 0; pi < Ubuff[DEFRBUFF].buffplen; pi++)	// 找到帧头
	{
		if(*(p+pi) == 0x68 && *(p+7+pi) == 0x68)
		{
			cs = 0;
			break;
		}
	}
	if(cs == 255)
	{	// 找不到帧头,返回出错
		return -1;
	}
	p = p+pi;	// 指针位置对齐
	InterPro.CtrlByte = *(p+8);							// 获得控制字
	InterPro.Lenth = *(p+9);							// 获得数据域长度
	if(*(p+11+InterPro.Lenth) != 0x16)
	{	// 当结束字符不在指定位置时,返回出错
		return -1;
	}
	// 计算校验码
//	cs = 0x68;
	for(i = 0; i < 10+InterPro.Lenth; i++)
	{
		cs += *(p+i);
	}
	if(cs != *(p+10+InterPro.Lenth))
	{	// 校验码出错返回
		ERROR_FLG = 0x01;
		return -2;
	}
	InterPro.pd = p+10;									// 数据首地址指针
	for(i = 0; i < 6; i++)								// 填入表号
	{
		InterPro.MeterSeri[i] = *(p+1+i);
	}
	// 解析成功返回
	return 0;
}
/*
	获取内部ID号
*/
char GetIntPro(unsigned int v_CB)
{
	unsigned char i;
	
	for(i = 0; i < TABLENUMBER; i++)
	{
		if(InstList[i].OutsideInst == v_CB)//
		{
			break;
		}
	}
	if(i == TABLENUMBER)
	{// 找不到ID号
		return -1;
	}
	InstPro.DF.value = InstList[i].InterInst;
	InstPro.bufflen = InstList[i].DLen;
	InstPro.pbuff = InstList[i].DAddr;
	return 0;
}
/*
	转成内部协议
*/
char T2InPro(void)
{
	unsigned char t,i,j;
	unsigned int CB;
	// 通用表号扫描
	for(j = 0; j < MSANo; j++)
	{
		t = 0;
		for(i = 0; i < 6; i++)
		{
			if(InterPro.MeterSeri[i] != MSAccess[j][i])
			{
				t = 255;
				break;
			}
		}
		if(!t)
		{// 表号匹配成功
			break;
		}
	}
	if(t)
	{// 检测完毕仍然没有找到匹配项
		return -1;
	}
	if(InterPro.CtrlByte == 0x01)			// 读数据
	{
		InstPro.CtrlByte = 0;
		CB = *InterPro.pd-0x33;
		CB <<= 8;
		CB |= *(InterPro.pd+1)-0x33;		// 
		// 根据外部规约的数据标识找到内部数据标识
		if(GetIntPro(CB) == -1)
		{// 数据标识错
			ERROR_FLG = 0x02;
			ReturnErr(1);
		}
		else
		{
			ReturnPro(1);
		}
	}
	else 									// 写操作
	{
		if(InterPro.CtrlByte == 0x04)		// 写数据
		{
			InstPro.CtrlByte = 1;
			if(*(InterPro.pd+2) != MeterCode[0] || *(InterPro.pd+3) != MeterCode[1] || 
				*(InterPro.pd+4) != MeterCode[2] || *(InterPro.pd+5) != MeterCode[3])
			{// 密码不匹配
				ERROR_FLG = 0x04;
				ReturnErr(2);
				return -1;
			}
			CB = *InterPro.pd-0x33;
			CB <<= 8;
			CB |= *(InterPro.pd+1)-0x33;	// 
			// 根据外部规约的数据标识找到内部数据标识
			GetIntPro(CB);
			InstPro.bufflen = InterPro.Lenth-6;
			InstPro.pbuff = InterPro.pd+6;
			for(i = 0; i < InstPro.bufflen; i++)
			{// -33H处理
				*(InstPro.pbuff+i) -= 0x33;
			}
			ReturnPro(2);			
		}
		else if(InterPro.CtrlByte == 0x08)	// 广播校时
		{
			InstPro.CtrlByte = 1;
			InstPro.DF.value = 0x8100;	// 内部指令码
			InstPro.bufflen = InterPro.Lenth;
			InstPro.pbuff = InterPro.pd;
			for(i = 0; i < InstPro.bufflen; i++)
			{// -33H处理
				*(InstPro.pbuff+i) -= 0x33;
			}
			pSetRTC.rSecond = *(InstPro.pbuff+0);
			pSetRTC.rMinute = *(InstPro.pbuff+1);
			pSetRTC.rHour = *(InstPro.pbuff+2);
			pSetRTC.rDate = *(InstPro.pbuff+3);
			pSetRTC.rMonth = *(InstPro.pbuff+4);
			pSetRTC.rYear = *(InstPro.pbuff+5);
			SetRTCTime(pSetRTC);
			ReturnPro(4);			
		}
		else if(InterPro.CtrlByte == 0x0f)	// 修改密码
		{
			InstPro.CtrlByte = 1;
			if(*(InterPro.pd+0) != MeterCode[0] || *(InterPro.pd+1) != MeterCode[1] || 
				*(InterPro.pd+2) != MeterCode[2] || *(InterPro.pd+3) != MeterCode[3])
			{// 密码不匹配
				ERROR_FLG = 0x04;
				return -1;
			}
			InstPro.DF.value = 0x8202;	// 内部指令码
			InstPro.bufflen = InterPro.Lenth-4;
			InstPro.pbuff = InterPro.pd+4;
			for(i = 0; i < InstPro.bufflen; i++)
			{// 密码拷贝
				MeterCode[i] = *(InstPro.pbuff+i);
			}
			ReturnPro(3);			
		}
	}
	
	return 0;		
}

char GProZJ(void)
{
	if(UDS.bits.UMOD == 4)
	{
		if(!DT645())		// 规约解包正确
		{
			return(T2InPro());//
		}
		else
		{
			return -1;
		}
	}
	else
	{
		return -1;
	}
}

⌨️ 快捷键说明

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