1107.c

来自「电能表源码」· C语言 代码 · 共 1,319 行 · 第 1/3 页

C
1,319
字号
//	StartTranUData(vno+5);
//}
/*
	FLASH写操作
	入口参数:	
				von-----操作个数
				*tp-----目标地址指针,需要写数据的目标地址
				*vp-----写数据时的数据源起始指针
*/
//void WFLASH(uint8 vno,uint8 code *tp,uint8 xdata *vp)
//{
//	uint8 code *point;
//	uint8 xdata *p;
//	uint8 i;
//	
//	point = tp;
//	p = vp;
//#ifdef DEF_TBUFF_STRUCTURE	
//	for(i = 0; i < vno; i++)
//	{	// 填写data
//		TransBuff[i] = *p;
//		p++;
//	}
//#else
//	Ubuff[DEFTBUFF].pbuff = Ubuff[DEFTBUFF].buffadd;
//	for(i = 0; i < vno; i++)
//	{	// 填写data
//		*(Ubuff[DEFTBUFF].pbuff+i) = *p;
//		p++;
//	}
//#endif
//	if(WState)
//	{	// 处在编程允许状态
//	#ifdef DEF_TBUFF_STRUCTURE	
//		TransBuff[i] = ACK;
//	#else
//		*(Ubuff[DEFTBUFF].pbuff+i) = ACK;
//	#endif	
//		p = vp; 
//		for(i = 0; i < vno; i++)
//		{
//			IAP_FLASH_ByteWrite((uint16)point,*p);
//			point++;
//			p++;
//		}
//		StartTranUData(vno+1);		
//	}
//	else
//	{	// 处在编程禁止状态
//	#ifdef DEF_TBUFF_STRUCTURE	
//		TransBuff[i+0] = SOH;
//		TransBuff[i+1] = 'B';
//		TransBuff[i+2] = '0';
//		TransBuff[i+3] = ETX;
//		TransBuff[i+4] = 0x71;	// BCC
//	#else
//		*(Ubuff[DEFTBUFF].pbuff+i+0) = SOH;
//		*(Ubuff[DEFTBUFF].pbuff+i+1) = 'B';
//		*(Ubuff[DEFTBUFF].pbuff+i+2) = '0';
//		*(Ubuff[DEFTBUFF].pbuff+i+3) = ETX;
//		*(Ubuff[DEFTBUFF].pbuff+i+4) = 0x71;
//	#endif	
//		StartTranUData(vno+5);					
//	}			
//}
///*
//	读RAM数据
//	入口参数:	
//				von-----操作个数
//				*tp-----目标地址指针,需要读数据的目标地址
//	出口参数:	直接通过串口发送给外部	
//*/
//void RRAM(uint8 vno,uint8 xdata *tp)
//{
//	uint8 xdata *point;
//	uint8 xdata *p;
//	uint8 i,bcc;
//	
//	point = tp;
//	Ubuff[DEFTBUFF].pbuff = Ubuff[DEFTBUFF].buffadd;
//	*Ubuff[DEFTBUFF].pbuff = STX;
//	*(Ubuff[DEFTBUFF].pbuff+1) = '(';
//	p = Ubuff[DEFTBUFF].pbuff+2;
//	bcc = '(';
//	for(i = 0; i < vno; i++)
//	{
//		*p = *point;
//		bcc ^= *point;
//		p++;
//		point++;
//	}
//	*(Ubuff[DEFTBUFF].pbuff+2+vno) = ')';
//	bcc ^= ')';
//	*(Ubuff[DEFTBUFF].pbuff+3+vno) = ETX;
//	bcc ^= ETX;
//	*(Ubuff[DEFTBUFF].pbuff+4+vno) = bcc;
//	StartTranUData(vno+5);	
//}
///*
//	RAM写操作
//	入口参数:	
//				von-----操作个数
//				*tp-----目标地址指针,需要写数据的目标地址
//				*vp-----写数据时的数据源起始指针
//*/
//void WRAM(uint8 vi,uint8 xdata *tp,uint8 xdata *vp)
//{
//	uint8 xdata *point;
//	uint8 xdata *p;
//	uint8 i,vno,cs;
//	uint16 code *pAddr1;
//	uint16 code *pAddr2;
//	
//	point = tp;
//	p = vp;
//	vno = InstList[vi].DLen;
////	pAddr1 = InstList[vi].WAddrA;
////	pAddr2 = InstList[vi].WAddrB;
//	cs = 0;
//	Ubuff[DEFTBUFF].pbuff = Ubuff[DEFTBUFF].buffadd;
//	for(i = 0; i < vno; i++)
//	{	// 填写data
//		*(Ubuff[DEFTBUFF].pbuff+i) = *p;
//		p++;
//	}
//	if(WState)
//	{	// 处在编程允许状态
//		*(Ubuff[DEFTBUFF].pbuff+i) = ACK;
//		p = vp; 
//		for(i = 0; i < vno; i++)
//		{
//			*point = *p;
//			cs += *p;
//			point++;
//			p++;
//		}
//		StartTranUData(vno+1);		
//	}
//	else
//	{	// 处在编程禁止状态
//		*(Ubuff[DEFTBUFF].pbuff+i+0) = SOH;
//		*(Ubuff[DEFTBUFF].pbuff+i+1) = 'B';
//		*(Ubuff[DEFTBUFF].pbuff+i+2) = '0';
//		*(Ubuff[DEFTBUFF].pbuff+i+3) = ETX;
//		*(Ubuff[DEFTBUFF].pbuff+i+4) = 0x71;
//		StartTranUData(vno+5);					
//	}			
//}
/*
	数据处理
*//*
void CData1107(uint8 xdata *vp,uint8 vi)
{//
	uint8 xdata *tp;
	uint8 tlen,ttype,tleg,tadt;
	uint16 taddr;
	
	tlen = InstList[vi].DLen;			// 数据长度
	ttype = InstList[vi].US.bits.DT;	// 数据存储格式
	tleg = InstList[vi].IegAtr;			// 数据合法类型
	tadt = InstList[vi].US.bits.DAT;	// 数据读地址属性
	taddr = InstList[vi].DAddr;			// 数据读地址
	
	if(Recvrw == 'R')
	{	// 读FLASH操作
		RFLASH(InstList[i].DLen,tcp);
	}
	else if(Recvrw == 'W')
	{	// 写FLASH操作
		CheckIegInst(p,InstList[i].DLen,InstList[i].IegAtr);
		WFLASH(InstList[i].DLen,tcp,p);
	}	
}*/
/*
	指令检测
*/
char CheckInst(uint8 xdata *vp)
{
	uint8 xdata *p;		// 指向xdata空间的指针
	uint8 code *tcp;	// 指向code空间的指针
	uint8 i,j,ti;		// 循环变量
	
	ti = MaxInst;	
	p = &InstArry[0];
	for(i = 0; i < MaxInst; i++)
	{	
		if(*(p+i) == '(')
		{	// 记录下'('的位置
			if(Recvrw == 'R')
			{	// 接受到的读指令的格式为A.A.A*A()
//				ti = i;
				*(p+i) = '*';
				ti = i + 1;
			}
			else if(Recvrw == 'W')
			{	// 接受到的写指令的格式为A.A.A(D...)
				*(p+i) = '*';
				ti = i + 1;
			}
		}
	}
	for(i = ti; i < MaxInst; i++)
	{	// 统一成A.A.A*A的标准模式
		*(p+i) = 'A';
	}
	// 指令寻址
	for(i = 0; i < TABLENUMBER; i++)
	{	
		for(j = 0; j < MaxInst; j++)
		{
			tcp = &InstList[i].Inst[j];
			p = &InstArry[j];
			if(*p != *tcp)
				break;	// 有一个比对错误则退出当前子循环
		}
		if(j == MaxInst)	// 说明全部比对成功
			break;			// 比对成功则退出大循环
	}
	if(i == TABLENUMBER)	// 说明没有找到指令码
		return -1;			// 没有此条指令
	else					// 反之表示指令码匹配成功
	{
		InstPro.DF.value = InstList[i].InterInst;	// 内部协议id号
		InstPro.bufflen = InstList[i].DLen;			// 数据长度
		ListLen = i;					// 记下内部通讯协议表位置
		if(Recvrw == 'W')
		{	// 数据格式转换
			ti = InstPro.bufflen % 2;	// 奇数个or偶数个
			j = InstPro.bufflen / 2;
			p = vp + ti + 4;
			Ubuff[DEFTBUFF].pbuff = Ubuff[DEFTBUFF].buffadd;
			if(ti)	
			{	// 奇数个时先做一次变换
				*Ubuff[DEFTBUFF].pbuff = ASC2BCD(0,*p);
				Ubuff[DEFTBUFF].pbuff++;
				p++;
			}
			for(i = ti; i < InstPro.bufflen; i+=2)
			{
				*Ubuff[DEFTBUFF].pbuff = ASC2BCD(*(p+i),*(p+1+i));
				Ubuff[DEFTBUFF].pbuff++;
			}
			InstPro.pbuff = Ubuff[DEFTBUFF].buffadd;// 数据指针
			InstPro.bufflen = j + ti;				// 数据长度			
			InstPro.CtrlByte = 1+InstList[i].IA;	// 写操作
		}
		else if(Recvrw == 'R')
		{											// 数据指针
			InstPro.pbuff = Ubuff[DEFTBUFF].buffadd+2;
			InstPro.CtrlByte = 0;					// 读操作
		}	
	}
	return 0;
}
/*
	状态机复位指令检测
*/
char CheckReset(uint8 xdata *vp,uint8 vlen)
{
	uint8 xdata *p;
//	uint8 xdata *pBPS;
	uint8 i;
	
	p = vp;				
	for(i = 0; i < vlen; i++)
	{
		if(*p == SOH && *(p+1) == 'B' && *(p+2) == '0' && *(p+3) == ETX && *(p+4) == 0x71)
		{
			UMS.bits.PS = 0;		// 状态机复位	
			FHead[0] = '/';
			FHead[1] = SOH;			// 第一个有效字符
			UMS.bits.FRBA = 0;		// 接受处理完毕,再次开放接受缓存
			Ubuff[DEFRBUFF].pbuff = Ubuff[DEFRBUFF].buffadd;
			Ubuff[DEFRBUFF].buffplen = 0;
//			SwitchBPS(UARTSERI,0);
			InstPro.CtrlByte = 0x10;// 波特率归零
			CfgEU(UARTSERI,300,10,0);
			//*pBPS = 0;
			//InstPro.pbuff = pBPS;
			//InstPro.bufflen = 1;
			UDS.bits.UMOD = 0;
			return 0;				// 找到匹配项
		}
		p++;
	}
	return -1;						// 没有找到匹配项
}
/*
	帧校验
	入口参数	val_buffno----需要校验的缓存号
*/
char CheckFram1107(uint8 val_buffno)
{
	uint8 i,j,tlen;
	uint8 xdata *p;
//	uint8 xdata *pBPS;
//	uint8 xdata tempbuff[20];
	
	i = 0;
	j = -2;		// 初始化
	tlen = Ubuff[val_buffno].buffplen;
	p = Ubuff[val_buffno].pbuff;
	
	i = CheckReset(p,tlen);
	if(i)						// 如果不是复位状态机指令
	{					
		switch(UMS.bits.PS)
		{
			case 0:			// 握手状态机
				i = Step0Cp1107(p,tlen);
				if(i != -1)
				{	// 
					Step0ACK1107();		// 握手成功,发送建议通讯波特率,转入下一个状态机
					UTest = 0x01;
				}
				else
				{
					UMS.bits.FRBA = 0;			// 接受处理完毕,再次开放接受缓存
					Ubuff[DEFRBUFF].pbuff = Ubuff[DEFRBUFF].buffadd;
					Ubuff[DEFRBUFF].buffplen = 0;
					UTest = 0x11;
					UDS.bits.UMOD = 0;
				}
				break;		
			case 1:			// 波特率确认状态机
				i = Step1Cp1107(p,tlen);
				if(!i)
				{	// 匹配成功处理
					UTest = 0x02;
					UDS.bits.CBPS = UDS.bits.RBPS;		// 将使用波特率修改为推荐波特率
//					SwitchBPS(UARTSERI,UDS.bits.CBPS);			// 切换波特率
					CfgEU(UARTSERI,300*(1+UDS.bits.CBPS),10,0);
					//InstPro.CtrlByte = 0x10;
					//*pBPS = UDS.bits.CBPS;
					//InstPro.pbuff = pBPS;
					//InstPro.bufflen = 1;
					//j = 0;
					Step1ACK1107();		// 请求密码,转入下一个状态机
					//RecvBuffA[0] = 0;
				}
				else if(i == -1)
				{	// 波特率不匹配,使用300bps
					UTest = 0x12;
					UDS.bits.CBPS = 0;
					Step1ACK1107();		// 请求密码,转入下一个状态机
					//RecvBuffA[0] = 0;
				}
				else if(i == -2)
				{	// 帧解析错误
					UTest = 0x22;
					NAK_NERR();			// 返回 1,'B','0',3,BCC
				}
				break;
			case 2:			// 密码认证状态机
				i = Step1Cp1107(p,tlen);
				if(!i)
				{	// 匹配成功处理
					UTest = 0x03;
					Step1ACK1107();		// 请求密码,转入下一个状态机
					break;
				}
				i = Step2Cp1107(p,tlen);
				if(!i)					// 密码匹配成功,转入下一个状态机(数据通讯阶段)
				{
					UTest = 0x13;
					Step2ACK1107();		// 返回 ACK
				}
				else if(i == -1)		// 数据帧错误
				{
					UTest = 0x23;
					NAK_NERR();			// 返回 1,'B','0',3,BCC
				}
				else if(i == -2)		// BCC错误
				{
					UTest = 0x33;
					ERO_NERR();			// 返回ERO标识
				}
				break;
			case 3:			// 数据通讯状态机
				i = Step3Cp1107(p,tlen);
				if(!i)					// 匹配成功,进行指令操作
				{
					i = CheckInst(p);	// 指令操作
					UTest = 0x04;
					if(i == -1)			// 无此指令
					{
						UTest = 0x14;
						RET_NAK();		// 回复错误
					}
					else
					{
						j = 0;			// 数据帧通讯请求
					}
				}
				else if(i == -1)		// 数据帧错误
				{
					UTest = 0x24;
					RET_NAK();			// 返回NAK指令
				}
				else if(i == -2)		// BCC错误
				{
					UTest = 0x34;
					ERO_NERR();			// 返回ERO标识
				}
				break;
			default:
				UMS.bits.PS = 0;	// 如果遇到状态机不在上述范围,则复位状态机
				UTest = 0x05;
				break;
		}
	}
//	else
//	{	// 当是复位指令时提起应用层需要波特率切换
//		j = 0;
//	}
	return j;
}
/*
	规约解析函数
	出口参数:	-1---没有接受到数据
				0----数据解析完成且正确,用户可通过InstPro结构体获得解析结果
				-2---数据解析完成但错误,用户可不需要操作
*/
char G1107Pro(void)
{
	if(UDS.bits.UMOD == 4)
	{
		Ubuff[DEFRBUFF].pbuff = Ubuff[DEFRBUFF].buffadd;
		UMS.bits.FRBA = 1;		// 缓存数据准备就绪
		return(CheckFram1107(0));
	}
	else
	{
		return -1;
	}
}

#undef _PRO1107_C_	

⌨️ 快捷键说明

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