NXP S32K344芯片FlexCAN模块
文章目录
- NXP S32K344芯片FlexCAN模块
- 资源简介
- FlexCAN模块简介
- 邮箱结构
- EDL 扩展数据长度:
- BRS 位速率选择位:
- ESI 错误状态指示:
- CODE (Message Buffer Code)报文缓冲区码:
- SRR (Substitute Remote Request):
- IDE (ID Extended Bit) ID扩展位:
- RTR (Remote Transmission Request) 远程发送请求位:
- DLC (Length of Data in Bytes) 数据的字节长度:
- TIMESTAMP (Free-Running Counter Time Stamp) 时间戳位:
- PRIO (Local Priority) 本地优先级:
- ID (Frame Identifier) 帧标识符:
- DATA Byte 0-7(Data Field) 数据字段:
- CAN总线标准帧同MB消息缓冲区的有一一对映关系
- CAN总线扩展帧同MB消息缓冲区的有一一对映关系
- 接收过程Rx、Rx FIFO及帧过滤机制Filter
- 通信波特率
- FlexCAN模块初始化
- 发送、接收与匹配过程
- 特殊功能
- 《AUTOSAR谱系分解(ETAS工具链)》之总目录

资源简介
S32K344
以下是S32K344芯片的FlexCAN模块资源一览:
FlexCAN模块简介
FlexCAN 模块是CAN协议的一个高完成度版本,带有动态数据率(Flexible Data rate,CAN FD)协议和 CAN 2.0 B 版本协议,支持标准和拓展数据帧和长达 64 字节的数据传输,频率最大可达到 8Mbps。数据缓冲器存在于中一个嵌入FlexCAN的 RAM 中。
上图为FlexCAN各模块关系,其功能如下:
协议引擎Protocol Engine (PE):
用于管理CAN总线上的串行通讯:请求RAM访问用于接收、发送消息帧;验证接收的消息;运行错误处理;探测CAN FD帧。
控制器主机接口Controller Host Interface (CHI):
用于管理接收、发送的消息缓存邮箱(Message Muffers),负责仲裁和ID匹配。
总线接口单元Bus Interface Unit (BIU):
用于控制访问内部总线,建立与CPU和其他模块的联系。包括时钟、寻址、数据总线、中断、DMA的访问都是通过BIU。
寄存器
FlexCAN外设模块寄存器清单:
地址偏移 | 寄存器 | 寄存器名 | 功能简介 |
---|---|---|---|
0x0000 | CAN_MCR | Module Configuration Register | 配置外设模块的工作模式、功能开关等。 |
0x0004 | CAN_CTRL1 | Control 1 register | 配置外设模块的工作模式、功能开关等,包含位时钟的时钟源。 |
0x0008 | CAN_TIMER | Free Running Timer register | 内部集成的一个16位的计数器,在特定的情况下对位时钟加减计数,一般用不上。 |
0x0010 | CAN_RXMGMASK | Rx Mailboxes Global Mask register | 给旧应用场景使用的,可用于设定MB0-MB13的接收过滤器。新应用大多使用另一种过滤机制。 |
0x0014 | CAN_RX14MASK | Rx Buffer 14 Mask register | 给旧应用场景使用的,专用于设定MB14的接收过滤器。 |
0x0018 | CAN_RX15MASK | Rx Buffer 15 Mask register | 给旧应用场景使用的,专用于设定MB14的接收过滤器。 |
0x001C | CAN_ECR | Error Counter Register | 内含两个8位的错误计数器,分别记录发送错误计数和接收错误计数。 |
0x0020 | CAN_ESR1 | Error and Status 1 Register | 包含了多个错误事件和常规标志位,部分错误标志位可以触发中断。 |
0x0028 | CAN_IMASK1 | Interrupt Masks 1 register | 对应每个MB通信过程(发送或接收)完成是否产生中断的开关。 |
0x0030 | CAN_IFLAG1 | Interrupt Flags 1 register | 对应每个MB通信过程(发送或接收)完成是否产生中断的标志位。 |
0x0034 | CAN_CTRL2 | Control 2 Register | 作为CTRL1的扩展,配置外设模块的工作模式、功能开关等。 |
0x0038 | CAN_ESR2 | Error and Status 2 Register | 附加的错误与标志位。不常用。 |
0x0044 | CAN_CRCR | CRC Register | 外设会自动计算发送帧数据的CRC值,并在发送帧之后通过本寄存器呈现出来。 |
0x0048 | CAN_RXFGMASK | Rx FIFO Global Mask register | 推荐使用FIFO模式管理MB空间。当启用FIFO模式后,本寄存器将用于指定接收帧ID的过滤器掩码。 |
0x004C | CAN_RXFIR | Rx FIFO Information Register | 查看当前FIFO的状态。不常用。 |
0x0050 | CAN_CBT | CAN Bit Timing Register | 专门用于配置位时钟各段的时间长度。 |
0x0080 – 0x017F | CAN_MBn (n=0-15) | Message buffers | MB的内存空间,每个MB占用连续的16个字节,总共16个MB。数据结构见下文。 |
0x0880 – 0x08BC | CAN_RXIMRn (n=0-15) | Rx Individual Mask Registers | 默认不启用FIFO模式时,顾名思义为每个MB指定过滤器。启用FIFO时,指定的是每个“接收FIFO ID过滤器表元素”。数据结构见下文。 |
邮箱结构
S32K344芯片的FlexCAN模块资源:
如下图所示,其具有6个CAN模块,均支持CAN FD。在FULL模式下CAN0~CAN5分别具有96、64与32个邮箱。
FlexCAN 模块使用时报文缓冲区(Message Buffer,MB)结构如下图所示:
FlexCAN外设地址空间的0x0080 – 0x017F之间的地址,被映射到RAM中,用于存放MB的数据结构,每个MB占用连续的16个字节,总共16个MB。 这些MB将用于存放即将向CAN总线发送的帧数据内容,软件需要先把数据填充到MB中再启动发送工程;或者从CAN总线上捕获的CAN数据内容,之后软件就可以从MB中读到接收帧的信息。
地址偏移0h4h为CS控制字段,主要存储报文属性与邮箱状态CODE码。地址偏移4h8h为ID字段,用于存储报文ID或设置接收邮箱的专用ID。
EDL 扩展数据长度:
该位用于区分CAN格式帧和CAN FD格式帧。对于配置为RANSWER的代码字段1010b的消息缓冲区,不能设置EDL位。
BRS 位速率选择位:
该位定义了是否在CAN FD格式帧内切换码率。
ESI 错误状态指示:
该位表示发送节点是错误主动还是错误被动。
CODE (Message Buffer Code)报文缓冲区码:
CPU和FlexCAN外设都可能向这个字段写命令。当CPU向CODE字段中写数,用于向FlexCAN外设配置发送和接收的过程;当FlexCAN外设向CODE字段中写数,用于告知CPU当前发送或接收过程已经完成或者正在进行的状态。关于具体的各种命令以及对应的操作和状态,可进一步参见芯片手册中的表格说明(Table 497 & Table 498)。
接收缓冲区的 MB CODE 如下表:
注1:SRV,表示处理 MB,可通过读 TIMER 或者被其他的 MB 解锁。
注2:如果一个帧被移入 MB,那么可认为该帧被成功的接收了。
注3:来自于 CAN_CTRL2的远程发送请求位。
注4:Code=1010 不被考虑,并且具有该 CODE 的 MB 应该被丢弃。
注5:对于发送 MB 来说,BUSY 应该在读的时候被忽略,除非 CAN_MCR[AEN] 位被置1,如果该位被置1,那么相应的 MB 将不会参与匹配过程。
发送缓冲区的 MB CODE 如下表:
SRR (Substitute Remote Request):
仅用于扩展帧。当表示扩展帧时,必须置1。
远程发送请求替代位。当固定隐性位时,SRR 只能用于扩展帧格式,该位必须由用户将其设置为1来传输,并且和从 CAN 总线上接收到的值一起被存储起来。它可以以隐性位或显性位的形式接收,如果 FlexCAN 以显性位接收,那么认为它是仲裁丢失。当 SRR=1 时,采用隐性位,强制用来以扩展帧模式传输;当 SRR=0 时,采用显性位,对于传输扩展模式是不可用的。
IDE (ID Extended Bit) ID扩展位:
标记是否为扩展帧,1表示扩展帧,0表示标准帧。
该位用来表示是标准帧还是扩展帧。当 IDE=1 时,为扩展帧;当 IDE=0 时,为标准帧。
RTR (Remote Transmission Request) 远程发送请求位:
该位影响远程帧的行为,是接收过滤器的一部分。如果 FlexCAN 传输1或者0,认为它是仲裁丢失。如果该位以0(显性)传输,在接收时为1(隐性),那么 FlexCAN 模块将会认为这是个错误。如果接收到的值与发送值相同,则认为是一次成功的传输。当 RTR=1 时,如果 MB 为发送 MB,那么表示当前的 MB 可能有一个等待发送的远程请求帧;如果 MB 为接收 MB,那么接收到的远程请求帧将会被存储起来;当 RTR=0 时,表示当前的 MB 有一个数据帧等待传输,在接收 MB 中,它可能会被当成匹配过程。
设定或表示当前MB中是否为远程请求帧,1表示远程帧,0表示数据帧。
DLC (Length of Data in Bytes) 数据的字节长度:
发送和接收帧中的数据长度,0表示没有。有效值为1到8。当接收通信帧时,FlexCAN协议引擎会从接收到的帧中提取有效数据填充到数据字段,并复制接收帧的DLC值到MB的DLC字段中。当发送通信帧时,在总线上发送通信帧的字节流时,若DLC小于8,则实际数据负载的字节流长度亦会对应缩短,而不会填充空位。当RTR=1,即发送远程帧时,此时发送数据字段中无有效内容,将会忽略DLC中的值(等价于DLC=0)。
该字段为发送或接收数据的长度。在接收阶段,该字段由 FLexCAN 模块写入,是从接收帧的 DLC(Data Length Code) 字段复制而得到的。在传输阶段,该字段由 MCU 写入,并且会传输与 DLC 值相同的帧长度。当 RTR=1 时,被传输的帧为远程帧且不包括数据字段,不考虑 DLC 字段。下表说明了 DLC 与可用数据字节的对应关系。
TIMESTAMP (Free-Running Counter Time Stamp) 时间戳位:
接收帧时本机填入时间戳,用于本机处理多个MB中的接收帧时判断先后时序。这个字段将由FlexCAN的协议引擎自动填充,从CAN_TIMER寄存器中复制过来。
为自由运行计数器时间戳。这16位是自由运行计数器的备份,用于在当标识符字段的开始出现在 CAN 总线时捕捉传输或者接收帧。
PRIO (Local Priority) 本地优先级:
对本机多个MB的发送帧执行仲裁(而不是总线上的设备,CAN总线对设备没有优先级的概念),使用唯一的发送引擎按优先级逐个发送。这个字段的值不会被发送到CAN总线上,可以被附加到常规的ID后面,作为一个配置项,当CAN_MCR[LPRIO_EN]=1时生效,仅作用于发送过程中的多个MB之前进行排序。
该位只有当 CAN_MCR[LPRION_EN] 位置1时才有用,并且只对传输报文缓冲区有效。这些位不会被传输,他们经常被附加到 ID 来定义传输的优先级。
ID (Frame Identifier) 帧标识符:
在标准帧的格式中,只用到收发通信帧的高11位(28b – 18b),后续的低18位被忽略。当使用扩展帧时,整个29位的字段全部用于表示通信帧的ID。话说,标准帧和扩展帧的区别就在于ID字段的位数,扩展帧使用更多位的ID,可以在总线系统中表示更多的通信帧类型。
在标准帧格式中,只有11位,高位比特(28到18)用来标识接收或者发送的帧,低18位将会被忽略;在扩展帧格式内,所有的位都用来标识传输或者接收的数据帧。
DATA Byte 0-7(Data Field) 数据字段:
通信帧的有效数据负载。最多8字节,同DLC字段描述的数据字节数对应。当为发送帧时,由CPU写入数据到本字段,供FlexCAN引擎发送到总线上;当为接收帧时,FlexCAN的协议引擎会在总线上捕获到数据帧后,自动复制值到本字段,供CPU读取。
最多64字节可用于数据帧。对于接收到的数据帧,以被接收时的格式进行存放。DATA BYTEn 只有当 n 小于 DLC 的值时才有效。对于传输数据帧,该字段用来表示发送的数据帧的长度。
CAN总线标准帧同MB消息缓冲区的有一一对映关系
如下图所示:
CAN总线扩展帧同MB消息缓冲区的有一一对映关系
CAN总线扩展帧相对于标准帧,多了SRR的字段,但仍同MB消息缓冲区有一一对映的关系,如下图所示:
接收过程Rx、Rx FIFO及帧过滤机制Filter
相对于默认的将每个MB作为一个单独的通道,一帧一帧地接收并处理数据,FIFO模式可以将几个MB的存储空间组织成一个FIFO,FIFO可以缓存更多的帧,在CPU提供同等算力的情况下,提升节点设备的处理CAN总线通信帧的动态吞吐率。
FIFO结构
当配置CAN_MCR[RFEN]=1时,启用Rx FIFO模式,此时,原MB列表的部分MB存储区域(MB0 – MB5,模块内偏移地址为0x80 – 0xDC的内存区域)将合并成Rx FIFO,由FIFO引擎管理。其中,原MB0的作为CPU访问Rx FIFO的接口,CPU始终可以从原MB0的位置读到最早进入FIFO的帧信息。此时,Rx FIFO的区域为只读模式,复位缺省值为0x00。
另外,还可以通过配置CAN_CTRL2[RFEN]=1,启用Rx FIFO的另一段区域,这个FIFO对应于原MB6 – MB15的区域(模块内偏移地址为0xE0 – 0x17C的内存区域,将用于存放Rx FIFO的ID过滤器表,只有通过ID过滤器表中的表项匹配的CAN通信帧才能被捕获进入Rx FIFO。ID过滤器表可能有多种模式(匹配不同的位数),可被配置为8至40个表项。复位FlexCAN外设模块后,ID过滤器表的内存区域的默认为从0xE0至0xFC,对应使用原MB6和MB7的空间,同未开启Rx FIFO模式的配置兼容。
Rx FIFO的数据结构:
其中,每个ID过滤器表项(ID Filter Table element)占用32位字的空间,可以被分成1个32位、2个16位或4个8位的匹配接收掩码(IDAF,Identifier Acceptance Filters),这需要在CAN_MCR[IDAM]寄存器中设置。图x中展示了这种可能使用多种格式分割ID过滤器表项的格式,但要特别注意,一旦选定一种格式,所有的ID过滤器表项都会使用同一种格式。
下图展示FlexCAN ID过滤器表项的格式:
其中,各配置字段的含义如下:
RTR (Remote Frame):
指定能否捕获匹配ID的远程帧。1指定可以捕获,0指定不捕获。
IDE (Extended Frame):
指定能否捕获匹配ID的扩展帧。1指定可以捕获,0指定不捕获扩展帧,仅捕获标准帧。
RXIDA/B/C (Rx Frame Identifier with Format A/B/C):
指定匹配的ID模式,当不满足完整的帧ID时,仅匹配帧的高位。
FIFO中MB结构中多出来的IDHIT (Identifier Acceptance Filter Hit Indicator):
表示当前的MB匹配到了哪个ID过滤器。
功能描述
Rx FIFO将6个MB的内存空间整合成一个FIFO,使用FIFO引擎管理先后收到的数据帧。相对于老式的单独管理各个MB,FIFO模式对DMA应用比较友好,并且可以提升从CAN总线上捕获帧的动态吞吐率。
CAN_IFLAG1[BUF5I]标志位,表示Rx FIFO中已经捕获到有效的数据帧,可供CPU读取。这个标志位也可以触发中断,CPU在中断服务程序中读取Rx FIFO的内容后,FlexCAN外设会更新FIFO状态寄存器CAN_RXFIR的值,然后自动清中断标志。如果Rx FIFO中有多个有效的数据帧,则CAN_IFLAG1[BUF5I]会持续置位,触发CPU处理接收帧的过程,直到Rx FIFO中捕获的通信帧全部被读走。
CAN_IFLAG1[BUF6I]标志位,表示Rx FIFO达到警告门限,此时Rx FIFO中已经积压了4个MB(从5个MB读走1个后剩下4个MB的时机),此时意味着Rx FIFO几乎要满到溢出了。这个标志位需要CPU清除。
CAN_IFLAG1[BUF7I]标志位,表示Rx FIFO已经满溢,此时Rx FIFO中已经积压了6个未读的MB,并且有一个新的CAN通信帧被捕获下来。这个标志位需要CPU清除。
CAN_IFLAG1[BUF0I]标志位,可用于清空Rx FIFO。当CPU向该标志位写1时,直接清空Rx FIFO。但这个功能仅在冻结模式下使用,这就意味着,用户不要试图在FlexCAN正常工作的情况下清空Rx FIFO(可以软件读掉Rx FIFO中的数据),这个功能大多用于改变全局配置时,重新初始化FlexCAN模块时使用。
FlexCAN模块中设计了功能强大(略显复杂)的帧过滤器模式,可以由硬件自动过滤掉很多本设备处理不了的帧,这就节约了很多原本需要在接收中断服务程序中判断捕获帧是否能在本机处理的过程。FlexCAN可以同时匹配众多的ID帧标识符,128个Format A格式的IDAF,或者256个Format B格式的IDAF,或者512个Format C格式的IDAF。每个捕获到Rx FIFO中的接收帧都有一个对应的IDHIT,指示它匹配到的过滤器的索引编号,CAN_RXFIR[IDHIT]寄存器字段中也能查看最近捕获的接收帧的IDHIT值。此时,需要在清接收标志之前读CAN_RXFIR寄存器,以确保存放在CAN_RXFIR寄存器中的值不会被后面捕获到帧覆盖掉。
当配置CAN_CTRL2[RFEN]=1时,启用过滤器表,过滤器表中最多可以有16个表项,可以由独立掩码寄存器CAN_RXIMRx分别配置。当CAN_MCR[IRMQ]=0时,过滤器表由CAN_RXFGMASK寄存器配置。
接收过程
为了能让FlexCAN从CAN总线上捕获到通信帧,CPU(软件)需要准备一些工作:
- 如果选定的MB处于激活状态,正在发送或接收,要么等等,要么强行终止,确保MB处于一个可用的非激活状态
- 向MB中写入希望捕获通信帧的ID值。
- 向MB的CODE字段中写入EMPTY(0b0100),激活接收过程。
当MB被激活后,它将会接收到通过ID过滤器匹配的通信帧。
当接收过程成功完成后,FlexCAN外设通过搬运过程将捕获到的通信帧从CAN通信引擎的缓冲中转运至MB中:
接收到通信帧的数据(8字节)将被存放至MB的DATA字段。
接收到的ID将被存放至MB的ID字段。
接收时刻的定时器CAN_TIMER寄存器的值将被写入到MB的时间戳字段中。
MB中的SRR、IDE、RTR和DLC字段将被更新。
MB中的CODE字段中的状态将被更新。
CAN_IFLAG1中的接收中断标志位将会置位,如果在CAN_IMASK1寄存器中启用了对应的中断,也将会触发中断。
因此,建议CPU(软件)在读取CAN接收帧时,遵循如下步骤:
- 先读一下对应MB的状态位,再看一下BUSY标志位是否置位,若置位,意味着MB被锁着,先等一等。
- 从MB中读数据。但如果MB被锁着,MB中的数据实际是无效的。
- 清IFLAG标志位。
- 读时间戳。
建议当收到CAN接收帧时,尽快把收到的帧读走,解锁MB,为后面接收的帧释放空间。
特别注意的是,在CPU通过轮询过程查看FlexCAN‘释放捕获到接收帧的过程中,应当以CAN_IFLAG1寄存器中的标志位来判定,而不是MB中CODE字段的状态码。读CODE状态码是没有意义的,因为一旦FlexCAN收到通信帧后被CPU读走,CODE不会变为EMPTY,而是仍保持为FULL,需要CPU人为清空。
若是使用FIFO模式,CPU需要在FlexCAN的冻结模式下配置启用Rx FIFO模式,再次启用FlexCAN通信引擎后,FlexCAN将以Rx FIFO模式捕获CAN通信帧:
- 读CAN_IFLAG中的Rx FIFO的接收标志位
- 读Rx FIFO头部MB的接收帧ID
- 读Rx FIFO头部MB的数据负载(8字节)
- 读CAN_RXFIR寄存器
- 写1清Rx FIFO捕获到有效帧的标志位CAN_IFLAG[BUF5I]。
Rx FIFO对使用DMA的场景更友好。但目前的ECU系统中,因为附加了协议栈和大量的软件干预,所以实际使用DMA的并不多。如果需要,也可以参见芯片用户手册的相关说明。
发送过程Tx和仲裁机制
发送过程
当要发送一个CAN通信帧,CPU需要选出一个MB,然后执行如下的步骤:
- 查看当前CAN通信引擎是否正忙,如果正忙就等一等,或者通过硬件机制终止通信过程。是否有之前通信过程的遗留标志位,如果有就清零。务必确保CAN通信引擎恢复成初始状态:
- 确保发送中断和接收中断都是停用的。
- 如果选用的MB是激活的(Active),正在被占用,可以通过向该MB的CODE字段中写入ABORT命令字(0b1001)终止通信过程。
- 通过轮询CAN_IFLAG寄存器中对应的IFLAG标志位置位,或者启用中断触发,等待MB转入非激活状态。
- 再读MB的CODE字段,确认发送过程已经被中断或者完成。
- 清除对应的中断标志位。
- 向MB中写入通信帧:
- 写入消息ID。如果通过配置CAN_MCR[LPRIO_EN]=1寄存器启用了本地优先级配置,还需要一并写入PRIO配置字段。
- 写入数据负载。最多8个字节的数据。
- 配置发送属性,包括:IDE、RTR、DLC。
- 在CODE字段中写入激活命令码,对应发送帧,CODE=0xC。
当MB被激活之后,它被加入到FlexCAN外设的发送仲裁过程,根据本地优先级(若有),最终被发送到CAN总线上。
在发送过程成功完成后:
定时器CAN_TIMER寄存器的时间戳将被写入到本MB的时间戳字段中。
CODE字段中的值将被FlexCAN外设更新。至于更新成什么状态,需要根据具体发送的情况确定。见表x所示。
在CAN_IFLAG1寄存器中的发送完成中断标志位会置位,
如果在CAN_IMASK1寄存器中启用了发送完成中断,那么对应的中断也会被触发。
注意,当通过CAN_MCR[AEN]启用了终止通信的功能后,当发送完整中断标志位置位时,此时MB是被锁住的,需要CPU清中断标志位后,才能再次访问MB,准备写入下一个新的通信帧。
仲裁过程
此处的仲裁过程并不是指CAN总线网络的仲裁机制,而是FlexCAN外设本身的多个通信通道(MB)争用同一个通信引擎发送至CAN总线上的过程。FlexCAN会扫描当前所有待发送的MB,然后根据特定的策略选出其中一个作为本次发送过程的MB。这个策略是可以通过寄存器配置的,如表x所示。
表x 配置发送仲裁优先级策略
CAN_CTRL1[LBUF] | CAN_MCR[LPRIOEN] | 仲裁策略 |
---|---|---|
1 | – | 当CAN_CTRL1[LBUF]置位时,CAN_MCR[LPRIOEN]的配置无效。此时编号小的发送MB拥有更高优先级。 |
0 | 1 | 当CAN_MCR[LPRIOEN]置位时,可以通过配置MB中的3b位宽PRIO字段,更小的值对应更高的优先级。 |
关于仲裁的过程,还有更多的细节,例如,当某个MB被激活发送过程后,如果长时间得不到仲裁优先级,也将会产生一些报警,此时,判断超时和报警的机制,在FlexCAN外设模块上有一些具体的实现策略。这些内容可以根据具体问题具体分析,在遇到具体场景时,再查阅手册一一对症。此处就不做赘述了。
通信波特率
CAN模块进行通信需要相同的波特率才可以进行正常的通信。在CAN的底层协议里,CAN数据的每一位时间(CAN Bit Time)被分为若干份时间,其组成为:
位同步时间(Tsync)、时间段1(Tseg1 = PROPSEG + PSEG1 + 2)、时间段2(Tseg2 +1)
- 1
位同步时间固定为1份,时间段1与时间段2可在一定范围内调整。
符合博世CAN 2.0B标准的位段设置范围如图所示:
注意一点:
在设置时间位段数量时,必须要确保位时间设置符合CAN协议标准(ISO 11898-1)。
当确定了位段时间数量后,通过计算单位时间的长度Tq即可知道CAN单帧时间,进而可以得到波特率。CAN模块的时钟设置这里不再介绍。
波特率设置公式如下:
根据下图所示,SYNC+SEG+(PROP_SEG+PSEG1+2)+(PSEG2+1)就是总的Tq,因此FlexCAN 的波特率就是CAN时钟频率除以Tq的数量:
如上图所示,采样点位于 Tseg1与Tseg2之间。计算方式为:
例如,假设Tsync = 1,Tseg1 = 14,Tseg2 = 5。那么采样点为:
MCAL中的TimeSegments配置代码:
/*!
* @brief Sets the FlexCAN time segments for setting up bit rate.
*
* @param base The FlexCAN base address
* @param timeSeg FlexCAN time segments, which need to be set for the bit rate.
*/
static inline void FlexCAN_SetTimeSegments(FLEXCAN_Type * base, const Flexcan_Ip_TimeSegmentType * timeSeg)
{
#if (FLEXCAN_IP_DEV_ERROR_DETECT == STD_ON)
DevAssert(timeSeg != NULL_PTR);
#endif
(base->CTRL1) = ((base->CTRL1) & ~((FLEXCAN_CTRL1_PROPSEG_MASK | FLEXCAN_CTRL1_PSEG2_MASK |
FLEXCAN_CTRL1_PSEG1_MASK | FLEXCAN_CTRL1_PRESDIV_MASK
) | FLEXCAN_CTRL1_RJW_MASK
)
);
(base->CTRL1) = ((base->CTRL1) | (FLEXCAN_CTRL1_PROPSEG(timeSeg->propSeg) |
FLEXCAN_CTRL1_PSEG2(timeSeg->phaseSeg2) |
FLEXCAN_CTRL1_PSEG1(timeSeg->phaseSeg1) |
FLEXCAN_CTRL1_PRESDIV(timeSeg->preDivider) |
FLEXCAN_CTRL1_RJW(timeSeg->rJumpwidth)
)
);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
FlexCAN模块初始化
对于FlexCAN模块的设置,初始化或更改配置都需要将FlexCAN设置为Freeze模式。注意,每次重置后都需要初始化模块。
下面是FlexCAN模块的通用初始化步骤:
初始化模块配置寄存器(MCR)。
- 通过设置IRMQ启用每MB单独过滤和接收队列特性。
- 通过设置WRNEN使能警告中断。
- 如果需要,可以通过设置SRXDIS来禁用帧自接收。
- 通过配置RFEN使能Legacy Rx FIFO,通过配置ERFEN使能Enhanced Rx FIFO
- 如果使能了Legacy Rx FIFO或Enhanced Rx FIFO且需要使用DMA,则需要设置DMA。
- 通过设置AEN使能终止机制。
- 通过设置LPRIOEN使能本地优先级特性。
初始化控制1寄存器(CTRL1)和CAN位定时寄存器(CBT)。
如果使用CANFD,还需要初始化CAN FD、CAN位定时寄存器(FDCBT):
- 确定位定时参数:PROPSEG、PSEG1、PSEG2和RJW。
- 可选择位定时参数:EPROPSEG、EPSEG1、EPSEG2、ERJW。
- 确定CAN FD位定时参数:FPROPSEG、FPSEG1、FPSEG2、FRJW。
- 通过编程PRESDIV字段和可选的EPRESDIV字段来确定比特率。
- 通过编程FPRESDIV字段确定CAN FD比特率。
- 确定内部仲裁方式(LBUF)。
如果ECC (Error Code Correction)使能,必须初始化所有FlexCAN内存。
初始化邮箱。
- 所有邮箱的CS字段必须初始化。
- 如果使能了Rx FIFO,则需要对ID过滤表进行初始化。
- 每个邮箱中的其他条目应根据需要初始化。
初始化Rx单个掩码寄存器(RXIMRn)。
设置所需的中断掩码位
- IMASK寄存器 (用于所有邮箱中断)
- CTRL1 / CTRL2寄存器 (用于总线断开和错误中断)
将MCR(HALT)失能。
在完成上面的初始化步骤后,FlexCAN将会尝试同步到CAN总线。
发送、接收与匹配过程
发送过程
要想传输一条消息,需要准备一个消息缓冲区(MB),然后执行以下步骤:
- 检查相应的中断位是否设置,同时清除中断标志。
- 检查邮箱是否为活动邮箱,如果邮箱是活动的,将中止代码(1001b)写入CODE字段,请求中止 该邮箱传输。
- 等待相应的IFLAG位变化。再次读取CODE字段,检查确认传输是否被中止。
- 清除相应的中断标志。
- 向ID段寄存器写入ID。
- 写入数据字节(DATA)。
- 向CS字段写入控制配置。
a. MB_CS[IDE] ——设置报文ID。
b. MB_CS[RTR] ——设置远程传输请求帧(如果需要的话)。
c. MB_CS[DLC] ——设置数据长度,以字节为单位。
d. MB_CS[CODE] ——设置邮箱CODE字,激活邮箱并发送。
在程序中,建议将CS字段中的所有配置只配置在一次32位写操作中,可以提高性能。如果是单独写入,CS[CODE]必须是C/S字中最后一个写入。
当邮箱被激活时,它会参与仲裁过程,并最终根据它的优先级进行传输。在成功发送之后:
- 运行计时器的值会被写入时间戳Time Stamp字段。
- 更新CS字段中的CODE字。
- 更新CRC和FDCRC寄存器
- 在中断标志寄存器中设置中断标志。
- 如果相应的中断掩码寄存器位允许,产生中断。
接收过程
对于Can消息的接收,可以采用以下的方式完成消息接收功能,具体步骤如下:
- 首先检查邮箱是是否为活动邮箱(CODE为0100b),若是活动邮箱需要将邮箱停用(CODE段置0000b),建议使用安全停用邮箱的方式进行停用。
- 将ID字段写入邮箱。
- 将EMPTY代码(0100b)写入邮箱CS字段中CODE位以激活邮箱。CS段内的EDL、BRS和ESI位不需要设置,它们会被接收到的CAN报文中各自对应的位字段覆盖掉。
- 在邮箱被激活后,它将能够接收到与程序设置的滤波器(MASK)相匹配的帧。在成功接收结束时,邮箱将通过移入过程更新(由FlexCAN模块执行,此更新过程CODE[0]=1,CPU无法访问)。
当FlexCAN成功接收CAN消息并移入对应邮箱后,官方参考手册中建议的CPU处理(读取)邮箱接收到的帧的方法如下:
- 读取该邮箱的控制和状态字(CS字段)。
- 检查BUSY位是否被取消(CODE[0]),表示邮箱被锁定。在中断时重复步骤1。
- 读取邮箱的内容。在邮箱被锁定后,邮箱内容将不会被FlexCAN的Move-in进程修改。
- 在IFLAG寄存器确认标志位状态。
- 读取空闲运行计时器以解锁邮箱。
- 匹配过程
待补充
特殊功能
邮箱锁机制
除了邮箱失活以外,FlexCAN还有另一种在接收过程中保护数据一致性的机制。当CPU读取如果一个接收邮箱(Rx MB)的CS字段中CODE代码为FULL或OVERRUN时。FlexCAN假设CPU想要在一个操作中读取整个MB。因此,它为该MB设置了一个内部锁标志。当CPU读取空闲运行计时器(全局解锁操作)时,或者当它读取另一个MB的CS字段时,不管它的代码是什么,锁就会被释放。CPU写入C/S字也会解锁MB,但这个过程不建议用于普通解锁,因为它会取消正在处理的移入过程,可能会丢失接收到的消息。当CPU正在读取邮箱时,邮箱锁机制可以防止新接收到的帧写入邮箱。
邮箱锁定机制只适用于不属于Legacy Rx FIFO的接收邮箱,并且与CODE字段中INACTIVE (0b0000)或EMPTY[1] (0100b)代码功能不同。注意,发送邮箱不能被锁定。
举个例子:假设Legacy Rx FIFO功能被禁用,2号邮箱与5号邮箱使用相同的ID,且FlexCAN已经接收并存储CAN消息到这两个邮箱中。
假设现在CPU决定读取5号邮箱,同时另一条具有相同ID的信息到达。当CPU读取5号邮箱的控制状态字,这个邮箱就会被锁定。当新消息到达时,FlexCAN匹配算法发现没有空闲的接收邮箱,因此它决定覆盖5号邮箱。但是5号邮箱是锁定的,因此不能在5号邮箱写入新消息。它将留在Rx SMB(临时RX邮箱)中,等待邮箱被解锁,然后才会被写入邮箱。
如果MB没有及时解锁,而另一个具有相同ID的新消息到达,那么新消息将覆盖Rx SMB上的消息,在MB的CODE字段或CS字段中都不会有丢失消息的指示。此时Rx SMB中丢失的消息将不会有任何的提示。当消息从Rx SMB移动到MB时,将置位CODE字段上的BUSY位。当CPU读取CS字段发现BUSY位显示正忙,应推迟访问邮箱,直到BUSY位被取消。
MCR[SRXDIS] 自接收功能
在MCR寄存器中,具有一个可以设置自接收功能的位。这个位定义了是否允许FlexCAN接收自己传输的帧(自发自收)。如果这个位被设置启用,不管邮箱是否被设置为与发送帧相匹配的ID,FlexCAN模块发送的帧都不会被存储在任何MB中。而且,信息帧的接收不会产生中断标志或中断信号。注意,这个位只能在冻结模式下进行写入。
0b /* 启用自接收 */
1b /* 自接收被禁用 */
- 1
- 2
评论记录:
回复评论: