1107.c

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

C
1,319
字号
#define _PRO1107_C_

//#include "var.h"
//#include "reg52.h"
#include "1107.h"


//uint8 ASC2HEX(uint8 vdin1,uint8 vdin2)
//{
//	uint8 temp1,temp2;
//	
//	temp1 = vdin1 - 0x30;
//	temp1 *= 10;
//	temp2 = vdin2 - 0x30;
//	temp1 += temp2;
//	return temp1;
//}
uint8 ASC2BCD(uint8 vdin1,uint8 vdin2)
{
	uint8 temp1,temp2;
	
	temp1 = vdin1 - 0x30;
	temp1 <<= 4;
	temp2 = vdin2 - 0x30;
	temp1 += temp2;
	return temp1;
}
uint16 BCD2ASC(uint8 vdin)
{
	uint16 temp16;
	uint8 temp8;
	
	temp8 = vdin & 0x0f;
	temp8 += 0x30;
	temp16 = temp8;
	temp8 = vdin & 0xf0;
	temp8 >>= 4;
	temp8 += 0x30;
	temp16 += (((uint16)temp8) << 8);
	return temp16;
}		
//#define DEBUG
/*
	函数功能:波特率切换
	入口:	val_numb---串口号-----------2/3/4/5
			val_bps----目标波特率-------1200bps/2400bps/4800bps/9600bps
	出口:	1----设置成功
			0----串口号出错
			-2---波特率出错			
	注:目前支持串口方式为10位/11位;波特率支持1200bps,2400bps,4800bps,9600bps		
*/
//char SwitchBPS(unsigned char val_numb,unsigned char val_bps)
//{
//	unsigned char temp1,temp2;
//	unsigned char xdata *point;//
//	temp2 = 0;
////==================串口号定位================================	
//	if(val_numb > 5 || val_numb <2)
//	{
//		return 0;									// 串口号找不到
//	}
//	point = 0x2820 + (8*(val_numb-2));	// TCONx
//	*point &= ~0xa2;						// clear T1M & SMOD & TR1
////==================波特率发生器模式设定======================
//	point++;							// TMODx
////==================串口波特率设定============================	
//	switch(val_bps)
//	{
//		case 0:	temp1 = 0xc7;temp2 = 2;break;	// T1M = 0,SMOD = 1;
//		case 1:	temp1 = 0xf2;temp2 = 3;break;	// T1M = 0,SMOD = 0;
//		case 2:	temp1 = 0xab;break;				// T1M = 1,SMOD = 0;
//		case 3:	temp1 = 0xab;temp2 = 1;break;	// T1M = 1,SMOD = 1;
//		case 4:	temp1 = 0xeb;break;				// T1M = 1,SMOD = 0;
//		case 5:	temp1 = 0xeb;temp2 = 1;break;	// T1M = 1,SMOD = 1;
//		default:return -2;break;				// 波特率不支持
//	}		
//	point += 2;							// TH1
//	*point = temp1;
//	point += 2;							// TL1
//	*point = temp1;
////===================波特率加倍设定============================	
//	point -= 5;							// TCONx
//	if(temp2 == 0)
//	{
//		*point |= 0x20;					// T1M = 1 波特率不加倍
//	}
//	else if(temp2 == 1)
//	{
//		*point |= 0x20 | 0x80;			// T1M = 1 波特率加倍
//	}
//	else if(temp2 == 2)
//	{
//		*point |= 0x80;					// T1M = 0 波特率加倍
//	}
////===================开启波特率发生器==========================		
//	*point |= 0x02;						// TR1 = 1;
//	return 1;
//}

void Init_P1107(void)
{	// 接受缓存1初始化
	Ubuff[DEFRBUFF].buffadd = RecvBuffA;
	Ubuff[DEFRBUFF].bufflen = UBUFFLEN;
	Ubuff[DEFRBUFF].buffplen = 0;
	Ubuff[DEFRBUFF].pbuff = Ubuff[0].buffadd;
//	Ubuff[DEFRBUFF].rpbuff = Ubuff[0].buffadd;
	// 发送缓存初始化
	Ubuff[DEFTBUFF].buffadd = RecvBuffA;
	Ubuff[DEFTBUFF].bufflen = UBUFFLEN;
	Ubuff[DEFTBUFF].buffplen = 0;
	Ubuff[DEFTBUFF].pbuff = Ubuff[DEFTBUFF].buffadd;
	
//	TransBuff[0] = 0x11;
//	TransBuff[1] = 0x13;
	// 底层规约状态初始化
	UMS.bits.PS = 0;
	UMS.bits.FRBS = 0;
	UDS.bits.UMOD = 0;
	UDS.bits.RBPS = 4;		// 修改推荐使用的波特率
	FHead[0] = '/';
	FHead[1] = SOH;
//	FEnd[0] = CR;
//	FEnd[1] = ETX;
//	UniC = 0;
}
	
/*
	数据接受--当前默认uart3
*/
char RecvUpData(void)
{
	uint8 xdata *point;
	uint8 xdata *p;
#ifdef DEBUG
#else	
	if(UDS.bits.UMOD == 4 || UDS.bits.UMOD == 2)
		return 1;
#endif
	point = UARTADDR;		// SBUF3
	ACC = *point;
	if(P)
	{
		UDS.bits.FByte = 1;			// 字节校验错
		return -1;
	}
	p = Ubuff[DEFRBUFF].pbuff;
	*p = *point & 0x7f;
#ifdef DEBUG
	Ubuff[DEFRBUFF].pbuff++;
	Ubuff[DEFRBUFF].buffplen++;
#else		
	Ubuff[DEFRBUFF].pbuff++;
	Ubuff[DEFRBUFF].buffplen++;
	if(UDS.bits.UMOD == 3)
	{
		UDS.bits.UMOD = 4;
		return 0;
	}

	if(*p == FHead[0] || *p == FHead[1])
	{	// 接受到起始符
		Ubuff[DEFRBUFF].pbuff = Ubuff[DEFRBUFF].buffadd;
		*Ubuff[DEFRBUFF].pbuff = *p;
		Ubuff[DEFRBUFF].pbuff++;			
		Ubuff[DEFRBUFF].buffplen = 1;
		UDS.bits.UMOD = 1;
	}
	else if(*p == ETX || *p == CR)
	{	// 接受到结束符
		if(UDS.bits.UMOD == 1)	// 并且已经启动了接受
		{
			UDS.bits.UMOD = 3;	// 切换准备
		}
		else					// 否则归零,视为无效数据
		{
			Ubuff[DEFRBUFF].pbuff = Ubuff[DEFRBUFF].buffadd;
			Ubuff[DEFRBUFF].buffplen = 0;				
		}
	}
#endif
	return 0;
}
/*
	数据发送--当前默认uart3
*/
char TranUpData(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 0;                  // 发送完毕
	}
	point = UARTADDR;
	p = Ubuff[DEFTBUFF].pbuff;
	ACC = *p;
	*point = *p | ((uint8)P)<<7;
	Ubuff[DEFTBUFF].pbuff++;
	Ubuff[DEFTBUFF].buffplen--;
	UDS.bits.UMOD = 2;
	return 1;                    //还有数据发送
}
/*
	启动数据发送--当前默认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;
	p = Ubuff[DEFTBUFF].pbuff;
	ACC = *p;
	*point = *p | ((uint8)P)<<7;
	Ubuff[DEFTBUFF].pbuff++;
	Ubuff[DEFTBUFF].buffplen--;
}
/*
	出错返回复位指令
*/
void NAK_NERR(void)
{
	Ubuff[DEFTBUFF].pbuff = Ubuff[DEFTBUFF].buffadd;
	*(Ubuff[DEFTBUFF].pbuff++) = SOH;
	*(Ubuff[DEFTBUFF].pbuff++) = 'B'; 
	*(Ubuff[DEFTBUFF].pbuff++) = '0'; 
	*(Ubuff[DEFTBUFF].pbuff++) = ETX; 
	*Ubuff[DEFTBUFF].pbuff = 0x71;
	StartTranUData(5);
}
/*
	出错返回
*/
void RET_NAK(void)
{
	Ubuff[DEFTBUFF].pbuff = Ubuff[DEFTBUFF].buffadd;
	*(Ubuff[DEFTBUFF].pbuff++) = NAK;
	StartTranUData(1);
}
/*
	正确应答
*/
void RET_ACK(void)
{
	Ubuff[DEFTBUFF].pbuff = Ubuff[DEFTBUFF].buffadd;
	*(Ubuff[DEFTBUFF].pbuff++) = ACK;
	StartTranUData(1);
}
/*
	ERO返回
*/
void ERO_NERR(void)
{
	Ubuff[DEFTBUFF].pbuff = Ubuff[DEFTBUFF].buffadd;
	*(Ubuff[DEFTBUFF].pbuff++) = SOH;
	*(Ubuff[DEFTBUFF].pbuff++) = 'E'; 
	*(Ubuff[DEFTBUFF].pbuff++) = '0'; 
	*(Ubuff[DEFTBUFF].pbuff++) = ETX; 
	*Ubuff[DEFTBUFF].pbuff = 0x76;
	StartTranUData(5);
}
/*
	应用层调用接口,首先完成数据准备,然后启动发送数据
	入口参数:	value
				0----读数据返回
				1----写数据成功返回(编程允许)
				2----写数据失败返回(编程不允许)
*/
void ReturnUData(uint8 value)
{
	uint8 i,bcc;
	uint8 rlen,tlen;
	uint16 temp16;
	
	Ubuff[DEFTBUFF].pbuff = Ubuff[DEFTBUFF].buffadd;
	if(!value)			// 读数据返回
	{	// 数据格式转换
		rlen = InstPro.bufflen;					// 转换源长度
		tlen = InstList[ListLen].DLen;			// 转换目标长度
		for(i = 0; i < tlen; i+=2)
		{
			temp16 = BCD2ASC(*(Ubuff[DEFTBUFF].pbuff+2+rlen-(i/2)));
			*(Ubuff[DEFTBUFF].pbuff+2+tlen-i) = (uint8)temp16;
			*(Ubuff[DEFTBUFF].pbuff+1+tlen-i) = (uint8)(temp16>>8);
		}
		*(Ubuff[DEFTBUFF].pbuff++) = STX;
		*(Ubuff[DEFTBUFF].pbuff++) = '(';
		bcc = STX ^ '(';
		for(i = 0; i < tlen; i++)
		{
			bcc ^= *Ubuff[DEFTBUFF].pbuff;
			Ubuff[DEFTBUFF].pbuff++;
		}
		*(Ubuff[DEFTBUFF].pbuff++) = ')';
		bcc ^= ')';
		*(Ubuff[DEFTBUFF].pbuff++) = ETX;
		bcc ^= ETX;		
		*Ubuff[DEFTBUFF].pbuff = bcc;
		StartTranUData(tlen+5);
	}
	else if(value == 1)	// 写数据成功返回
	{
		RET_ACK();		
	}
	else if(value == 2)	// 写数据失败返回
	{
		NAK_NERR();		
	}
}
/*
	获取表号
	默认表号必须存放在FLASH地址中,并且在指令表(InstList)的第1个位置就要出现
*/
void GetMeterSeri(uint8 xdata *rp)
{
	uint8 code *p;
	uint8 i;
	
	p = InstList[0].DAddr;
	for(i = 0; i < InstList[0].DLen; i++)
	{
		*rp = *p & 0x7f;
		rp++;
		p++;
	}
}
/*
	获取密码,将密码依次存放到rp指针指定的地址中去
	默认密码必须存放在FLASH地址中,并且在指令表(InstList)的第2和第3个位置就要出现,分别为读密码和写密码
*/
void GetMeterCode(uint8 xdata *rp,uint8 vno)
{
	uint8 code *p;
	uint8 i;
	
	p = InstList[vno].DAddr;
	for(i = 0; i < InstList[vno].DLen; i++)
	{
		*rp = *p & 0x7f;
		rp++;
		p++;
	}	
}
/*
	状态机为0时进行表号比对
	入口参数:	vp----需要被比对的数据首地址指针
				vlen--需要被比对的数据项长度
	出口参数:	ifok
				0-----表号匹配
				1-----万能表号				
				-1----表号不匹配			
*/
char Step0Cp1107(uint8 xdata *vp,uint8 vlen)
{
	uint8 xdata *p;
	uint8 xdata *tp;
	uint8 i,ti,ifok;
//	uint8 xdata MeterSeri[13] = {'/','?',0,0,0,0,0,0,0,0,'!',CR,LF}; 
//	uint8 xdata AllSeri[5] = {'/','?','!',CR,LF};
	
	ifok = -1;			// 开始时默认表号不匹配
	p = &MeterSeri[2];
	GetMeterSeri(p);	// 获取表号
	p = vp;				
	for(i = 0; i < vlen; i++)
	{
		if(*p == '/' && *(p+1) == '?')
		{
			ifok = 0;	// 找到首地址了,默认表号匹配
			tp = p;
			ti = i;
			break;
		}
		p++;
	}
	if(ifok != 0)		// 连首地址都无法找到,说明匹配失败
		return -1;		// 返回表示表号不匹配
	for(i = 0; i < vlen-ti; i++)
	{
		if(*p != MeterSeri[i])
		{
			ifok = -1;	// 匹配表号不成功
			break;
		}
		p++;
	}
	if(ifok == 0)		// 匹配表号成功
		return 0;		// 成功返回
	p = tp;
	for(i = 0; i < vlen-ti; i++)
	{
		if(*p != AllSeri[i])
		{
			return -1;	// 返回匹配失败
		}
		p++;
	}
	return 1;			// 如果没有返回匹配失败,则返回匹配成功,为万能表号
}
/*

*/
void Step0ACK1107(void)
{
	Ubuff[DEFTBUFF].pbuff = Ubuff[DEFTBUFF].buffadd;
	*(Ubuff[DEFTBUFF].pbuff++) = '/';
	*(Ubuff[DEFTBUFF].pbuff++) = 'H';
	*(Ubuff[DEFTBUFF].pbuff++) = 'L';
	*(Ubuff[DEFTBUFF].pbuff++) = 'Y';
	*(Ubuff[DEFTBUFF].pbuff++) = ' ';
	*(Ubuff[DEFTBUFF].pbuff++) = UDS.bits.RBPS + 0x30;	// 发送推荐使用的波特率
	*(Ubuff[DEFTBUFF].pbuff++) = ' ';
	*(Ubuff[DEFTBUFF].pbuff++) = 'L';
	*(Ubuff[DEFTBUFF].pbuff++) = 'I';
	*(Ubuff[DEFTBUFF].pbuff++) = 'M';
	*(Ubuff[DEFTBUFF].pbuff++) = 'E';
	*(Ubuff[DEFTBUFF].pbuff++) = 'S';
	*(Ubuff[DEFTBUFF].pbuff++) = ' ';
	*(Ubuff[DEFTBUFF].pbuff++) = 'V';	
	*(Ubuff[DEFTBUFF].pbuff++) = ' ';
	*(Ubuff[DEFTBUFF].pbuff++) = '1';
	*(Ubuff[DEFTBUFF].pbuff++) = '.';
	*(Ubuff[DEFTBUFF].pbuff++) = '0';
	*(Ubuff[DEFTBUFF].pbuff++) = CR;
	*Ubuff[DEFTBUFF].pbuff = LF;
//	UDS.bits.RBPS = 4;		// 修改推荐使用的波特率
	StartTranUData(20);
	
	UMS.bits.PS = 1;		// 转入下一个状态机	

⌨️ 快捷键说明

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