一、背景:
使用LPC1768来做CAN的收发,在此对使用LPC1769的 CAN 控制器进行收发做个总结和记录,以备下次开发快速上手使用。
附:LPC1768/1769 除了支持最高频率不同以外,其它基本上一致。
二、正文:
由上图可见,整个 CAN 控制器一头是 CPU,另一头是 CAN 收发器:
CAN 收发器负责 CAN 数据与 CAN 网络的通信。CAN 内核模块解析和封装要发送到 CAN 收发器以及从 CAN
收发器发过来的数据,此处 CAN 内核工作由硬件自行完成。
CPU通过 APB总线即可设置 CAN 控制器状态,以及读取中断信息和中断状态。
一共有 3 个发送缓冲器(邮箱),这样就可以保证,最少可以发送 3组并发的 CAN 数据;
2 个接收缓冲器(邮箱),这样就可以在 CPU 处理 1 个邮箱的接收数据的同时,
还能用另一个邮箱接收网络上的数据。
LPC17XX CAN 的验收滤波器比较特殊,
它是一个独立于 CAN 控制器的器件,也属于一种外设,不过比较特殊的是,
它是服务于 CAN 控制器的外设,这么做的意义就在于,验收滤波这方面,不再需要软件来做任何事情,直接由硬件来实现查表算法,节省宝贵的 CPU资源,由于它也算是一个
独立的外设,
CAN 验收滤波器有 2 种工作模式:一种是一般模式;另一种被称为“FullCAN 模式”。
1.在一般模式下,当 CAN 控制器的接收端收到一个完整的标识符时,它将通知接收验收滤波器。验收滤波器响应这个信号,读出 CAN 控制器编号和标识符大小(标准标识符 ll 位或扩展标识符 29位);然后搜索 LUT,查找匹配的标识符。如果找到匹配的标识符,则通知 CAN 控制器将接收的报文放入 CAN控制器接收缓冲中;否则,放弃接收到的这一帧信息。
2.如果使能 FullcAN 模式,且 CAN 控制器报告产生的是一
个标准标识符,则验收过滤器首先查询 FullCAN 标准标识符表然后在 FullCAN 模式下处理接收。如果在 FullCAN 标准标识符表中没有找到匹配的 ID,则依次查找下一个存在的表格,直到找到匹配者或查找表结束。一旦发现匹配的 ID,就将接收到的报文放入特定的报文缓冲中而不是 CAN 控制器接收缓冲中,这个特定的缓冲位于验收滤波器的 RAM 中,而且是在 LUT的最后部分。CPU可以在任何时候读取接收到的报文。
以上读起来有点累:
我的理解独立的外设 CAN,
1.本质是多个硬件比较器,接受 ID 与内部设定 ID自动比较,不通过 CPU,直接由硬件来实现查表算法,节省宝贵的CPU 资源。这是 NXP-CAN独特优点, 实时工控系统需要由多个功能 CAN,RS485,I2C,用户逻辑编程等。NXP-CAN 适合设计实时控制系统。
2.编程
只是设定接收滤波器工作模式,与收滤波器起始地址。
3.其它设定网上资料很多。
/*-------------------------------------------------------------------
* 函数名称: CAN_SetACCF()
* 参 数: 波特率
* 返 回: XX
* 函数功能: 接收滤波器状态
* 版本信息: 2010-04-30 * 修改信息:
-*-------------------------------------------------------------------
void CAN_SetACCF(const unsigned int ACCFMode)
{
switch (ACCFMode)
{
case ACCF_OFF: // 接收滤波器状态-复位/停止
LPC_CANAF->AFMR = ACCFMode;// 不 缓 冲 区 接 收 报
文
break;
case ACCF_BYPASS: // 接收滤波器状态-复位/停止
LPC_CANAF->AFMR = ACCFMode; // 所有接收的报文
存到接收缓冲区中
break;
// 接收滤波器状态-运行 // 硬件接收过滤
case ACCF_ON: // ACCOFFACCBPEFCAN=0 时,接收滤波
器处于工作模式
case ACCF_FULLCAN: // ,接收滤波器处于 FullCAN 工作模
式
LPC_CANAF->AFMR = ACCF_OFF;
CAN_SetACCF_Lookup();
LPC_CANAF->AFMR = ACCFMode;
break;
default: break;
}
}
/*-------------------------------------------------------------------
函数名称: CAN_SetACCF()
* 参 数: 波特率
* 返 回: XX
* 函数功能: 接收滤波器状态
*
*-*------------------------------------------------------------------
void CAN_SetACCF_Lookup(void)
{
unsigned int address = 0;
unsigned int ID_high, ID_low;
/* Set explicit standard Frame */
LPC_CANAF->SFF_sa = address;
ID_low = (0x125 << 16);
ID_high = 0x126;
*((volatile uint32_t *)(LPC_CANAF_RAM_BASE + address))
= ID_low | ID_high;
address += 4;
/* Set group standard Frame */
LPC_CANAF->SFF_GRP_sa = address;
ID_low = (0x125 << 16); // 下边界
ID_high = 0x129; / 上边界
*((volatile uint32_t *)(LPC_CANAF_RAM_BASE + address))
= ID_low | ID_high;
address += 4;
LPC_CANAF->EFF_sa = address; //标准扩展帧
LPC_CANAF->EFF_GRP_sa = address; // 扩展帧组帧
/* Set End of Table */
LPC_CANAF->ENDofTable = address; //表结束地址
}
/*-------------------------------------------------------------------------*-
*函数名称: CAN_SetACCF_Lookup()
*参 数: 波特率
*返 回: XX
*函数功能: 接收滤波器状态
*说 明: 如果一个表格的起始地址等于下一个表格的起始
地址或表格终止寄存器的数值,
*则该表格为空,在处理中将被忽略。
*表格的大小由其前后 2 个表格起始地址寄存器的差值决
定。
*例如,(SFF_GRP_sa) - (SFF_sa)为独立标准帧标识符查找表
格大小。
*若其值为0,即 SFF_GRP_sa=SFF_sa,则独立标准帧标识符
查找表格大小为 0,
*在查找时此表格将被忽略。查找表结束寄存器 ENDofTable
代表查找表结束地址,
*(ENDofTable) - (EFF_GRP_sa)为扩展帧组标识符查找表大小。
上一篇:LPC1788 SPI主从机代码
下一篇:LPC1100 IAP使用注意事项与实验例程源码V2.0-基于Keil编译环境
推荐阅读最新更新时间:2024-11-10 09:02