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

📄 comm.c

📁 基于mega48单片机编码cmx865芯片驱动程序实现FSK通信模块。
💻 C
字号:
#include "Comm.h"

/***********************************************************************
*
*		函数名:RxdHost()
*		说  明:接收主机的应答,然后对应答信息进行分析
*		入口值:无
*		返回值:=0xff, 通信超时,断开所有通道
*               2:从从机转发数据或者表示收到初始化命令
*               1:执行了正确的命令
*               0:没有收到有效的命令
*		日  期:2006-09-29 
*
***********************************************************************/
unsigned char RxdHost(void)
{
	unsigned char bTemp;
	bTemp=AnalyseRxHost();				// 1:收到有效数据;0没有 //
	if(bTemp==1)						// 收到有效数据 //
	{
		bTemp=PerformCmd();			// 0:三次重发超时;1、通讯超时;2、初始化应答 //
		if(bTemp==0)					// 三次重发超时即退出 //
		{
			return 0xff;
		}
		else
		{
			return bTemp;				/*应答正确返回上一级*/
		}
	}
	return 0;
}


/***********************************************************************
*
*		函数名:byte AnalyseRxHost(void)
*		说  明:分析从主机串口收到的数据,分析数据是否为有效数据,然后将有
*               效的命令数据交下层处理。
*		入口值:无
*		返回值:1 收到主机的有效数据包
*               	0 没有有效数据包
*		日  期:2006-09-29 
*
***********************************************************************/
unsigned char AnalyseRxHost(void)
{
	unsigned char i;
	unsigned char aTemp[30];
	unsigned char bTemp;
	unsigned char bOffSet=0;
	unsigned char bLength=0;
	if(iHostRxRd>=iHostRxWr)			// 若没有收到有效的数据就返回0 //
		return 0;

	mem_set(aTemp,0,30);
	for (i=0; i<30; i++)
	{
		bTemp=aHostRxBuf[iHostRxRd];
		if(bTemp=='N')					//0x4e、在接收缓冲区中搜寻开头字符N //
			break;
		iHostRxRd++;
		if(iHostRxRd>=iHostRxWr)
			return 0;
	}
	if(i==30)
	{
		return 0;
	}

	// 取出所有已经接收到的数据串,进行分析,以便送应用层或进行转发 //
	bOffSet=(unsigned char)(iHostRxWr-iHostRxRd);

	// 数据最小长度不符,退出 //
	if(bOffSet<3)
		return 0;
	// 收到的数据存储到aTemp中 //
	mem_cpy(aTemp,&aHostRxBuf[iHostRxRd],bOffSet);

	while(1)
	{
		if((aTemp[1]==P_CONNECTICS)||(aTemp[1]==P_DTMFNUM)||(aTemp[1]==P_TXDFSK))	// S->T的变长命令仅此三条,ccw //
			bTemp=aTemp[2]+2;					// 数据长度+校验位+数据长度位 //
		else
			bTemp=SearchCmd(aTemp[1]);		// 分析命令长度 //

		if(bTemp==0)							// 命令非法 //
		{					
			bLength=2;
			break;
		}
		bLength=bTemp+2;						// 该命令的总长度,加命令和命令校验两位 //

		if(bOffSet>=bLength)
		{
			bTemp=CalcCheckSum(aTemp+1,bLength-2);			// 命令中除去0x4e、最后的校验和 //
			//if(bTemp==aTemp[bLength-1]) 					// 命令正确,进行处理 //
			{
				iHostRxRd+=bLength;							// 对齐指针收发 //
				bCmdAns.bLineCmd=aTemp[1];
				bCmdAns.bLength=bLength-3;					// 数据体的长度 除掉0x4e,命令,命令校验和 //
				mem_cpy(bCmdAns.aBuf,&aTemp[2],bCmdAns.bLength);
				return 1;
			}
			/*else
			{
			
				bLength=1;
				break;
			}*/
		}
		bLength=0;
		break;
	}
	iHostRxRd+=bLength;					// 对齐指针收发 //
	return 0;
}

/***********************************************************************
*
*		函数名:PerformCmd(void)
*		说  明:对接收到的命令进行处理,执行命令或对于应答的命令进行处理
*		入口值:无
*		返回值:无
*		日  期:2006-09-29 
*
***********************************************************************/

unsigned char PerformCmd(void)
{
	unsigned char i=0;
	LINE_DATA *p;
	p=&aLineData;
	switch(bCmdAns.bLineCmd)
	{
		case P_OK:						//0x52    肯定应答
			// 若收到的确认命令是期望的,就结束本次通信 //		
			if ((p->bExpAns==bCmdAns.bLineCmd)&&(p->bLastCmd==bCmdAns.aBuf[0]))
			{
			   	//p->fTxEn=1;				// 打开发送使能 收到期望的命令,允许发送//
			   	//p->fTimeOut=0;
				p->bLastCmd=P_OVER;
			}
			// 否则继续接收该期望的命令应答 //
			break;

		case P_NAK:						//0x53  否定应答
	
			break;

		case P_INITANS:	 
			//0x51初始化应答
			if (p->bExpAns==bCmdAns.bLineCmd)
			{
				//cbTimeOut=bCmdAns.aBuf[0];						// 通信超时 //
				//if(cbTimeOut==0)
				//	cbTimeOut=10;
				cbKeepTime=bCmdAns.aBuf[1];					// 链路保持时间 //

				//cbDTMFTime=bCmdAns.aBuf[2];					// DTMF拨号时长 //
			//	if ((cbDTMFTime<3)||(cbDTMFTime>25))
			//		cbDTMFTime=10;

				cbDialDelay=bCmdAns.aBuf[3];				        // 摘机延时发平台接入码时间 //

				return 2;
			}
			break;

		case P_CONNECTICS:								//0x60		// 接入平台 S->T,变长  //
			p->bDailWord=0x10;								// 设置代拨状态字为开始状态
			p->bLineCmd=bCmdAns.bLineCmd;
			RespondHost(P_OK,bCmdAns.bLineCmd);
			break;

		case P_DTMFNUM:							// 0x61	DTMF号码 S->T,变长  //
			p->bDailWord=0x11;						// 设置代拨状态字为开始状态 //
			p->bLineCmd=bCmdAns.bLineCmd;
			RespondHost(P_OK,bCmdAns.bLineCmd);
			break;

		case P_TXDFSK:										// FSK发送 S->T,变长 //
			p->bLineCmd=bCmdAns.bLineCmd;
			RespondHost(P_OK,bCmdAns.bLineCmd);
			Delay1MS(5);
			/*FSK发送*/
			ModemTxFSK();
			RxFskInit();                                     // 发送完成后准备再次接收数据 //
			ModemRxFSK();				//中断函数内接收

			break;

		case P_ONHOOK:										//0x64    挂机 //
			p->bLineCmd=bCmdAns.bLineCmd;
			RespondHost(P_OK,bCmdAns.bLineCmd);
			break;

		default:
			return 3;
	}
	return 1;
}

/***********************************************************************
*
*		函数名:SearchCmd
*		说  明:查找命令是否有效及其长度
*		入口值:要查找的命令
*		返回值:该命令数据的长度,=0表示该命令无效
*		日  期:
*
***********************************************************************/
unsigned char SearchCmd(unsigned char bCmd)
{
	unsigned char  i=0;
	unsigned char  bTemp;
	unsigned char aCmdTab[][2]={
			   0x50,17,
                         0x51,17,
                         0x52,2,
                         0x53,2,
                         0x54,2,
                         0x55,1,
                         0x56,1,
                         0x57,1,
                         0x58,1,
                         0x64,1,
                         0xff,0
                        };
	while(1)
	{
		bTemp=aCmdTab[i][0];
		if(bTemp==bCmd)
			return aCmdTab[i][1];
		else if(bTemp>0xa0)
			return 0;
		i++;
	}
}

/***********************************************************************
*
*		函数名:RespondHost
*		说  明:应答主机发送的命令
*		入口值:主机发送命令、应答
*		返回值:无
*		日  期:2006.10.11
*
***********************************************************************/
void RespondHost(unsigned char bCmd,unsigned char bAnsCmd)
{
	unsigned char aBuf[4];
	aBuf[0]='N';
	aBuf[1]=bCmd;
	aBuf[2]=bAnsCmd;
	aBuf[3]=CalcCheckSum(aBuf+1,2);
	mem_cpy(aHostTxBuf,aBuf,4);
	TX_addss=0;
	cTX_num=4;
	UCSR0B |= 0x28;// 发送数据 //				// 首先发送对接收命令的应答 //
	iHostRxWr=0;
	iHostRxRd=0;
}

/***********************************************************************
*
*		函数名:SendHostCmd
*		说  明:向售卡机发送命令函数
*		入口值: 发送命令
*		返回值:无
*		日  期:2006.10.11
*
***********************************************************************/
void SendHostCmd(unsigned char bCmd)
{
	unsigned char aBuf[4];
	LINE_DATA *p;
	p=&aLineData;
	
	aBuf[0]='N';
	aBuf[1]=bCmd;
	aBuf[2]=CalcCheckSum(aBuf+1,2);
	mem_cpy(aHostTxBuf,aBuf,3);
	TX_addss=0;
	cTX_num=3;
	UCSR0B |= 0x28;
	p->bExpAns=P_OK;
	p->bLastCmd=bCmd;
	iHostRxWr=0;
	iHostRxRd=0;
	/*需增加超时重传处理*/	
}

/***********************************************************************
*
*		函数名:FskSendCmd
*		说  明:向售卡机发送平台下发FSK数据
*		入口值: 发送命令
*		返回值:无
*		日  期:2006.10.11
*
***********************************************************************/
void FskSendCmd(unsigned char bCmd)
{
	unsigned char bLength;
	aHostTxBuf[0]='N';
	aHostTxBuf[1]=bCmd;
	bLength = aHostTxBuf[4]+3;
	aHostTxBuf[2]=bLength;
	aHostTxBuf[3+bLength]=CalcCheckSum(aHostTxBuf+1,bLength+1);
	TX_addss=0;
	cTX_num=bLength+4;
	UCSR0B |= 0x28;	
	iHostRxWr=0;
	iHostRxRd=0;
	/*需增加超时重传处理*/		
}

⌨️ 快捷键说明

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