CAN控制器消息对象与FIFO缓冲机制:从寄存器配置到实战应用

📅 2026/7/23 19:49:59 👁️ 阅读次数 📝 编程学习
CAN控制器消息对象与FIFO缓冲机制:从寄存器配置到实战应用

1. 项目概述:深入理解CAN控制器的消息管理核心

在汽车电子和工业控制领域,控制器局域网(CAN)总线堪称通信的“大动脉”,其稳定性和实时性直接决定了整个系统的可靠性。作为一名长期与各种微控制器和通信协议打交道的工程师,我深知仅仅知道CAN的物理层和数据链路层协议是远远不够的。真正的挑战在于如何高效、可靠地驾驭控制器内部的硬件资源,而其中最关键、也最容易被忽视的,就是消息对象(Message Object)FIFO缓冲机制的配置与管理。

很多开发者拿到芯片手册,看到一堆诸如CANIFnARBCANIFnMSKCANIFnMCTL的寄存器时,往往感到无从下手,只能照抄例程。但一旦遇到复杂的多帧通信、需要动态过滤特定ID范围的消息、或者处理高速连续数据流时,照抄的代码就容易“翻车”。消息丢失、优先级混乱、缓冲区溢出等问题接踵而至。这篇文章,我将结合TI Tiva系列微控制器的CAN控制器,为你彻底拆解消息对象从配置、过滤到组成FIFO缓冲区的完整流程。我会重点解释每个寄存器位背后的设计逻辑,分享实际调试中积累的配置心得和避坑指南,让你不仅能配置出来,更能理解为什么这么配置,从而在复杂的现场应用中游刃有余。

2. CAN消息对象基础与优先级机制解析

在深入配置细节之前,我们必须建立一个清晰的认知模型:CAN控制器内部的消息对象到底是什么?你可以把它想象成邮局里一个个专属的“信箱”。每个信箱(消息对象)都有一个唯一的编号(Message Number,通常是1到32或更多),并且预先设置好了收件人地址(消息标识符ID)和邮件处理规则(控制位)。当总线上的数据帧(邮件)到来时,硬件会自动根据地址进行分拣,投入对应的信箱;当我们需要发送数据时,也是把数据放入指定的信箱,然后通知邮差(消息处理器)按顺序寄出。

2.1 消息编号与传输优先级:硬件级的调度策略

输入材料中明确指出:“The receive/transmit priority for the message objects is controlled by the message number. Message object 1 has the highest priority, while message object 32 has the lowest priority.”

这是CAN控制器硬件优先级的核心规则,与CAN总线协议本身的ID仲裁优先级完全独立。理解这一点至关重要。

  • 总线仲裁优先级:由CAN协议定义,基于消息标识符(ID)进行“线与”判定,ID值越小,优先级越高。这个优先级决定了在总线空闲时,哪个节点能抢到发送权。
  • 控制器内部发送优先级:由消息对象的编号决定。当多个消息对象同时置起发送请求位(TXRQST)时,消息处理器(Message Handler)会严格按照编号从小到大的顺序,依次将消息对象的数据加载到发送移位寄存器。消息对象1总是最先被服务

为什么需要两套优先级?设想一个汽车车身控制器,它需要同时处理车窗升降(低实时性)和碰撞传感器信号(高实时性)的发送。如果只依赖总线ID仲裁,为了确保碰撞信号优先,必须赋予其极小的ID值。但ID资源有限,且过于分散的ID不利于管理。有了硬件消息对象优先级,我们可以将碰撞信号放在消息对象1,车窗控制放在消息对象10。即使车窗控制消息先准备好,控制器内部也会优先处理并尝试发送消息对象1的碰撞信号。这为软件设计提供了极大的灵活性,可以将最紧急、最关键的通信任务绑定到低编号的消息对象上。

实操心得:优先级规划在实际项目规划阶段,建议制作一个消息对象分配表。将需要发送的消息,按其紧急程度从高到低排序,依次分配到从1开始的编号。对于纯接收的消息对象,优先级意义不大,可以分配较高的编号。记住,这个分配是静态的,初始化后通常不会改变。

2.2 消息对象的核心寄存器概览

每个消息对象的配置,本质上是配置两组寄存器:接口寄存器(Interface Registers)消息RAM(Message RAM)。我们通过写接口寄存器来“描述”我们想要的消息对象,然后通过一个“提交”命令,将这套描述写入到实际的硬件消息RAM中。Tiva的CAN控制器通常提供两套接口寄存器(IF1和IF2),可以用于流水线操作,但基本功能相同。

关键寄存器组包括:

  • 命令请求寄存器(CANIFnCRQ):指定我们要操作哪个编号的消息对象(MNUM字段)。
  • 命令掩码寄存器(CANIFnCMSK):指定本次操作是读还是写,以及要更新消息对象的哪些部分(如数据、仲裁场、控制位)。
  • 仲裁寄存器(CANIFnARB1/2):设置消息的标识符(ID)、扩展标识符位(XTD)和方向位(DIR)。
  • 掩码寄存器(CANIFnMSK1/2):设置验收过滤的掩码,决定哪些位需要严格匹配。
  • 消息控制寄存器(CANIFnMCTL):这是核心控制寄存器,包含数据长度码(DLC)、新数据标志(NEWDAT)、中断挂起(INTPND)、缓冲区结束标志(EOB)等关键位。
  • 数据寄存器(CANIFnDA1/2, DB1/2):存放8字节的数据载荷。

3. 接收消息对象的配置详解与验收过滤

配置一个接收消息对象,就是告诉控制器:“请为我建立一个信箱,我只接收符合这些特征的‘邮件’。” 这个过程需要严谨的步骤,错一步都可能导致接收失败。

3.1 配置流程分步拆解

根据输入材料,配置一个接收消息对象的标准流程如下,我将为每一步补充背后的意图和实操细节:

第一步:准备命令掩码(CANIFnCMSK)这一步是声明我们的“操作意图”。我们需要配置CANIFnCMSK寄存器,告诉消息处理器:“接下来我要写数据到消息RAM。” 关键是将WRNRD位设置为1(写操作)。同时,MASK字段用来选择我们要更新消息对象的哪些部分。对于初始配置,我们通常需要更新仲裁场、控制场和数据场,所以需要设置相应的位(如ARB,CTRL,DATA)。一个常见的坑是忘记设置这些位,导致配置没有完全生效。

第二步:设置验收过滤掩码(CANIFnMSK1/2)这是实现“精准接收”或“群组接收”的关键。验收过滤的原理类似于通配符。

  • CANIFnMSK1CANIFnMSK2寄存器中的MSK[15:0]位对应着29位扩展ID的[28:13]位和11位标准ID的[10:0]位(具体对应关系需查数据手册,输入材料提到MSK[12:0]用于29位ID的[28:16])。
  • 掩码位为0:表示对应ID位必须严格匹配CANIFnARB寄存器中设定的值。
  • 掩码位为1:表示对应ID位是“不关心”位,无论总线上该位是0还是1,都算匹配。
  • MXTDMDIR位:分别控制是否对扩展标识符位(XTD)和方向位(DIR)进行过滤。如果MXTD=1,则只接收与配置的XTD位相同的帧(即只接收标准帧或只接收扩展帧)。

例如:假设我们使用11位标准ID,配置ARB的ID为0x123MSK0x7FF。由于MSK所有位都是1(不关心),那么所有标准帧都会被接收,过滤失效。如果配置MSK0x7F0(二进制111 1111 0000),则只匹配ID的高7位(0x123 & 0x7F0 = 0x120),即所有ID在0x1200x12F之间的帧都会被接收。这常用于接收某个节点发出的一组相关消息。

注意事项:启用掩码掩码寄存器配置好后并不会立即生效!必须将CANIFnMCTL寄存器中的UMASK位设置为1,才能使能验收过滤功能。这是新手最容易遗漏的一步,会导致配置了掩码但不起作用,所有消息都涌进来。

第三步:配置仲裁字段(CANIFnARB1/2)这里设定我们期望接收的消息的“地址”。

  • CANIFnARB2寄存器中设置XTD位:0表示11位标准标识符,1表示29位扩展标识符。
  • CANIFnARB1/2中写入具体的标识符值(ID)。
  • 必须将MSGVAL位设置为1,这表示该消息对象是有效的、激活的。如果忘记设置,该消息对象将被硬件忽略。
  • 必须将DIR位清除为0,明确这是一个用于接收的消息对象。

第四步:配置消息控制寄存器(CANIFnMCTL)这是收尾也是精细化控制的一步。

  1. 设置UMASK:如前所述,使能验收过滤掩码。
  2. 设置RXIE:如果希望该消息对象成功接收一帧数据后产生中断,就置位此位。它会使INTPND位在接收完成后置1。
  3. 清除RMTEN:对于纯接收对象,通常清除此位。它的功能是远程帧自动处理,保持为0意味着接收对象的TXRQST位不会被远程帧自动置位。
  4. 设置EOB:对于单个接收消息对象(非FIFO成员),此位必须设置为1,表示它是一个独立的“缓冲区结束”。
  5. 配置DLC[3:0]:这里设置的是期望接收的数据长度(0-8字节)。如果总线上到来的数据帧长度小于此DLC,数据寄存器中未使用的字节会被填入未定义值;如果大于此DLC,则可能根据控制器配置产生错误或只接收前DLC个字节。最佳实践是将其设置为8,以接收最大可能的数据,然后在软件中根据实际长度处理。

严重警告:配置时的“雷区”输入材料特别强调:“Take care during this configuration not to set the NEWDAT, MSGLST, INTPND or TXRQST bits.” 在初始化配置阶段,NEWDAT(新数据)、MSGLST(消息丢失)、INTPND(中断挂起)、TXRQST(发送请求)这些状态位必须保持为0。它们应由硬件在运行时自动设置,或在软件处理时由软件清除。如果在初始化时误写这些位,会导致状态机混乱,例如可能错误地触发发送或误判已有数据。

第五步:提交配置最后,将目标消息对象的编号写入CANIFnCRQ寄存器的MNUM字段。这个写操作就像一个触发器,命令消息处理器将刚才在接口寄存器中设置好的所有参数,一次性写入到消息RAM中对应编号的“信箱”里。从此,这个接收信箱就开始工作了。

4. FIFO缓冲机制的配置与应用实战

单个消息对象只能缓存一帧数据。如果新数据到来而旧数据未被CPU读取,旧数据就会被覆盖,导致丢失。对于连续、高速的数据流(如电机编码器位置、高速ADC采样值),我们需要一个队列,这就是FIFO缓冲区

4.1 FIFO的构成原理

FIFO缓冲区由多个消息对象串联而成。这些对象共享相同的标识符和过滤掩码(如果需要过滤),形成一个逻辑上的先进先出队列。其核心思想是利用硬件自动管理数据在多个物理“信箱”中的轮转。

关键配置点在于EOB位和消息编号的隐式优先级:

  1. 串联对象:将2个到32个(取决于控制器)连续编号的消息对象配置成一组。它们的ARB(ID)和MSK(掩码)必须设置为相同的值。
  2. EOB位的作用EOB(End Of Buffer)是区分单个对象和FIFO成员的关键。
    • 对于FIFO中最后一个消息对象,其EOB位必须设置为1
    • 对于FIFO中其他所有消息对象,其EOB位必须清除为0
  3. 硬件管理流程:当匹配的CAN帧到达时,消息处理器会从这组对象中编号最小的那个开始查找。它会寻找第一个NEWDAT位为0(即没有未读新数据)的消息对象,将数据存入,并置位其NEWDAT位。如果所有对象的NEWDAT都为1(即队列已满),则数据会被存入EOB=1的最后一个对象,并覆盖那里的旧数据,同时该对象的MSGLST位会被置1,提示有消息丢失。

4.2 配置一个FIFO接收缓冲区的步骤

假设我们需要一个深度为4的FIFO来接收ID为0x100的标准帧数据。

  1. 选择对象编号:例如使用消息对象10, 11, 12, 13。
  2. 配置对象10(FIFO第一个)
    • 按照上一章步骤配置ARB(ID=0x100, DIR=0, XTD=0)、MSK(如0x7FF完全匹配)、MCTL(DLC=8, RXIE=1使能中断)。
    • 关键:EOB清零
    • MNUM设为10,写入配置。
  3. 配置对象11和12(FIFO中间成员)
    • 重复与对象10完全相同的ARBMSKMCTL配置。
    • EOB位同样清零
    • 分别将MNUM设为11和12,写入配置。
  4. 配置对象13(FIFO最后一个)
    • 重复相同的ARBMSKMCTL配置。
    • 关键:EOB设置为1
    • MNUM设为13,写入配置。

至此,一个深度为4的接收FIFO就配置完成了。硬件会自动管理数据在10->11->12->13这个链路上的存储。

4.3 从FIFO中读取数据的正确姿势

读取FIFO不能乱读,必须遵循“从低编号到高编号”的顺序,这是由硬件的工作机制决定的。

  1. 中断触发:当任何FIFO成员接收到数据,如果使能了中断(RXIE=1),就会产生中断。CANINT寄存器会指向当前所有中断中编号最小的那个挂起对象。
  2. 读取操作:在中断服务程序或主循环中,我们需要读取数据。
    • 首先,向CANIFnCMSK寄存器写入0x007F。这个值通常表示设置CLRINTPNDTXRQST等位,具体含义是:在读取消息时,同时清除该对象的NEWDATINTPND。这是至关重要的一步,目的是释放该消息对象槽位,使其可以接收下一帧数据。
    • 然后,将你想要读取的消息对象编号(例如10)写入CANIFnCRQMNUM字段。
    • 硬件会将消息对象10的数据从消息RAM加载到接口寄存器(CANIFnDAx/DBx)中,并自动清除对象10的NEWDATINTPND位。
  3. 顺序读取:读完对象10后,接下来应该检查对象11的NEWDAT位(通过读取其MCTL寄存器)是否为1,如果是,则重复上述步骤读取对象11,以此类推。绝对不能跳着读。因为硬件总是将新数据放入NEWDAT=0的、编号最小的槽位。如果你跳过了对象10直接读对象11,那么对象10将永远保持NEWDAT=1而被锁定,新数据会持续覆盖对象13(最后一个),导致FIFO的有效深度减一,并不断触发消息丢失(MSGLST)。

实操心得:FIFO读指针管理在实际编程中,建议维护一个软件“读指针”,指向当前期望读取的FIFO起始对象编号(例如read_ptr = 10)。每次中断后,从read_ptr开始,循环读取直到遇到一个NEWDAT为0的对象。每成功读取一个,就将read_ptr加1,如果超过最后一个对象编号(13),则将其重置为起始编号(10)。同时,每次读取前都要正确配置CANIFnCMSK以自动清除状态位。这种软件管理与硬件机制配合,才能实现稳定可靠的FIFO操作。

5. 中断处理与测试模式深度解析

5.1 中断系统的优先级与处理

CAN控制器的中断源分为两类:状态中断消息中断

  • ���态中断:由错误(如总线离线、错误被动)、状态变化(如发送成功、接收成功计数器更新)等触发。它在CANINT寄存器中表现为INTID=0x8000状态中断具有最高优先级
  • 消息中断:由单个消息对象接收或发送完成触发(需配置RXIETXIE)。多个消息中断同时发生时,消息对象编号最小的中断优先级最高

中断处理流程建议:

  1. 进入中断服务程序后,首先读取CANINT寄存器。
  2. 如果INTID == 0x8000,说明是状态中断,应读取CANSTS寄存器以清除中断源,并分析错误/状态码进行处理。
  3. 如果INTID为其他值(1-32),则对应一个具体的消息对象编号。此时,该值就是当前优先级最高的、待处理的消息对象号。
  4. 为了全面了解中断情况,可以额外读取CANMSGnINT寄存器(消息中断挂起寄存器)。这是一个位图,每一位代表一个消息对象是否有中断挂起。这在处理可能同时到达的多个消息时非常有用。
  5. 处理具体消息对象中断时,如前所述,通过配置CANIFnCMSK(设置CLRINTPND)并写入MNUM来读取数据,这个操作会同时清除该对象的INTPND位。
  6. 处理完当前最高优先级中断后,CANINT寄存器会自动更新为下一个优先级最高的挂起中断ID,如果为0则说明所有中断已处理完毕。

5.2 测试模式:开发与调试的利器

CAN控制器的测试模式极大地便利了开发调试,无需连接真实总线即可验证软件逻辑。

  1. 静默模式(Silent Mode)

    • 通过设置CANTST.SILENT位进入。
    • 行为:控制器可以正常接收总线数据,但永远不会发送任何显性位(Dominant Bit)到总线上。这意味着它不会发送ACK应答位、错误帧等。
    • 用途:监听总线流量而不产生任何干扰,是完美的“总线监听器”模式,用于分析网络通信、排查问题。
  2. 环回模式(Loopback Mode)

    • 通过设置CANTST.LBACK位进入。
    • 行为:控制器内部将发送输出(TX)直接连接到接收输入(RX)。自己发送的消息会被自己接收回来(如果通过验收过滤)。它完全忽略外部CAN总线。
    • 用途:自测试。可以验证CAN控制器内核、消息对象配置、中断逻辑等是否正常工作,无需任何外部硬件。
  3. 环回结合静默模式

    • 同时设置LBACKSILENT位。
    • 行为:TX引脚被强制为隐性,RX引脚被断开。控制器在内部进行环回测试,但对外部总线呈现高阻态,毫无影响。
    • 用途:在已连接的真实CAN网络中,安全地对单个节点进行功能测试,完全不影响网络其他部分。
  4. 基本模式(Basic Mode)

    • 通过设置CANTST.BASIC位进入。
    • 行为:绕过消息RAM。CANIF1寄存器直接作为发送缓冲区,CANIF2寄存器直接作为接收缓冲区。没有验收过滤,所有接收到的帧都存入IF2
    • 用途:最底层的调试。当怀疑消息RAM或复杂的状态机逻辑有问题时,可以用此模式验证最基础的收发功能是否正常。它也常用于实现一些非标准的、需要直接操作底层寄存器的通信需求。

注意事项:测试模式切换测试模式通常需要在控制器初始化(Init)但未进入正常工作模式(Normal Operation)之前配置。在某些控制器上,切换测试模式可能需要先使控制器进入复位或配置模式。务必参考具体的数据手册时序要求。此外,TX[1:0]控制位用于直接驱动TX引脚电平,进行物理层测试,但在使用环回、静默等协议相关测试模式时,必须将其清零。

6. 位时序配置:理论、计算与避坑指南

位时序配置是CAN通信稳定的物理基础。配置不当会导致偶尔的错误帧,在仲裁时尤其容易出问题,导致节点误入错误被动状态。

6.1 位时间结构与参数计算

一个位时间(Bit Time)被划分为4段:

  1. 同步段(Sync_Seg):固定为1个时间份额(Time Quantum, tq)。期望的边沿跳变发生在此段内。
  2. 传播时间段(Prop_Seg):用于补偿网络中的物理延迟(总线线缆延迟、收发器延迟等)。
  3. 相位缓冲段1(Phase_Seg1):位于采样点之前,可被同步临时延长。
  4. 相位缓冲段2(Phase_Seg2):位于采样点之后,可被同步临时缩短。采样点(Sample Point)位于Phase_Seg1结束之时。

寄存器配置参数为:

  • BRP(Baud Rate Prescaler): 决定时间份额tq。tq = (BRP) / fsys,其中fsys是CAN控制器的输入时钟频率。
  • TSEG1=Prop_Seg + Phase_Seg1 - 1
  • TSEG2=Phase_Seg2 - 1
  • SJW(Resynchronization Jump Width) =SJW - 1,SJW不能大于Phase_Seg1Phase_Seg2

因此,位时间 = (TSEG1 + TSEG2 + 3) * tq

6.2 配置步骤与实例验证

输入材料提供了1Mbps(高速)和100Kbps(低速)两个经典示例。我们以更常见的1Mbps, CAN时钟25MHz为例,复盘计算过程,并解释每一步的工程考量:

  1. 确定系统参数

    • 目标比特率bit_rate = 1 Mbps-> 位时间t_bit = 1 / 1e6 = 1 µs
    • CAN模块时钟f_can = 25 MHz-> 时钟周期T_can = 40 ns
  2. 计算时间份额tq和BRP

    • 位时间必须是tq的整数倍。通常我们希望tq是时钟周期的整数倍,且整个位时间包含的tq数在4到25之间(协议要求)。
    • 尝试选择BRP=5,则tq = BRP / f_can = 5 / 25e6 = 200 ns
    • 验证位时间所需的tq数:N = t_bit / tq = 1 µs / 200 ns = 5。满足4≤N≤25。
  3. 分配各段tq数

    • Sync_Seg= 1 tq (固定)。
    • 估算物理延迟t_prop_delay。包括收发器环路延迟(高速收发器约50-100ns)、信号在总线上的传播延迟(约5ns/米,假设20米总线约100ns)。这里保守估计总t_prop_delay ≈ 300 ns
    • 将物理延迟转换为tq数:Prop_Seg = ceil(t_prop_delay / tq) = ceil(300ns / 200ns) = 2 tq必须向上取整,确保足够补偿。
    • 剩余tq数给相位缓冲段:Phase_Seg1 + Phase_Seg2 = N - Sync_Seg - Prop_Seg = 5 -1 -2 = 2 tq
    • 通常让Phase_Seg1Phase_Seg2相等或相差1。这里2 tq是偶数,所以Phase_Seg1 = Phase_Seg2 = 1 tq
    • 检查Phase_Seg2是否大于等于信息处理时间IPT(控制器将采样值移入移位寄存器所需时间,通常为0-2 tq)。这里Phase_Seg2=1 tq,假设IPT=0或1,满足要求。
    • 计算SJW:取min(4, Phase_Seg1, Phase_Seg2) = min(4,1,1) = 1 tq
  4. 计算寄存器值

    • TSEG1 = Prop_Seg + Phase_Seg1 - 1 = 2 + 1 - 1 = 2
    • TSEG2 = Phase_Seg2 - 1 = 1 - 1 = 0
    • SJW = 1 - 1 = 0
    • BRP = 5 - 1 = 4
    • 组合成CANBIT寄存器值:TSEG2[3:0] | TSEG1[3:0] << 4 | SJW[1:0] << 8 | BRP[7:0] << 16。根据示例,结果为0x0204

避坑指南:位时序配置的常见问题

  • 采样点过早Prop_Seg估算不足,未能完全补偿物理延迟,在仲裁或噪声环境下容易出错。建议在计算值基础上增加1-2个tq的余量。
  • 采样点过晚Phase_Seg2太短,小于控制器的IPT,可能导致控制器来不及处理当前位。确保Phase_Seg2 >= IPT(通常认为IPT=2是安全的)。
  • SJW设置过小:SJW决定了每次重同步可以调整的最大相位误差。在节点时钟差异较大或噪声环境中,SJW过小可能导致无法有效同步,累积误差最终引发错误。通常设置为Phase_Seg1Phase_Seg2中较小的那个值。
  • 忽略时钟容差:输入材料给出了振荡器容差计算公式。在长距离、多节点、高波特率的网络中,必须确保所有节点的���钟精度(包括晶振误差、温漂等)在计算出的容差范围内。否则,同步机制可能无法弥补时钟差异。

7. 寄存器地图速查与关键操作总结

为了方便参考,下表整理了Tiva CAN控制器最核心的寄存器及其功能摘要。实际开发中,应结合具体型号的数据手册使用。

寄存器名称偏移地址 (CAN0)主要功能描述关键位/字段
CANCTL0x000控制寄存器INIT(初始化模式), IE(全局中断使能), CCE(配置改变使能)
CANSTS0x004状态寄存器LEC(上次错误代码), TXOK/RXOK(成功计数), BOFF(总线离线), EWARN(错误警告)
CANBIT0x00C位时序配置TSEG1, TSEG2, SJW, BRP
CANINT0x010中断标识INTID(中断源编号,0x8000为状态中断)
CANTST0x014测试模式控制BASIC, LBACK, SILENT, TX[1:0]
CANIF1CRQ0x020IF1命令请求MNUM(消息对象编号), BUSY(基本模式忙标志)
CANIF1CMSK0x024IF1命令掩码WRNRD(读写方向), DATAA/B, ARB, CTRL等(选择更新区域)
CANIF1MSK1/20x028/0x02CIF1掩码寄存器MSK[15:0](ID掩码), MXTD, MDIR(扩展ID/方向掩码使能)
CANIF1ARB1/20x030/0x034IF1仲裁寄存器ID[28:0](消息标识符), XTD(扩展标识符), DIR(方向), MSGVAL(消息有效)
CANIF1MCTL0x038IF1消息控制DLC[3:0](数据长度), EOB(缓冲区结束), TXIE/RXIE(发送/接收中断使能), RMTEN(远程帧使能), UMASK(使用掩码), NEWDAT, MSGLST, INTPND, TXRQST(状态位)
CANIF1DA1/2, DB1/20x03C-0x048IF1数据寄存器DATA[7:0] ~ DATA[63:56](8字节数据)
CANTXRQ1/20x100/0x104发送请求寄存器只读,位图显示哪些消息对象的TXRQST被置位。
CANNWDA1/20x120/0x124新数据寄存器只读,位图显示哪些消息对象的NEWDAT被置位。
CANMSG1INT/20x140/0x144消息中断挂起只读,位图显示哪些消息对象的INTPND被置位。

关键操作流程总结:

  1. 初始化:使能CAN模块时钟,将控制器置为初始化模式(CANCTL.INIT=1CANCTL.CCE=1),配置CANBIT位时序,配置消息对象,最后退出初始化模式(CANCTL.INIT=0)。
  2. 发送消息:选择IF寄存器,配置CMSK为写操作并选择数据/仲裁/控制域,在ARB寄存器中设置ID和方向(DIR=1),在MCTL中设置DLC和TXRQST=1,在数据寄存器填入数据,最后写入CRQ触发消息提交。硬件会自动处理发送。
  3. 接收消息(轮询):定期读取CANNWDACANMSGINT寄存器,查看哪些对象有新数据。然后配置CMSK(通常设置CLRINTPND),写入对象编号到CRQ,从接口数据寄存器读取数据。
  4. 接收消息(中断):在消息对象配置中使能RXIE。在全局中断中,读取CANINT获取最高优先级中断源,然后按上述读取流程处理对应消息对象,并清除其中断标志。

掌握消息对象和FIFO的配置,是解锁CAN控制器高级应用的关键。它让你从被动的数据接收者,转变为能够主动、高效、可靠管理通信流量的架构师。希望这篇结合了手册原理与实战经验的详解,能帮助你在下一个汽车电子或工业控制项目中,构建出更加稳健的CAN通信系统。