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

📄 can.c

📁 Arm7
💻 C
📖 第 1 页 / 共 3 页
字号:
#include "..\CAN\can.h"

/* 全局接收缓冲数据区,除开揭示信息,依下面的数据信息说明可知:
一共有8×18=144帧,每帧12个字节,故缓冲区大小为144×12字节 */
static stcCANRxData Global_CAN_RxDBuf[144];	

/* 18个接收缓冲区,对应18种数据 */
static CAN_RxBuf Drv_CAN_RxBuf[18];

/* 各缓冲区帧数,每种数据皆为8帧 */
static uint32 Drv_CAN_RxDBufSize[18] = {8, 8, 8, 8, 8, 8, 8, 8, 8,
                                              8, 8, 8, 8, 8, 8, 8, 8, 8};

/* 数据信息说明:
测速测距单元1         8帧×12字节  CAN优先级0x04		0
测速测距单元2         8帧×12字节  CAN优先级0x05		1
机车信号1             8帧×12字节  CAN优先级0x08		2
机车信号2             8帧×12字节  CAN优先级0x09		3
1端显示器按键         8帧×12字节  CAN优先级0x48		4
2端显示器按键         8帧×12字节  CAN优先级0x49		5
显示器设定1           8帧×12字节  CAN优先级0x4C/0x4D	6
显示器设定2           8帧×12字节  CAN优先级0x50/0x51	7
显示器设定3           8帧×12字节  CAN优先级0x54/0x55	8
1端显示器自检         8帧×12字节  CAN优先级0xC8		9
2端显示器自检         8帧×12字节  CAN优先级0xC9		10
显示器转储请求        8帧×12字节  CAN优先级0xCC/0xCD	11
记录单元自检          8帧×12字节  CAN优先级0xE0		12
记录单元发送文件目录  8帧×12字节  CAN优先级0xE1		13
记录单元发送文件数据  8帧×12字节  CAN优先级0xE2		14
通信板发送信息        8帧×12字节  保留					15
CAN3                  8帧×12字节  保留					16
CAN4                  8帧×12字节  保留					17
*/

static stcCANTxData Global_CAN_TxDBuf[80];	      /* 4个通用发送缓冲数据区 */
static CAN_TxBuf Drv_CAN_TxBuf[4];	                  /* 4个通用发送缓冲区 */
static uint32 Drv_CAN_TxDBufSize[4] = {32, 32, 8, 8}; /* 各缓冲数据区帧数 */

eSend_CMD SendCMD[CAN_MAX_NUM];	/* 定义发送命令(CAN_MAX_NUM = 4)*/


/************************************************************************************ 
  功能:创建验收滤波LUT表格
  参数:nCell[5] -- 指定每个表格Cell的个数,每个Cell为32bits;
  返回值:enum LUT_BUILD_ERR -- LUT状态枚举 
*************************************************************************************/ 
uint32 CAN_AFBuildLUT(uint32 nCell[5])
{
	uint32 i;
	uint32 * pU32;
	uint32 tmpREGSFF_sa, tmpREGSFF_GRP_sa, tmpREGEFF_sa;
	uint32 tmpREGEFF_GRP_sa, tmpREGENDofTable;
	
	/* 接收过滤用RAM区大小为2048(0x800)个字节 */
	if (4 * (nCell[0] + nCell[1] + nCell[2] + nCell[3] + nCell[4]) > 0x800)
	{
		return TOTAL_SIZE_TOO_LARGE;
	}

	/* 扩展标志符范围表格必须以偶数个cell出现 */
	if ((nCell[4] & 0x01) != 0)	/* 或用条件(nCell[4] % 2) != 0 */
	{
		return EFF_GRP_SIZE_INVALID;
	}

	tmpREGSFF_sa 		= (nCell[0] << 2);
	tmpREGSFF_GRP_sa 	= tmpREGSFF_sa + (nCell[1] << 2);
	tmpREGEFF_sa		= tmpREGSFF_GRP_sa + (nCell[2] << 2);
	tmpREGEFF_GRP_sa	= tmpREGEFF_sa + (nCell[3] << 2);
	tmpREGENDofTable	= tmpREGEFF_GRP_sa + (nCell[4] << 2);

	/* FullCAN模式下必须满足:EndOfTable <= 0x800 - 6 * SFF_sa(解释详见《LPC2000系列32位ARM微控制器的CAN接收过滤设置》P8)*/
	if ((0x800 - tmpREGSFF_sa * 6) < tmpREGENDofTable)
	{
		return FCAN_STORE_SIZE_INVALID;
	}

	regCANAFMR = 0x02; /* 要修改接收过滤相关的寄存器和LUT内容时,必须先将AFMR中的AccBP置位 */

	pU32 = (uint32 *)(CANAFRAM_GADR); /* 指向接收过滤用RAM(AF RAM)的首地址 */	
	
	/* 禁能所有的AF cell,即往cell中写入-1(0xFFFFFFFF) */
	for (i = 0; i < (tmpREGENDofTable >> 2); i++)
	{							   	
		*(pU32 + i) = 0xFFFFFFFF;
	}
	
	/* 清空FullCAN自动接收存储区 */
	for (i = (tmpREGENDofTable >> 2); i < 0x200; i++) 
	{
		*(pU32 + i) = 0;
	}

	/* 初始化各接收过滤寄存器 */
	regCANSFF_sa 		= tmpREGSFF_sa;
	regCANSFF_GRP_sa	= tmpREGSFF_GRP_sa;
	regCANEFF_sa		= tmpREGEFF_sa;
	regCANEFF_GRP_sa	= tmpREGEFF_GRP_sa;
	regCANENDofTable	= tmpREGENDofTable;

	return LUT_SETTING_OK;
}


/************************************************************************************ 
  功能:初始化FullCAN表格
  参数:pTab  -- 指向待设定FullCAN表格的数组;
        nCell -- 待设定cell数目
  返回值:enum LUT_BUILD_ERR -- LUT状态枚举 
*************************************************************************************/
uint32 CAN_AFInitFCANTab(_AF_SFF_CELL * pTab, uint32 nCell)
{
	uint32 i;

	_AF_SFF_CELL *pU32 = (_AF_SFF_CELL *)(CANAFRAM_GADR); /* FullCAN表格首地址 */

	/*将cell写入-1(即0xFFFFFFFF),也可以用 _AF_SFF_CELL mask = {-1, -1, -1, -1, -1, -1, -1, -1};替代该语句*/
	_AF_SFF_CELL mask  = {0x7FF, 1, 1, 0x07, 0x7FF, 1, 1, 0x07};
	
	/* 判断FullCAN表格是否超出范围 */
	if (nCell > (regCANSFF_sa >> 2))
	{
		return TABLE_CELL_TOO_LARGE;
	}

	/* 判断cell的内容是否有效 */
	for (i = 0; i < nCell; i++)
	{
		/* 每个cell的控制器编号必须相同,高位标志符小于低位标志符 */
		if ((pTab[i].LoCh != pTab[i].UpCh) || (pTab[i].LoId >= pTab[i].UpId))
		{
				return CELL_CONTENT_INVALID;
		}
	}
	
	regCANAFMR = 0x02; /* 要修改接收过滤相关的寄存器和LUT内容时,必须将AFMR中的AccBP置位 */
	
	/* 格式化FullCAN表格,即cell全部置位 */
	for (i = 0; i < (regCANSFF_sa >> 2); i++)
	{
		*(pU32 + i) = mask;
	}

	/* 创建FullCAN cell */
	for (i = 0; i < nCell; i++)
	{
		*(pU32 + i) = *(pTab + i);
	}
	
	regCANAFMR = 0x00; /* 通知FullCAN表格已初始化,恢复正常模式 */
	return LUT_SETTING_OK;
}


/************************************************************************************ 
  功能:初始化独立标准帧标识符表格
  参数:pTab  -- 指向待设定独立标准帧标识符表格的数组;
        nCell -- 待设定cell数目
  返回值:enum LUT_BUILD_ERR -- LUT状态枚举 
*************************************************************************************/
uint32 CAN_AFInitSFFIndvTab(_AF_SFF_CELL * pTab, uint32 nCell)
{
	uint32 i;

	_AF_SFF_CELL *pU32 = (_AF_SFF_CELL *)((CANAFRAM_GADR) + (regCANSFF_sa)); /* 独立标准标识符表格首地址 */
	
	/* 或用语句_AF_SFF_CELL mask  = {-1, -1, -1, -1, -1, -1, -1, -1};替代 */
	_AF_SFF_CELL mask  = {0x7FF, 1, 1, 0x07, 0x7FF, 1, 1, 0x07};		 
	
	/* 判断独立标准标识符表格是否超出范围 */
	if (nCell > ((regCANSFF_GRP_sa - regCANSFF_sa) >> 2))
	{
		return TABLE_CELL_TOO_LARGE;
	}

	/* 判断cell的内容是否有效 */
	for (i = 0; i < nCell; i++)
	{
		/* 每个cell的控制器编号必须相同,高位标志符小于低位标志符 */
		if ((pTab[i].LoCh != pTab[i].UpCh) || (pTab[i].LoId >= pTab[i].UpId))
		{
				return CELL_CONTENT_INVALID;
		}
	}
	
	regCANAFMR = 0x02; /* 将AFMR中的AccBP置位,允许修改LUT内容和CAN接收过滤相关的寄存器 */

	/* 格式化独立标准标志符表格,即将cell全部置位 */
	for (i = 0; i < ((regCANSFF_GRP_sa - regCANSFF_sa) >> 2); i++)
	{
		*(pU32 + i) = mask;
	}

	/* 创建独立标准标志符表格 */
	for (i = 0; i < nCell; i++)
	{
		*(pU32 + i) = *(pTab + i);
	}
	
	regCANAFMR = 0x00; /* 通知独立标准标志符表格已初始化,恢复正常模式 */
	return LUT_SETTING_OK;
	
}

/************************************************************************************ 
  功能:初始化标准帧标识符范围表格
  参数:pTab  -- 指向待设定标准帧标识符范围表格的数组;
        nCell -- 待设定cell数目
  返回值:enum LUT_BUILD_ERR -- LUT状态枚举 
*************************************************************************************/
uint32 CAN_AFInitSFFGrpTab(_AF_SFF_CELL * pTab, uint32 nCell)
{
	uint32 i;

	_AF_SFF_CELL *pU32 = (_AF_SFF_CELL *)((CANAFRAM_GADR) + (regCANSFF_GRP_sa)); /* 标准帧标识范围表格首地址 */
	
	/* 或用语句_AF_SFF_CELL mask  = {-1, -1, -1, -1, -1, -1, -1, -1}; */
	_AF_SFF_CELL mask  = {0x7FF, 1, 1, 0x07, 0x7FF, 1, 1, 0x07};

	/* 判断标准帧标识范围表格是否太大 */
	if (nCell > ((regCANEFF_sa - regCANSFF_GRP_sa) >> 2))
	{
		return TABLE_CELL_TOO_LARGE;
	}

	regCANAFMR = 0x02; /* 允许修改LUT内容 */

	/* 格式化标准帧标识范围表格 */
	for (i = 0; i < ((regCANEFF_sa - regCANSFF_GRP_sa) >> 2); i++)
	{
		*(pU32 + i) = mask;
	}

	/* 创建标准帧标识范围表格 */
	for (i = 0; i < nCell; i++)
	{
		*(pU32 + i) = *(pTab + i);
	}
		
	regCANAFMR = 0x00; /* 通知标准帧标识范围表格已初始化,恢复正常模式 */
	return LUT_SETTING_OK;
}


/************************************************************************************ 
  功能:初始化独立扩展帧标识符表格
  参数:pTab  -- 指向待设定独立扩展帧标识符表格的数组;
        nCell -- 待设定cell数目
  返回值:enum LUT_BUILD_ERR -- LUT状态枚举 
*************************************************************************************/
uint32 CAN_AFInitEFFIndvTab(_AF_EFF_CELL * pTab, uint32 nCell)
{
	uint32 i;
	
	/* 扩展帧标识符表格首地址 */
	_AF_EFF_CELL *pU32 = (_AF_EFF_CELL *)((CANAFRAM_GADR) + (regCANEFF_sa));
	
	/* 或用_AF_EFF_CELL mask  = {-1, -1}; */
	_AF_EFF_CELL mask  = {0x1FFFFFFF, 0x07};

	/* 判断独立扩展帧标识符表格是否超出范围 */
	if (nCell > ((regCANEFF_GRP_sa - regCANEFF_sa) >> 2))
	{
		return TABLE_CELL_TOO_LARGE;
	}

	regCANAFMR = 0x02; /* 允许修改LUT内容 */

	/* 格式化独立扩展帧标识符表格 */
	for (i = 0; i < ((regCANEFF_GRP_sa - regCANEFF_sa)>> 2); i++)
	{
		*(pU32 + i) = mask;
	}

	/* 创建独立扩展帧标识符表格 */
	for (i = 0; i < nCell; i++)
	{
		*(pU32 + i) = *(pTab + i);
	}
	
	regCANAFMR = 0x00; /* 通知独立扩展帧标识符表格已初始化,恢复正常模式 */
	return LUT_SETTING_OK;
}


/************************************************************************************ 
  功能:初始化扩展帧标识范围表格
  参数:pTab  -- 指向待设定扩展帧标识范围表格的数组;
        nCell -- 待设定cell数目
  返回值:enum LUT_BUILD_ERR -- LUT状态枚举 
*************************************************************************************/
uint32 CAN_AFInitEFFGrpTab(_AF_EFF_CELL * pTab, uint32 nCell)
{
	uint32 i;
    
	/* 扩展帧标识范围表格首地址 */
	_AF_EFF_CELL *pU32 = (_AF_EFF_CELL *)((CANAFRAM_GADR) + (regCANEFF_GRP_sa));
	
	/* 或用_AF_EFF_CELL mask  = {-1, -1}; */
	_AF_EFF_CELL mask  = {0x1FFFFFFF, 0x07}; 
	
	/* 扩展标志符范围表格必须以偶数个cell出现 
	   判断条件也可改为"(nCell[4] & 0x01) != 0" */
	if ((nCell % 2) != 0)
	{
		return CELL_NUM_INVALID;
	}

	/* 判断扩展标志符范围表格cell数是否越限 */
	if (nCell > ((regCANENDofTable - regCANEFF_GRP_sa) >> 2))
	{
		return TABLE_CELL_TOO_LARGE;
	}

	regCANAFMR = 0x02; /* 允许修改LUT内容 */

	/* 格式化扩展标志符范围表格 */
	for (i = 0; i < ((regCANENDofTable - regCANEFF_GRP_sa)>> 2); i++)
	{
		*(pU32 + i) = mask;
	}
	
	/* 创建独立扩展帧标识符范围表格 */	
	for (i = 0; i < nCell; i++)
	{
		*(pU32 + i) = *(pTab + i);
	}
		
	regCANAFMR = 0x00; /* 通知独立扩展帧标识符范围表格已初始化,恢复正常模式 */
	return LUT_SETTING_OK;
}


/************************************************************************************ 
  功能:指定接收过滤器的工作模式,启动或关闭全局滤波器
  参数:mode -- 接收过滤寄存器AFMR的各种模式枚举(AF_NORMAL、AF_IGNORE、AF_BYPASS、
	    AF_FULLCAN) 
  返回值:无
*************************************************************************************/
void CAN_AFSetMode(eAF_MODE mode)
{
	regCANAFMR = 0x02; /* 允许修改接收过滤寄存器AFMR */ 

	switch(mode)
	{
		case AF_NORMAL:
			regCANAFMR = 0x00; /* 正常模式,执行全局过滤操作 */
			break;
		case AF_IGNORE:
			regCANAFMR = 0x01; /* 忽略模式,接收器忽略总线上出现的数据 */
			break;
		case AF_BYPASS:
			regCANAFMR = 0x02; /* 旁路模式,允许所有接收通过,以及用于修改与CAN接收过滤相关的寄存器和LUT内容 */
			break;
		case AF_FULLCAN:
			regCANAFMR = 0x04; /* FullCAN模式,允许在全局接收过滤的基础上添加自动接收和存储功能 */
			break;
		default:
			regCANAFMR = 0x00; /* 默认为正常模式 */
			break;
	}
}


/************************************************************************************ 
  功能:获取接收过滤表格的结束偏移地址
  参数:无 
  返回值:表格结束偏移地址,即ENDofTable寄存器中的值 
*************************************************************************************/
uint32 CAN_AFGetEndOfTabOffset(void)
{
	return regCANENDofTable;
}


/****************************************************************************************
  功能:初始化接收和发送数据缓冲区:缓冲区帧数大小、有效帧数为0、缓冲区指针、
        发送缓冲区下一读出位置为0
  参数:无 
  返回值:无 
*****************************************************************************************/
void CAN_InitBuf(void)
{
	uint32 i;
	uint8 * pTT;
	
	/* 接收缓冲区设置 */
	Drv_CAN_RxBuf[0].RxDBufSize = Drv_CAN_RxDBufSize[0]; /* 缓冲区帧数大小 */

⌨️ 快捷键说明

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