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

📄 recv.c

📁 freescale crc模块驱动 经调试
💻 C
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************
 * 源程序文件名: recv.c                                                       *
 * 功能: 串行通信接收模块                                                     *
 * 说明: 本文件中包含的子模块有:接收串行数据,检查数据的正确性                 *
 ******************************************************************************/

/* 加载头文件 */
# include "crc.h"
# include "recv.h"
# include "machine.h"
# include "ctrlout.h"
# include "chksafety.h"

/* 从发射机接收的数据 */
SioPackRecvBuf  SioRecvBuf;
unsigned char   cSioRecvBufEnd;
unsigned char   cRecvBufType;
unsigned int    nflgCommDatRight;
unsigned char   cflgCommDatOvertime;

/******************************************************************************
 * 函数原型: void InitDataRecv(void);                                         *
 * 功能: 数据接收模块相关变量的初始化                                         *
 * 说明: 无                                                                   *
 ******************************************************************************/
void InitDataRecv (void)
{
	cSioRecvBufEnd      = 0;
	cRecvBufType        = 0x00;
	nflgCommDatRight    = CommDatRightTime0;
	cflgCommDatOvertime = 0;
}

/******************************************************************************
 * 函数原型: void RecvMOnTimeReadRxBuf(void);                                 *
 * 功能: 将接收缓冲区中的数据转移到SioRecvBuf.buf中                           *
 * 说明: 无                                                                   *
 ******************************************************************************/
void RecvMOnTimeReadRxBuf (void)
{
	int n, m;
	if(cUART1RxEnd == cUART1RxHead)                        // 如果UART1接收缓冲区中无数据
		return;                                            // 返回
	// 留2个字节的余量
	n = CMSioRecvPackLenMax-cSioRecvBufEnd-2;              // 最多接收的字节数
	m = UART1GetRx(SioRecvBuf.buf+cSioRecvBufEnd,n);       // 接收数据,m为实际接收到的字节数
	cSioRecvBufEnd += m;                                   // 重新设置SioRecvBuf.buf的尾
}

/******************************************************************************
 * 函数原型: int RecvMOnTimeCheckLead(void);                                  *
 * 功能: 在SioRecvBuf.buf中寻找包头                                           *
 * 说明: 1.UniversalPackLead未被定义                                          *
 *       2.返回值为接收包"类型+序列"的下标                                    *
 *       3.注意:连续2个FF+1个非FF即认为收到了正确的包!!!                      *
 ******************************************************************************/
int RecvMOnTimeCheckLead (void)
{
# ifdef UniversalPackLead
	int i, j, k;
	for(k = 0; k < cSioRecvBufEnd; k++)
	{
		for(i = k; i < cSioRecvBufEnd; i++)
			if(SioRecvBuf.buf[i] == 0x00FF)
				break;
		if(i+CMSioRecvPackLenMin > cSioRecvBufEnd)
			break;
		for(j = i; j < cSioRecvBufEnd; j++)
			if(SioRecvBuf.buf[j] != 0x00FF)
				break;
		if(j-i >= CMSioLeadLenMin)
			return j;
	}
	return 0;
# else                                                     // UniversalPackLead
# define p SioRecvBuf.buf
	int k;
	for(k = 2; k < cSioRecvBufEnd; k++)
		if(p[k-2] == 0xFF && p[k-1] == 0xFF && p[k-0] != 0xFF)
			return k;
	return 0;
# undef  p
# endif                                                    // UniversalPackLead
}

/******************************************************************************
 * 函数原型: void RecvMOnTimeNormalBuf(int lead);                             *
 * 功能: 将接收到的有效包移至SioRecvBuf.buf的起始位置                         *
 * 说明: 1.注意不同情况的处理方式                                             *
 *       2.将SioRecvBuf.buf的前3个字节设置成引导字节                          *
 ******************************************************************************/
void RecvMOnTimeNormalBuf (int lead)
{
	int n, adj, len;
	n = cSioRecvBufEnd-CMSioLeadLenMax;                    // n = cSioRecvBufEnd-4
	if(n <= 0)                                             // 如果SioRecvBuf.buf中的数据不超过4字节
		return;                                            // 不处理,返回
	if(!lead)                                              // 如果没有找到"FF+FF+非FF"的包头
	{
		// __memmovebufforlittle
		__memmovebuf(SioRecvBuf.buf,n,CMSioLeadLenMax);    // 移动最末尾的4个字节到包的头部,以便不
		                                                   // 影响下一次寻找包头的操作(有效包最多有
		                                                   // 4个字节的引导字)
		cSioRecvBufEnd = CMSioLeadLenMax;                  // 设置包尾为4
		return;                                            // 处理完毕,返回
	}
	if(lead == CMSioLeadLen)                               // 如果包类型字节的下标是3
		return;                                            // 不必处理,返回
	adj = lead-CMSioLeadLen;                               // 统一将有效包调整为有3个引导字
	len = cSioRecvBufEnd-(adj>0?adj:0);                    // lead最小值为2,adj有小于0的情况
	// __memmovebufforlittle(lead>3) or __memmovebufforlarge(lead==2)
	__memmovebuf(SioRecvBuf.buf,adj,len);                  // 前3个字节均为引导字
	cSioRecvBufEnd -= adj;                                 // 重新设置包尾
}

/******************************************************************************
 * 函数原型: int CRCChk(char *cp, char nn);                                   *
 * 功能: 对接收到的数据包进行CRC校验                                          *
 * 说明: 1.cp指向需校验数据包的包头,nn为有效数据的长度(不含CRC校验码)         *
 *       2.返回值为1说明传输无差错                                            *
 ******************************************************************************/
int CRCChk (char *cp, char nn)
{
	SioPackCRC *crcp, crc;
	// crcp指向包的CRC1
	crcp = (SioPackCRC *)(cp+nn);
	// cp指向包的第1个有效字节,nn为有效字节的长度
    crc = crc1608strrevCRC16(cp, nn, NULL);
	return crc==*crcp?1:0;
}

/******************************************************************************
 * 函数原型: int MachineAddrChk(unsigned int addr, int Rc);                   *
 * 功能: 检查并设定遥控器的机器地址                                           *
 * 说明: 1.addr为要设定的地址值,Rc为设定机器地址的标志(1有效)                 *
 *       2.注意本函数在不同情况下的返回值,返回0表示地址校验失败               *
 *       3.遥控器的ID号一旦被设置,将永远不能用常规的办法更改该ID号,且不再接受 *
 *         通用机器地址                                                       *
 ******************************************************************************/
int MachineAddrChk (unsigned int addr, int Rc)
{
	nMachineAddr = (unsigned int)GetMachineAddr();         // 从单片机内获取机器的ID号
	if(nMachineAddr == addr)                               // 如果对码成功
		return 1;                                          // 返回1!
	if(nMachineAddr == NoMachineAddr && addr == UniversalMachineAddr)
		                                                   // 如果机器尚未设置ID号且接收的地址为通
														   // 用的机器地址
		return 2;                                          // 返回2!
	if(nMachineAddr == NoMachineAddr && Rc == 1)           // 如果机器尚未设置ID号且接收到的数据包
		                                                   // 通过了CRC校验
	{
		PutMachineAddr((unsigned long)addr);               // 为机器设置ID号
		return 3;                                          // 返回3!
	}
	return 0;                                              // 出现错误,返回0!
}

/******************************************************************************
 * 函数原型: void RecvMOnTimeDebug(void);                                     *
 * 功能: 收到"调试"包的处理                                                   *
 * 说明: 不做任何事情                                                         *
 ******************************************************************************/
void RecvMOnTimeDebug (void)
{
	return;
}

/******************************************************************************
 * 函数原型: int RecvMOnTimeCheckData(void);                                  *
 * 功能: 对收到的包进行整体校验                                               *
 * 说明: 1.本函数依次进行CRC校验和机器地址校验                                *
 *       2.注意本函数在不同情况下的返回值                                     *
 ******************************************************************************/
int RecvMOnTimeCheckData (void)
{
	SioPackHead   *pack;
	char          type, len;
	unsigned char *cp;
	int           Rc, Ra, i = 0;

⌨️ 快捷键说明

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