1. 项目概述从数据手册到工程实践如果你在汽车电子或者工业控制领域摸爬滚打过几年肯定对CAN总线不陌生。这玩意儿就像工业ాలుాలుాలుాలుాలు里的“普通话”各个ECU电子控制单元靠它来交换数据。但光有协议标准还不够真正让数据在芯片里跑起来的是像飞思卡尔MSCAN这样的CAN控制器。我手头这份MC9S12HZ256的数据手册第12章密密麻麻几十页全是关于MSCAN的寄存器描述和功能框图。新手看了可能头大但对我们这些老鸟来说这里面藏着让系统跑得又快又稳的关键。这份手册详细描述了MSCAN控制器的消息存储模型、三重发送缓冲机制以及最核心的标识符接受过滤器。简单说它解决了CAN应用里两个最头疼的问题第一CPU怎么才能不被海量的CAN消息中断淹死第二当有好几条消息都想发送时先发哪条MSCAN通过硬件级的消息过滤和优先级调度把CPU从繁重的报文筛选工作中解放出来让它能专心处理应用逻辑。这篇文章我就结合自己踩过的坑和项目经验把这套机制掰开揉碎了讲清楚重点不是复ాలుాలుాలుాలుాలుాలు数据手册而是告诉你这些寄存器位在实际代码里怎么配为什么这么配以及配错了会出什么幺蛾子。2. MSCAN消息存储结构与核心寄存器精解MSCAN的消息存储设计得非常巧妙它采用了“前台-后台”分离的模型这对于理解其高效运作至关重要。整个消息缓冲区在内存映射中占据16字节但实际用于存储CAN帧的数据结构是13字节剩下3字节用于特殊功能。2.1 消息缓冲区的统一布局无论是接收缓冲区还是发送缓冲区它们都遵循相同的13字节数据结构布局。这种统一性大大简化了驱动程序的编写。这13个字节的分配如下字节 0-3 (IDR0-IDR3)标识符寄存器。用于存放标准11位或扩展29位的CAN ID以及SRR、IDE、RTR等控制位。ాలుాలు 4-11 (DSR0-DSR7ాలు数据段寄存器。最多存放8个字节的CAN数据。字节 12 (DLR)数据长度码寄存器。低4位DLC[3:0]指示数据字节数范围0-8。字节 13 (TBPR)发送缓冲区优先级寄存器。仅存在于发送缓冲区用于定义本条消息的本地优先级。字节 14-15 (TSRH-TSRL)时间戳寄存器。当使能时间戳功能后由MSCAN硬件在消息成功发送或接收的ACK定界符采样点自动写入。这里有个关键细节IDR0-IDR3的映射方式因帧格式ాలు不同。ాలు扩展帧RR1ాలు IDEాలు时ాలుID28最高ాలు占据IDR0的最高位依次排列直到ID0占据IDR3的低位。而对于标准帧IDE0只有IDR0和IDR1被使用ID10占据IDR0的最高位。这种比特位的排列顺序与CAN总线在线上的仲裁发送顺序完全一致IDాలు先发送。ాలు在配置过滤器ాలు必须ాలు这种比特顺序来设置接受码ాలు掩码ాలు否则过滤会ాలు乱。ాలు ాలు.2 ాలు发送缓冲区Tx Buffer的“三重奏”MSCAN配备了三个独立的发送缓冲区Tx0, Tx1, Tx2。为什么是三个而不是一个或两个数据手册里给出了很实在ాలుాలుాలుాలుాలుాలుాలుాలుాలు为了满足现代ాలుRRాలుాలుాలు软件“不间断发送消息流”的假设。试想一下如果只有一个发送缓冲区CPU必须在上一帧消息发送完毕后的极短时间内在帧间间隔IFS内填好下一帧数据这对CPU的中断响应时间提出了苛刻要求。双缓冲区方案有所改善但如果在CPU填充第二个缓冲区时第一个缓冲区发送完成依然会出现总线空闲期。三个缓冲区构成了一个“流水线”一个正在发送TxFG一个准备就绪TxBG一个正在被CPU填充。这确保了只要总线上有发送权限节点就能持续发送实现了“背靠背”传输对于需要周期性发送大量数据的节点如电机控制器、传感器融合单元性能提升显著。每个发送缓冲区都附带一个8位的本地优先级寄存器TBPR。这个优先级仅在本节点内部生效用于在多个缓冲区同时就绪时决定谁先参与总线仲裁。优先级数值越小优先级越高。如果优先级相同则缓冲区索引号小的胜出。这个设计允许软件根据消息的紧急程度进行灵活调度比如刹车信号优先级设为0x01车窗状态信号优先级设为0xFF。2.3 接收缓冲区Rx Buffer的五级FIFO接收侧采用了5级FIFO先入先出队列但呈现给CPU的只有一个“前台”接收缓冲区RxFG。另外四个缓冲区和一个“后台”缓冲区RxBG对CPU不可见由MSCAN硬件管理。工作流程是这样的当CAN总线上出现消息时MSCAN的接收引擎会先将它存入后台接收缓冲区RxBG。同时硬件过滤器后面会详述对该消息的标识符进行匹配检查。只有通过过滤的消息才会从RxBG移入接收FIFO队列。当有消息进入FIFO并且前台缓冲区RxFG为空时FIFO中的第一条消息会被自动搬运到RxFG并置位接收完成标志RXF1如果使能了接收中断则会向CPU申请中断。CPU在中断服务程序中从RxFG读取数据然后必须手动清除RXF标志。这个清除动作相当于告诉MSCAN“这条消息我处理完了请把ాలుFG缓冲区释放ాలు并把ాలుFIFాలు中的下ాలు条消息ాలు进来。”这个设计的好处是ాలుCPU永远从一个固定的ాలు址ాలుFGాలు取数据ాలు软件处理逻辑简单ాలు同时ాలు级FాలుO提供了ాలు定的缓存能力ాలు即使CPU一时ాలు不过来也不至于ాలు丢消息直到FIFాలు被填ాలు此时会发生ాలు载错误。ాలు ాలు.4ాలు时间戳ాలుTIMEాలు能的妙ాలు时间戳ాలు能是ాలు个容易被RR略但非常实用的特性。当使能CANCTL0.TIME 1后MSCAN会在消息被成功确认ACK定界符的隐性位采样点的瞬间将一个16位的内部自由运行计数器值写入该消息缓冲区的时间戳寄存器。这个时间戳的时钟源是CAN位时钟因此它的精度非常高单位是CAN位时间。它有什么用呢网络延迟分析发送节点可以在发送时记录一个软件时间戳接收节点记录硬件时间戳结合总线传播延迟可以估算端到端延迟。节点间时间同步虽然不如IEEE 1588精确但在一些对时间同步有要求但不苛刻的分布式控制系统中可以通过定期发送的同步帧附带的时间戳来校准各节点的本地时钟。故障诊断当总线上出现错误或异常消息时精确的时间戳有助于在日志中重建事件序列定位问题根源。需要注意的是这个时间戳计数器在初始化模式下会被清零并且溢出后不会产生中断。因此如果应用依赖于绝对时间软件需要在其溢出前每65536个CAN位时间进行读取和累计。3. 标识符接受过滤器CAN网络的“守门人”这是MSCAN最核心、最灵活也最容易配错的功能。它的作用就像一个智能门卫只放行“认识”的消息进入CPU把无关的消息直接挡在硬件层极大减轻了CPU的中断负担。3.1 过滤器的基本原理接受码与掩码过滤器由两组寄存器共同工作标识符接受寄存器CANIDAR0-7和标识符掩码寄存器CANIDMR0-7。每组都有8个寄存器对应32个字节的过滤配置空间。接受寄存器CANIDAR这里面存放的是你期望匹配的标识符模式。你可以把它想象成一张“通行证”的模板。掩码寄存器CANIDMR这里面的每一位决定了对接受寄存器对应位的匹配要求。掩码位为0表示“必须严格匹配”为1表示“不关心”Dont Care。过滤逻辑是逐位进行的(接收到的ID位) XOR (接受寄存器位) AND (NOT 掩码位)。如果最终结果为0则该位匹配。所有需要匹配的位即掩码为0的位都匹配成功这条消息就被接受。举个例子假设我们只想接收标准ID为0x123的消息。标准ID 0x123的二进制是001 0010 001111位。我们需要配置过滤器为“2个32位过滤器”模式后文详述并使用第一个过滤器。对于标准帧只使用CANIDAR0/1和CANIDMR0/1。设置 CANIDAR0 0x12 CANIDAR1 0x30注意比特对齐ID10在IDR0的最高位ID0在IDR1的bit5RTR和IDE位也要设置。设置 CANIDMR0 0x00 CANIDMR1 0x1F低3位AM[2:0]必须设为1手册要求标准帧下最后3位为“不关心”。 这样只有当接收到的ID高8位ID10-ID3完全等于0x12且ID2-ID0位等于0x3即0011时消息才会被接受。掩码寄存器中为1的位如IDR1的低3位被忽略允许RTR和IDE位任意。3.2 过滤器的四种工作模式MSCAN过滤器可以通过CANIDAC寄存器的IDAM[1:0]位配置成四种模式这是其灵活性的体现。模式0两个32位可屏蔽过滤器这是功能最强的模式专为扩展帧设计。每个过滤器检查完整的29位扩展ID外加SRR、IDE、RTR位共32位。第一个过滤器使用CANIDAR0-3和CANIDMR0-3。第二个过滤器使用CANIDAR4-7和CANIDMR4-7。应用场景需要精确匹配一两个特定扩展ID或者匹配一个ID段利用掩码。例如在车载网络中某个节点只处理发动机控制模块ECMID 0x18ECFFxx和变速箱控制模块TCMID 0x18EBFFxx发来的特定消息。模式1四个16位可屏蔽过滤器每个过滤器检查扩展ID的高14位SRRIDE位或者标准ID的11位RTRIDE位共16位。第一个过滤器使用CANIDAR0-1和CANIDMR0-1。第二个过滤器使用CANIDAR2-3和CANIDMR2-3。第三、四个过滤器使用CANIDAR4-7和CANIDMR4-7。应用场景需要按ID段进行分组过滤。例如在一条总线上有多个同类型的传感器它们的ID高11位相同如0x5A0低ాలు位表示传感器地址ాలు就可以用ాలు个过滤器匹配所有地址为0-3的传感器消息用另一个过滤器匹配地址为4-7的消息。模式2八个8RR可屏蔽ాలు器ాలు个过滤器ాలు检查ID的前8RR对于扩展ాలు是IDాలు-ID21ాలు于标准 RR是IDాలు-ID3ాలు。 -ాలు个寄存器对ాలుIDARాలు/CAN RRMRnాలు成一个过滤器。应用RR景ాలు用于标准帧的ాలు播或组ాలు过滤非常高效。ాలు如ాలు个网关上ాలు要转发所有ాలుID高8RR为0x08控制类ాలు令ాలు0x18诊断服务的消息到另一条ాలు线就可以用ాలు个过滤器ాలు别匹配0xాలు和0ాలు18。**ాలు式3ాలు关闭过滤器ాలు -ాలు有消息ాలు被接ాలుRXFాలు志永远不会被ాలు位。这通常ాలు于调试ాలు者让节点进入ాలు种“监听”ాలు静默模式接收所有消息但不产生中断通过轮询方式读取。3.3 配置过滤器的实战步骤与避坑指南配置过滤器必须在MSCAN的初始化模式INITRQ1且INITAK1下进行。下面是一个典型的配置流程以“四个16位过滤器”模式接收标准ID 0x123和0x456为例// 1. 请求进入初始化模式 CANCTL0_INITRQ 1; while(CANCTL1_INITAK 0); // 等待确认进入 // 2. 设置过滤器模式四个16位过滤器 CANIDAC_IDAM1 0; CANIDAC_IDAM0 1; // IDAM[1:0] 01b // 3. 配置第一个过滤器接受标准ID 0x123 (数据帧) // 标准ID 0x123 001 0010 0011 b // 在IDR0/1中的布局[ID10-ID3] [ID2-ID0, RTR, IDE] // IDR0 ID10-ID3 0010 0011 0x23 // IDR1 [ID2-ID0011, RTR0, IDE0] 0110 0000 0x60 CANIDAR0 0x23; // 接受码高字节 CANIDAR1 0x60; // 接受码低字节 // 掩码需要匹配所有位但标准帧下IDR1的低3位(AM2-AM0)必须为1不关心 CANIDMR0 0x00; // 必须匹配IDR0所有位 CANIDMR1 0x07; // 低3位设为1不关心IDE/RTR等 // 4. 配置第二个过滤器接受标准ID 0x456 (远程帧) // 标准ID 0x456 100 0101 0110 b // IDR0 0101 0110 0x56 // IDR1 [ID2-ID0110, RTR1, IDE0] 1101 0000 0xD0 CANIDAR2 0x56; CANIDAR3 0xD0; CANIDMR2 0x00; CANIDMR3 0x07; // 同样低3位不关心 // 5. 退出初始化模式 CANCTL0_INITRQ 0; while(CANCTL1_INITAK 1); // 等待退出避坑要点模式与寄存器对应关系务必根据选择的过滤器模式正确配对使用接受寄存器和掩码寄存器。用错了寄存器对过滤会完全失效。标准帧的“最后三位”数据手册特别强调在32位和16位过滤器模式下用于标准帧时必须将掩码寄存器CANIDMR1, CANIDMR3, CANIDMR5, CANIDMR7的最低3位AM[2:0]设置为1不关心。这是因为标准帧的ID只有11位在IDR1寄存器中只占高5位低3位是未使用的。如果错误地设为0要求匹配将永远无法收到任何标准帧。扩展帧的SRR和IDE位在配置扩展帧过滤器时接受寄存器中的SRR位必须设为1IDE位也必须设为1以匹配扩展帧的固定格式。掩码寄存器中对应位通常设为0必须匹配。过滤器的优先级当一条消息同时匹配多个过滤器时IDHIT[2:0]标志位会指示编号最小的那个过滤器。这在调试时非常有用可以确认是哪条过滤规则生效了。初始化顺序一定要先进入初始化模式再配置过滤器寄存器最后退出。在正常操作模式下写这些寄存器是无效的。4. 消息传输机制与优先级调度实战理解了存储和过滤我们再来看MSCAN如何高效、可靠地发送消息。这涉及到三重发送缓冲区的协同和基于本地优先级的内部调度。4.1 消息发送的完整流程假设我们要发送一条扩展数据帧ID为0x18FEDF00数据长度为8字节数据内容为0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88并赋予其较高的本地优先级0ాలు01。1.ాలు寻找空闲发送ాలు冲区ాలుాలు环检查CANTాలుLG寄存器中的TXాలు0、ాలుXE1ాలుTXEాలు标志。ాలు个标志ాలు1表示ాలు应的缓冲区ాలు空ాలు以被ాలు写。ాలు果都为零ాలు明所有ాలు冲区ాలు在等待发送ాలు需要等待ాలు者检查是ాలు发生了错误。ాలు.ాలు择并锁定缓冲区ాలుాలు设TXాలు21我们ాలు定使用ాలు送缓冲区ాలు。通过向CANTBSEL寄存器写入2来“选中”这个缓冲区。这个操作ాలు关重要ాలు它使得ాలు下来对CANTాలుFG地址空间通常是基地址0x00的读写操作都会映射到Tx2的实际内存区域。这是一种硬件地址重映射机制让软件可以用同一套地址操作不同的缓冲区。填充消息对象配置标识符因为是扩展帧IDE位需为1。IDR0-IDR3的填充需要特别注意比特顺序。IDR0 (0x18FEDF00 21) 0xFF 0x18FEDF00 21 结果是0x0C7取低8位为0xC7。但注意ID28是最高位在IDR0的bit7。所以我们需要将29位ID左移3位因为ID后面还有SRR、IDE等位再按字节分割。更稳妥的方法是使用联合体union或结构体位域来操作。配置数据段将8个字节的数据依次写入DSR0-DSR7。配置数据长度设置DLR寄存器的DLC[3:0] 1000b (0x8)。配置本地优先级设置TBPR 0x01数值越小优先级越高。提交发送请求清除CANTFLG寄存器中的TXE2标志位。这个“清除”操作对于CPU是“写1清0”。一旦TXE2被清零MSCAN硬件便知道该缓冲区已准备就绪会将其纳入内部的发送调度队列。等待发送完成/中断MSCAN会在总线空闲时根据内部调度算法见下文选择优先级最高的就绪缓冲区进行仲裁发送。发送成功后硬件会自动将TXE2标志位置1如果使能了发送中断CANRIER_TXEIE2 1则会产生中断。在中断服务程序中我们可以通过检查TXE2标志位来确定是哪个缓冲区发送完成并进行后续处理如填充下一帧数据。4.2 内部优先级调度机制当多个发送缓冲区TXEx0表示就绪同时存在时MSCAN如何决定发送顺序它采用了一套基于本地优先级TBPR的硬件调度机制。调度发生在两个时刻当MSCAN尝试获取CAN总线使用权即参与仲裁之前。在发生发送错误后重试发送之前。调度规则很简单比较所有就绪缓冲区的TBPR值数值最小的拥有最高发送优先级。如果两个缓冲区的TBPR值相同则缓冲区索引号小的Tx0 Tx1 Tx2优先。这个机制赋予了软件极大的灵活性。例如在一个车身控制模块中你可以将“碰撞传感器信号”的TBPR设为0x01“车门锁状态”的TBPR设为0xFE。这样即使车门状态消息先准备好一旦碰撞信号需要发送它总能优先被调度出去满足了功能安全中对最高优先级消息的实时性要求。4.3 消息发送中止Abort机制有时候情况会发生变化。比如一条低优先级的诊断请求消息正在等待发送但此时突然产生了需要立即发送的高优先级事件帧。为了避免高优先级消息被阻塞MSCAN提供了消息中止功能。中止流程是软件请求、硬件执行的软件请求CPU设置CANTARQ寄存器中对应缓冲区的ABTRQx位为1。硬件裁决与执行MSCAN检查该缓冲区是否尚未开始发送即未进入“正在发送”状态。如果条件满足则 a. 设置CANTAAK寄存器中对应的ABTAKx位为1表示中止已确认。 b. 将该缓冲区的TXEx标志位置1释放缓冲区。 c. 产生一个发送中断。软件响应在发送中断服务程序中软件需要检查CANTAAK寄存器。如果ABTAKx1说明消息被中止如果ABTAKx0说明消息正常发送完成。根据此标志软件可以决定是重新填充原消息还是填充新的高优先级消息。重要提示中止只能发生在消息进入发送移位寄存器之前。一旦开始发送位流就无法中止必须等待其发送完成或出错。因此对于实时性要求极高的应用需要预估最坏情况下的总线负载和仲裁时间确保高优先级消息能在其截止期前获得发送机会而不是依赖中止机制。5. 接收处理、错误管理与深度调试技巧消息接收的流程相对直接但其中的细节和错误处理是保证通信鲁棒性的关键。5.1 接收中断处理与缓冲区管理接收中断服务程序ISR的编写必须高效且正确#pragma interrupt_handler CAN_Rx_ISR void CAN_Rx_ISR(void) { // 1. 检查中断源一定是RXF标志置位 if (CANRFLG_RXF 1) { // 2. 读取标识符命中标志确定是哪条过滤规则匹配可选用于诊断或分派 uint8_t filter_hit CANIDAC_IDHIT2 2 | CANIDAC_IDHIT1 1 | CANIDAC_IDHIT0; // 3. 从RxFG读取消息数据 // 注意读取顺序建议为先读IDR/DSR等数据最后读时间戳如果使能 my_rx_id ((uint32_t)IDR0 21) | ... ; // 组合扩展ID my_rx_dlc DLR 0x0F; for(int i0; imy_rx_dlc; i) { my_rx_data[i] DSR[i]; } if (CANCTL0_TIME) { // 如果使能了时间戳 my_rx_timestamp (TSRH 8) | TSRL; } // 4. 清除RXF标志释放前台缓冲区这是最关键的一步。 CANRFLG_RXF 1; // 写1清0 // 5. 处理数据... process_received_message(my_rx_id, my_rx_data, my_rx_dlc); } // 清除模块级接收中断标志如果存在 CANRFLG_RXF 1; // 确保清除 }关键点必须在读取完所需数据后立即清除RXF标志。这个动作不仅是为了响应中断更重要的是释放RxFG缓冲区让MSCAN能把FIFO中的下一条消息搬进来。如果忘记清除接收FIFO将会阻塞新消息无法进入RxFG表现为“无法接收后续消息”。5.2 错误计数器与总线状态管理MSCAN有两个错误计数器发送错误计数器CANTXERR和接收错误计数器CANRXERR。它们对于监控总线健康度至关重要。错误计数器行为遵循CAN协议规范。成功发送/接收一次计数器减1最低到0。发生错误时根据错误类型增加相应值。总线状态转换当发送错误计数器值超过127时节点进入错误被动Error Passive状态。在此状态下节点仍能收发数据但在检测到错误时只能发送被动错误标志连续6个隐性位其错误恢复能力变弱。当发送错误计数器值超过255时节点进入总线关闭Bus Off状态。节点自动从总线上断开停止一切发送和接收活动。这是最严重的错误状态通常由硬件故障或严重电磁干扰引起。监控与恢复策略定期轮询在应用层任务中定期读取CANTXERR和CANRXERR的值。如果发送错误计数器持续快速增加可能表明本地发送器故障或终端电阻不匹配。中断响应使能错误中断CANRIER_ERRIE 1。在错误中断服务程序中读取CAN错误状态寄存器判断是警告中断、错误被动中断还是总线关闭中断。总线关闭恢复MSCAN支持自动恢复。当进入总线关闭状态后硬件会等待128次出现11个连续的隐性位总线空闲后自动将错误计数器清零并尝试重新进入总线活动状态。软件也可以主动干预通过进入初始化模式再退出来强制复位MSCAN模块。5.3 常见问题排查实录在实际项目中MSCAN相关的问题五花八门但大多集中在配置和中断处理上。问题1节点发送正常但完全收不到任何消息。检查1过滤器配置这是最常见的原因。确认是否误入了“关闭过滤器”模式IDAM3。检查接受码和掩码设置是否正确特别是标准帧下的低3位掩码。一个快速的调试方法是先将所有掩码寄存器设为0xFF全部不关心如果此时能收到消息再逐步收紧过滤条件。检查2接收中断配置确认CANRIER中的RXFIE接收中断使能位已置1。检查CPU全局中断是否开启。检查3RXF标志处理在第一次收到消息产生中断后是否在ISR中清除了RXF标志如果没有清除RxFG缓冲区一直被占用后续消息无法进入看起来就像“只收到第一条消息后便沉默”。检查4波特率发送和接收节点的波特率必须精确一致。即使有万分之一的误差长期积累也会导致采样点偏移最终无法识别帧起始SOF而收不到帧。问题2发送中断不产生或产生一次后不再产生。检查1发送缓冲区释放在发送中断服务程序中完成数据处理后是否将数据准备好并再次清空了TXEx标志发送中断产生TXEx1只表示“发送完成缓冲区已空”。如果你需要周期发送必须在中断里重新填充缓冲区并清除TXEx置0以提交下一次发送请求。忘记清除TXEx缓冲区会一直处于“空”状态MSCAN认为没有消息要发。检查2中断标志清除发送中断产生后除了硬件置位TXEx可能还需要软件清除某个模块级中断标志。查阅数据手册确认是否需要向CANTFLG寄存器对应位写1来清除中断标志。检查3优先级与仲裁消息是否真的成功发送出去了如果消息优先级很低而总线一直很忙它可能长时间无法赢得仲裁从而一直停留在发送缓冲区不会产生“发送完成”中断。可以通过监听总线或检查发送错误计数器来辅助判断。问题3网络增加节点后通信变得不稳定错误帧频发。检查1终端电阻CAN总线两端最远的两个节点必须各接一个120欧姆的终端电阻用于阻抗匹配消除信号反射。增加节点可能改变了总线拓扑导致等效阻抗变化。确保总线上有且仅有两个120欧姆电阻。检查2总线负载使用CAN分析仪监控总线负载率。如果负载率持续超过70%-80%网络延迟会急剧增加错误概率上升。需要优化通信矩阵减少非必要消息的发送频率或提升波特率。检查3地电位差在大型设备或长距离通信中不同节点的地线可能存在电位差。这会在CAN_H和CAN_L上引入共模噪声。确保所有节点的CAN_GND良好连接或考虑使用带隔离的CAN收发器。问题4如何验证过滤器配置是否正确软件仿真在编写初始化代码时可以计算一个期望的ID然后模拟过滤过程。例如期望接收ID0x123就计算(0x123 21)后的比特模式与CANIDAR和CANIDMR逐位比对。硬件回环测试将MSCAN配置为环回模式CANCTL1.LOOPB1。在此模式下节点发送的消息会被自己接收。你可以先配置一个狭窄的过滤器如只接受ID0x123然后尝试发送ID0x123和0x124的消息。只有0x123的消息能触发接收中断从而验证过滤器工作正常。利用IDHIT标志在接收中断中读取CANIDAC寄存器的IDHIT[2:0]位。它会告诉你当前收到的消息命中了哪个过滤器编号。通过发送一系列已知ID的消息观察IDHIT值的变化可以逆向推导出过滤器的实际匹配范围。调试CAN通信一个CAN总线分析仪如PCAN-USB, ZLG CANalyst-II是必不可少的。它能让你直观地看到总线上流动的所有原始帧包括错误帧是定位物理层、数据链路层问题最强大的工具。当软件层面排查无果时一定要用分析仪看看总线实际波形。