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

📄 com_232.c

📁 232串口通讯的驱动
💻 C
📖 第 1 页 / 共 4 页
字号:
/////////////////////////////////////////////////////////////////////////////
//
//  文件名:							版本
//                                                            
//  com_232.c						0.03
//        
//  概述:
//		b5300系列装置通信任务处理程序
//
////////////////////////////////////////////////////////////////////////////

#include "typedef.h"
#include "hardef.h"
#include "sci_drv.h"
#include "flash_mng.h"
#include "set.h"
#include "set_drv.h"
#include "report.h"
#include "calcasm.h"
#include "func.h"
#include "mea.h"
#include "samcall.h"
#include "factor.h"
#include "bios.h"
#include "gl_convert.h"
#include "mmi_drv.h"
#include "com_232.h"
#include "main.h"
#include "initfunc.h"


//保护名称(ps64x.c中定义)
extern const char szRelayName[];

//应答命令表
const TCOMMANDTABLE tCmdTable[]=
{
	{0x81,ReplyCmd81},
	{0x82,ReplyCmd82},
	{0x83,ReplyCmd83},
	{0x84,ReplyCmd84},
	{0x85,ReplyCmd85},
	{0x86,ReplyCmd86},
	{0x89,ReplyCmd89},
	{0x8A,ReplyCmd8A},
	{0x8B,ReplyCmd8B},
	{0x8C,ReplyCmd8C},
	{0x8E,ReplyCmd8E},
	{0x8F,ReplyCmd8F},
	{0x90,ReplyCmd90},
	{0x91,ReplyCmd91},
	{0x92,ReplyCmd92},
	{0x93,ReplyCmd93},
	{0x94,ReplyCmd94},
	{0x95,ReplyCmd95},
	{0x96,ReplyCmd96},
	{0x98,ReplyCmd98},
	{0x99,ReplyCmd99},
	{0x9A,ReplyCmd9A},
	{0x9B,ReplyCmd9B},
	{0x9C,ReplyCmd9C},
	{0x9E,ReplyCmd9E},
	{0x9F,ReplyCmd9F},
	{0xA0,ReplyCmdA0},
	{0xA1,ReplyCmdA1},
	{0xA2,ReplyCmdA2},
	{0xA3,ReplyCmdA3},
	{0xA4,ReplyCmdA4},
	{0xA5,ReplyCmdA5},
	{0xA6,ReplyCmdA6},
	{0xAA,ReplyCmdAA},
	{0xAB,ReplyCmdAB},
	{0xAE,ReplyCmdAE},
	{0xAF,ReplyCmdAF},
	{0xB0,ReplyCmdB0},
	{0xB5,ReplyCmdB5},
	{0xB6,ReplyCmdB6},
	{0xB7,ReplyCmdB7},
};
const int cstCmdNum=sizeof(tCmdTable)/sizeof(tCmdTable[0]);

//报文的目的地址=命令报文的原地址
//事件报文(17,18)目地址始终=DESTADDR
BYTE byDst=0;

//事件报文的目地址
const BYTE DESTADDR=0;

//应答报文缓冲区
BYTE caAckBuf[260];

//临时存放定值或遥控命令缓存(参见 Ack94,Ack95或98,99报文)
BYTE  caTmpBuf[260];

//临时存放逻辑定值的接收缓冲
BYTE caTmpLogBuf[0x8000];

static FM_LOGIC_HEADER m_logic_head;

//逻辑定值接收缓冲指针
static BYTE *pTmpLogBuf;

//内存操作参数
TMEMRDWR tMemRdWr;

//95,99,9B命令执行状态
TCOMMAND tCmd=
{
	0, //byCmd:命令
	0, //byStatus:执行状态
	0  //wDelay:定时计数器,>5"清除byCmd
};

static WORD m_232EventPos=0;
static WORD m_232AlarmPos=0;
static WORD m_232DiPos=0;
static WORD m_232SoePos=0;

static WORD m_232EventCopyPos=0;

// Sci通信任务
//	1)插入通信缓冲队列结构检查程序代码;
//	2)插入主动上送报告发送程序代码:上送报告缓冲区-->sci_out_buf队列;
//		  关于上送报告用法的几点说明:
//		  a)各任务中需主动发送的信息,若实时性要求不高,则报送信息先添入
//		      各自的信息缓冲区,在主程序调用SCI通信任务函数时由该函数自行调入
//		      SCI发送缓冲进行发送。本段程序即为此种方式而设置;
//		  b)若任务中主动发送的信息实时性要求较高,则可采用发送信息直接送入
//		      发送缓冲的方式;
//	3)插入发送中断开放检查及启动发送中断程序代码;
// 在主程序中,调用此函数即完成与SCI串行通信有关的任务
static BYTE szRxBuf[272];  //接收缓冲区
void SciCommTask()
{
	int len;

    CommTask(0,0,0);

	SendPolling();     //主动上送事件报告

    SendTaskBuffer();  //发送多帧任务缓冲区报文

	len=(int)SCI_Receive(szRxBuf);
	if(len >= 7)       // 报文长度最少5字节,加2字节dTCounter低16位
	{		
		SciAck(szRxBuf,len);
	}
	return;
}

//========================================================
//	与通信任务有关的操作函数
//========================================================
//通信应答
//s      =报文开始地址
//iLength=报文长度
void SciAck(BYTE *sBuf,int iRecLen)
{
	BYTE *pt;
	WORD wCount0;
	
	//计算接收时的dTCounter的低16位
	pt=sBuf+iRecLen-2;		
	wCount0=((WORD)(*pt++))<<8;
	wCount0+=*pt;				
	pt=sBuf;                   

	//如果报文目的地址=本CPU的地址或者=0xFF(广播报文),则处理此报文
	if((*pt==byCpuN) || (*pt==0xff))
	{
		//byDst:应答报文的目的地址
		pt++;
		byDst=*pt++;

		//解释执行命令应答
		CommandReply(*pt,sBuf,wCount0);
	}
}

//解释--执行命令表中的命令
void CommandReply(BYTE byCmd,BYTE *sBuf,WORD wFcount)
{
	int i;
	for(i=0; i < cstCmdNum; i++)
	{
		if(byCmd == tCmdTable[i].byCmdId)
		{
			tCmdTable[i].func(sBuf,wFcount);
			return;
		}
	}
	//命令表中不存在的命令视为非法命令
	Send15();
}

//发送1个字节数组
//s=数组的开始地址,第一个字节=从第二字节开始有效字节数()
void SciPutn(BYTE * s)
{
	BYTE byLen;

	byLen =*s++;
	SCI_Send(s,byLen);
}


//计算字节数组的SUM8(校验和)
//SUM8的反码被添加在数组尾部
//第1个字节给出数组长度(包括被添加的SUM8的反码)。根据规约要求,数组的长度 >= 5
bool MakeCs(BYTE *str)
{
	WORD i;
	BYTE *pt,c;

	pt=str;
	i=(WORD)(*pt++);
	c=0;
	if(i < 5) return FALSE;
	for(; i > 1; i--) c +=*pt++;
	*pt =(BYTE)~c;
	return TRUE;
}

//10报文:装置上电
void Send10()
{
	BYTE *s;
	BYTE *cpAck;
	int i,l;
	//名称长度最多16字节(8个汉字)
	l =0;
	s =(BYTE *)szRelayName;
	while(*s++ && l < 16) l++;
	i =16-l;
	s =(BYTE *)szRelayName;

	cpAck =caAckBuf;
	*cpAck++ =29;
	*cpAck++ =byDst;
	*cpAck++ =byCpuN;
	*cpAck++ =0x10;
	*cpAck++ =24;
	//保护类型码
	*cpAck++=RELAY_TYPE_LO;
	*cpAck++=RELAY_TYPE_HI;
	//保护名称长度16字节,不足时补空格(0x20)
	while(l > 0)
	{
		*cpAck++=*s++;
		l--;
	}
	while(i > 0)
	{
		*cpAck++=' ';
		i--;
	}
	//软件版本号
	*cpAck++=RELAY_VER_LO;
	*cpAck++=RELAY_VER_HI;
	//插入软件校验码
	{
	extern TSOFTINFO tSoftInfo;
	WORD w =tSoftInfo.wProgCrc;
	*cpAck++=(BYTE)w;
	*cpAck++=(BYTE)(w>>8);
	}
	//插入配置信息校验码
	*cpAck++=0;
	*cpAck++=0;
	MakeCs(caAckBuf);
	SciPutn(caAckBuf);
}

//11报文:上报日历时钟
void Send11()
{
	BYTE *cpAck;
	TDATE td;
	WORD w;

	DateAsign(&td);
	cpAck=caAckBuf;
	*cpAck++=13;
	*cpAck++=byDst;
	*cpAck++=byCpuN;
	*cpAck++=0x11;
	*cpAck++=8;
	*cpAck++=(BYTE)td.wYear;
	*cpAck++=(BYTE)(td.wYear>>8);
	*cpAck++=td.byMon;
	*cpAck++=td.byDay;
	*cpAck++=td.byHour;
	*cpAck++=td.byMin;
	w=td.wMs;
	*cpAck++=(BYTE)w;     //low byte
	*cpAck++=(BYTE)(w>>8);//high byte
	MakeCs(caAckBuf);
	SciPutn(caAckBuf);
}

//12报文:准备发送配置信息
void Send12()
{
	BYTE *s;
	BYTE *cpAck;
	int i,l;
	//名称长度最多16字节(8个汉字)
	l=0;
	s=(BYTE *)szRelayName;
	while(*s++ &&  l < 16) l++;
	i =16-l;
	s =(BYTE *)szRelayName;
	
	cpAck=caAckBuf;
	*cpAck++=29;
	*cpAck++=byDst;
	*cpAck++=byCpuN;
	*cpAck++=0x12;
	*cpAck++=24;
	//保护类型码
	*cpAck++=RELAY_TYPE_LO;
	*cpAck++=RELAY_TYPE_HI;
	//保护名称长度16字节,不足时补空格(0x20)
	while(l > 0)
	{
		*cpAck++=*s++;
		l--;
	}
	while(i > 0)
	{
		*cpAck++=(BYTE)' ';
		i--;
	}
	//软件版本号
	*cpAck++=RELAY_VER_LO;
	*cpAck++=RELAY_VER_HI;
	//插入软件校验码
	{
	extern TSOFTINFO tSoftInfo;
	WORD w=tSoftInfo.wProgCrc;
	*cpAck++=(BYTE)w;
	*cpAck++=(BYTE)(w>>8);
	}
	//插入配置信息校验码
	*cpAck++=0;
	*cpAck++=0;
	MakeCs(caAckBuf);
	SciPutn(caAckBuf);
}

//否定回答
void Send15()
{
	BYTE *cpAck;
	cpAck=caAckBuf;
	*cpAck++=5;
	*cpAck++=byDst;
	*cpAck++=byCpuN;
	*cpAck++=0x15;
	*cpAck++=0;
	MakeCs(caAckBuf);
	SciPutn(caAckBuf);
}

//肯定回答
void Send16()
{
	BYTE *cpAck;
	cpAck=caAckBuf;
	*cpAck++=5;
	*cpAck++=byDst;
	*cpAck++=byCpuN;
	*cpAck++=0x16;
	*cpAck++=0;
	MakeCs(caAckBuf);
	SciPutn(caAckBuf);
}

//命令接收正确,但无所要的数据
void Send19()
{
	BYTE *cpAck;
	cpAck=caAckBuf;
	*cpAck++=5;
	*cpAck++=byDst;
	*cpAck++=byCpuN;
	*cpAck++=0x19;
	*cpAck++=0;
	MakeCs(caAckBuf);
	SciPutn(caAckBuf);
}

//发送指定定值区的整定值
//ff=当前定值区
void Send23(WORD bn)
{
	extern TSECTIONINFO tSecInfo;
	short i;
	BYTE *cpAck;

	cpAck=caAckBuf;
	*cpAck++=SET_NUMBER*3+7;
	*cpAck++=byDst;
	*cpAck++=byCpuN;
	*cpAck++=0x23;
	*cpAck++=SET_NUMBER*3+2;
	*cpAck++=RELAY_TYPE_LO;
	*cpAck++=RELAY_TYPE_HI;
	if(bn == 0xff)
	{
		if( g_tSysErr.bErr[EV_SETERR] )
		{
			Send25(RES_SET_INVALID);
			return;
		}
		bn=tSecInfo.byCurSec;
	}
	//从Flash memory中读取定值
	if( !FM_Read_Set((BYTE)bn,cpAck) )
	{
		//定值错误,返回缺省值
		TSETVAL *pSet;
		pSet=(TSETVAL *)cpAck;
		for(i =0; i < SET_NUMBER; i++)
		{
	        *pSet++=tSetTable[i].tDef;
		}
	}
	MakeCs(caAckBuf);
	SciPutn(caAckBuf);
}

//操作结果
void Send25(BYTE res)
{
	BYTE *cpAck;
	cpAck=caAckBuf;
	*cpAck++=8;
	*cpAck++=byDst,*cpAck++=byCpuN;
	*cpAck++=0x25;
	*cpAck++=3;
	*cpAck++=RELAY_TYPE_LO;
	*cpAck++=RELAY_TYPE_HI;
	*cpAck=res;
	MakeCs(caAckBuf);
	SciPutn(caAckBuf);
}

//2E:9E命令读取的内存单元的内容
//tMemRdWr
void Send2E()
{
	BYTE u;
	BYTE *cpAck,*pt;
	if(tMemRdWr.byLen > 0xf0)
	{
		Send15();
		return;
	}
	switch(tMemRdWr.byType)
	{
	case 1://RAM
		if(tMemRdWr.dAddr < RAM_BEGIN || (tMemRdWr.dAddr+tMemRdWr.byLen) > RAM_END)
		{
			Send25(RES_MEM_OVRANGE);
			return;
		}
		pt=(BYTE*)tMemRdWr.dAddr;
		cpAck=caAckBuf;
		*cpAck++=tMemRdWr.byLen+5+5;
		*cpAck++=byDst,*cpAck++=byCpuN;
		*cpAck++=0x2E;
		*cpAck++=tMemRdWr.byLen+5;
		*cpAck++=tMemRdWr.byType;
		*cpAck++=(BYTE)tMemRdWr.dAddr;
		*cpAck++=(BYTE)(tMemRdWr.dAddr >> 8);
		*cpAck++=(BYTE)(tMemRdWr.dAddr >> 16);
		*cpAck++=tMemRdWr.byLen;
		//store M bytes
		u=tMemRdWr.byLen;
		while( u-- ) *cpAck++=*pt++;
		MakeCs(caAckBuf);
		SciPutn(caAckBuf);
		return;  
  //case 2:	//EEPROM
	case 3: //FLASH MEMORY
		if(tMemRdWr.dAddr < (DWORD)FM_BEGIN || (tMemRdWr.dAddr+tMemRdWr.byLen) > FM_END)
		{
			Send25(RES_MEM_OVRANGE);
			return;
		}
		if ( !FM_LOCK_FLASH() )
		{
			Send15();		
			return;
		}
		pt =(BYTE *)tMemRdWr.dAddr;
		cpAck=caAckBuf;
		*cpAck++=tMemRdWr.byLen+5+5;
		*cpAck++=byDst,*cpAck++=byCpuN;
		*cpAck++=0x2E;
		*cpAck++=tMemRdWr.byLen+5;
		*cpAck++=tMemRdWr.byType;
		*cpAck++=(BYTE)tMemRdWr.dAddr;
		*cpAck++=(BYTE)(tMemRdWr.dAddr >> 8);
		*cpAck++=(BYTE)(tMemRdWr.dAddr >> 16);
		*cpAck++=tMemRdWr.byLen;
		//store u bytes
		u =tMemRdWr.byLen;
		while( u-- ) *cpAck++ =*pt++;
		FM_UNLOCK_FLASH();

		MakeCs(caAckBuf);
		SciPutn(caAckBuf);
		return;
	case 4:	//EPROM
		if((tMemRdWr.dAddr+tMemRdWr.byLen) > ROM_END)
		{
			Send25(RES_MEM_OVRANGE);
			return;
		}
		pt=(BYTE*)tMemRdWr.dAddr;
		cpAck=caAckBuf;
		*cpAck++=tMemRdWr.byLen+5+5;
		*cpAck++=byDst,*cpAck++=byCpuN;
		*cpAck++=0x2E;
		*cpAck++=tMemRdWr.byLen+5;
		*cpAck++=tMemRdWr.byType;
		*cpAck++=(BYTE)tMemRdWr.dAddr;
		*cpAck++=(BYTE)(tMemRdWr.dAddr >> 8);
		*cpAck++=(BYTE)(tMemRdWr.dAddr >> 16);
		*cpAck++=tMemRdWr.byLen;
		//store u bytes
		u =tMemRdWr.byLen;
		while( u-- ) *cpAck++=*pt++;
		MakeCs(caAckBuf);
		SciPutn(caAckBuf);
		return;
	default:
		Send15();
	}
}

//发送30报文
void Send30(BYTE *sBuf)
{
	BYTE *pt;
	WORD i,k;
	DWORD dw;

	long arg0,arg,lOff;

	//以Ua的相位角作参考量
	arg0=ptMea->lAng[SAM_UA];

	//校验通道号
	//ff=所有通道,否则指定一个通道
	pt =sBuf+4;
	i =(WORD)(*pt);
	if(i == 0xff)
	{
		k=AI_NUMBER;
		i=0;
	}
	else if(i > AI_NUMBER ||  i < 1)
	{
		Send25(RES_CHN_INVALID);
		return;
	}
	else
	{
		i--;
		k=1;
	}

	//发送有效值和相位角
	//i=起始通道号
	//k=通道数
	pt=caAckBuf;
	*pt++=(BYTE)(k*12+5);
	*pt++=byDst;
	*pt++=byCpuN;
	*pt++=0x30;
	*pt++=(BYTE)(k*12);
	for(; k > 0; i++,k--)
	{
		if(i<=(AI_NUMBER-1))
		{
			dw=_MulFac2(ptMea->lrms[i],0x10000L,tMeaRelayTab[i].dKBL);
			lOff=_MulFac2(ptMea->l0[i],0x10000L,tMeaRelayTab[i].dKBL);
			arg=ptMea->lAng[i]-arg0;
		}
		else
		{
			dw=0;
			lOff=0;
			arg=0;
		}
		*pt++=(BYTE)dw;
		*pt++=(BYTE)(dw>>8);
		*pt++=(BYTE)(dw>>16);
		*pt++=(BYTE)(dw>>24);
		while(arg < -(180*65536L))
		{
			arg +=(360*65536L);
		}
		while(arg > (180*65536L))
		{
			arg -=(360*65536L);
		}
		*pt++=(BYTE)arg;
		*pt++=(BYTE)(arg>>8);
		*pt++=(BYTE)(arg>>16);
		*pt++=(BYTE)(arg>>24);
		*pt++=(BYTE)lOff;
		*pt++=(BYTE)(lOff>>8);
		*pt++=(BYTE)(lOff>>16);
		*pt++=(BYTE)(lOff>>24);
	}
	MakeCs(caAckBuf);
	SciPutn(caAckBuf);
}

//81:设置日历时钟
void ReplyCmd81(BYTE *sBuf,WORD wFrameCounter)
{

⌨️ 快捷键说明

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