ZYNQ CAN总线之CAN ID过滤器分析

ZYNQ CAN 总线学习总结

参考链接:
https://www.uisrc.com/portal.php?mod=view&aid=73

CAN基础知识总结

在这里插入图片描述

帧的种类

通信是通过以下 5 种类型的帧进行的。
• 数据帧
• 遥控帧
• 错误帧
• 过载帧
• 帧间隔
另外,数据帧和遥控帧有标准格式和扩展格式两种格式。标准格式有 11 个位的标识符(Identifier: 以下称 ID),扩展格式有 29 个位的 ID。
各种帧的用途如表 7 所示,各种帧的构成如图 11~图 15 所示
在这里插入图片描述
在这里插入图片描述

波特率

根据CAN规范,位时间被分成4个时间段:同步段(Sync_Seg)、传播时间段(Prop_Seg)、相位缓冲段1(Phase_Seg1)和相位缓冲段2(Phase_Seg2)

每个段由具体、可编程数量的时间份额(time quanta)组成,时间份额是位时间的基本时间单元,它的长度(tq)由CAN控制器的系统时钟(fcan)和波特率预分频器BRP定义:tq=BRP/fcan
CAN模块的系统时钟fcan是其CAN模块时钟(CAN_CLK)输入的频率。
在这里插入图片描述

其中位同步时间占用1个Tscl;时间段2占用(Tseg1+1)个Tscl;时间段2占用(Tseg2+1)个Tscl,所以CAN控制器的位时间(TBit)就是:TBit=Tseg1+Tseg2+Tsync=(TSEG1+TSEG2+3)*Tscl,那么CAN的波特率 (CANbps)就是1/TBit。
但是这样计算出的值是一个理论值。在实际的网络通信中由于存在传输的延时、不同节点的晶体的误差等因素,使得网络CAN的波特率的计算变得复杂起来。CAN在技术上便引入了重同步的概念,以更好的解决这些问题。这样重同步带来的结果就是要么时间段1(Tseg1)增加TSJW(同步跳转宽度SJW+1),要么时间段减少TSJW

CAN有波特率的值四以下几个元素决定:
A. 最小时间段Tscl;
B. 时间段1 TSEG1;
C. 时间段2 TSEG2;
D. 同步跳转宽度 SJW
那么Tscl又是怎么计算的呢?这是总总线时序寄存器中的预分频寄存器BRP派上了用场,Tscl=(BRP+1)/FVBP。FVBP为微处理器的外设时钟。
而TSEG1与TSEG2又是怎么划分的呢?TSEG1与TSEG2的长度决定了CAN数据的采样点,这种方式允许宽范围的数据传输延迟和晶体的误差。其中TSEG1用来调整数据传输延迟时间造成的误差,而TSEG2则用来调整不同点节点晶体频率的误差。但是他们由于过于灵活,而使初次接触CAN的人有点无所适从。TSEG1与TSEG2的是分大体遵循以下规则: Tseg2≥Tscl2,Tseg2≥2TSJW,Tseg1≥Tseg2
总的来说,对于CAN的波特率计算问题,把握一个大的方向就行了,其计算公式可了规结为: BitRate = Fpclk/( (BRP+1) * ((Tseg1+1)+(Tseg2+1)+1)

采样时间

除了波特率之外,CAN接口还有1个重要的参数就是单bit数据的采样时间。采样时间通常用采样点时间位于整个bit时间内的百分比来表示。

   (Sync_Seg+ Prog_Seg+ Phase_Seg1)/( Sync_Seg+ Prog_Seg+ Phase_Seg1+ Phase_Seg2)
  如下图所示,采样点位置为(1+1+4)/(1+1+4+2)=75%。 

在这里插入图片描述

与采样时间相关的有如下几个重要参数。
在这里插入图片描述

确定Prog_Seg、Phase_Seg1、Phase_Seg2 、SJW的值需要遵循如下几个原则:

Sync_Seg、Prog_Seg、Phase_Seg1和 Phase_Seg2的总和在8~25之间。
Phase_Seg2应该取Phase_Seg1和信息处理时间二者中的最大值。
SJW取Phase_Seg1和4中的最小值。
Phase_Seg2≥SJW,Phase_Seg1≥SJW。
Phase_Seg1+Phase_Seg2为偶数时Phase_Seg1=Phase_Seg2 ,Phase_Seg1+ Phase_Seg2为奇数时Phase_Seg1+1=Phase_Seg2。

广州周立功作为国内CAN产品的领先者,使用了CiA CANopen的建议值,即采样时间为87.5%,SJW=1 tq。因此,我们以此作为CAN接口的设计参考标准。

ZYNQ系列CAN控制器

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

Message Format

The same message format is used for RxFIFO and Tx (FIFO and HPB). Each message includes four words (16 bytes). Software must read and write all four words regardless of the actual number of data bytes and valid fields in the message.
The message words, fields and structure are shown in Table 18-2. The details of each field are in
Table 18-3.

在这里插入图片描述

Bit Field Details

Writes
If a bit field or data byte is not required, then write zeros. Software should write the default values . shown in Table 18-3 for unused functions.
Reads
Data starts at byte 0 and continues for the number of counts in DLC. Software should read both data words, but the only valid bytes are determined by DLC.
Table 18-3 provides bit descriptions for the identifier word bits, the DLC word bits, and data word 1 and data word 2 bits.

在这里插入图片描述
在这里插入图片描述

ZYNQ CAN总线之CAN ID过滤器分析与设置

CAN报文标识符:并不代表节点的地址, 而是和报文的内容有关 发送者以广播的形式发送消息 ,节点在接收报文时根据标识符(CAN ID)决定是否需要该报文, 如果需要则拷贝到SRAM中 不需要则丢弃实现硬件过滤 节省CPU开销。

详细介绍参考 ug585–page566, Rx Message Filtering

下面对其进行翻译整理:
要筛选Rx消息,请配置并启用最多四个带有接受掩码和ID寄存器的接受过滤器,以确定是在RxFIFO中存储消息,还是确认并丢弃它们。验收过滤按以下顺序进行:
1.传入的标识符被接受过滤器掩码寄存器中的位屏蔽。
2.验收过滤器ID寄存器也被验收过滤器掩码寄存器中的位屏蔽。
3.并对这两个结果值进行了比较。
4.如果这两个值都相等,则该消息将存储在RxFIFO中。
5.验收过滤器由每个已定义的过滤器进行处理。如果传入的标识符通过任何接受过滤器,则该消息将存储在RxFIFO中。

验收过滤器启用
验收过滤器寄存器(AFR)定义了要使用哪些验收过滤器。它包括对应于四个接受过滤器的四个启用位。每个验收过滤器ID寄存器(AFIR)和验收过滤器掩码寄存器(AFMR)对都与使用验收过滤器(UAF)位相关联。
当UAF位为1时,使用相应的验收滤波器对进行验收滤波。
当UAF位为0时,对应的验收过滤器对不用于验收过滤。
要在正常模式下修改接受滤波器对,该寄存器中相应的UAF位必须首先设置为0。修改接受过滤器后,必须将相应的UAF位设置为1,才能启用过滤器。
CAN中的UAF位。AFR寄存器启用Rx接受过滤器:
如果所有UAF位都设置为0,那么所有接收到的消息都存储在RxFIFO中。
如果在接收CAN消息时,UAF位从1更改为0,则该消息将不会存储在RxFIFO中。

如果任何已启用的过滤器(最多4个)满足此等式,那么Rx消息将存储在RxFIFO:
If (AFMR & Message_ID) == (AFMR & AFIR) then Capture Message
每个验收过滤器都是独立启用的。过滤器是由CAN.AFR寄存器选择。
• Set can.AFR[UAF4] = 1 to enable AFMR4 and AFID4.
• Set can.AFR[UAF3] = 1 to enable AFMR3 and AFID3.
• Set can.AFR[UAF2] = 1 to enable AFMR2 and AFID2.
• Set can.AFR[UAF1] = 1 to enable AFMR1 and AFID1.

如果所有 can.AFR[UAFx] 被设置为0,然后所有接收到的消息都存储在RxFIFO中。UAF位在传入消息开始时由硬件进行采样。

验收过滤器掩码
验收过滤器掩码寄存器(AFMR)包含用于验收过滤的掩码位。将消息帧的传入消息标识符部分与存储在接受过滤器ID寄存器中的消息标识符进行比较。掩码位定义存储在接受过滤器ID寄存器中的哪些标识符位与传入的消息标识符进行比较。有四个afmr。这些寄存器被存储在一个存储器中。如果内存未初始化,从AFMR返回‘X。断言软件重置或硬件重置不会清除寄存器内容。这些寄存器只有在CAN.AFR =0 和CAN,SR=0 时可以被读取和写入。
控制AFMRs的条件如下:
Extended Frames
All bit fields (AMID [28:18], AMSRR, AMIDE, AMID [17:0] and AMRTR) need to be defined.
Standard Frames
Only AMID [28:18], AMSRR and AMIDE need to be defined. AMID [17:0] and AMRTR should be written as 0.

验收过滤器标识符
验收过滤器ID寄存器(AFIR)包含用于接受过滤的标识符位。有四个验收过滤器ID寄存器。这些寄存器可以从中读取和写入到。只有当SR中对应的UAF位为0,而SR中的ACFBSY位为0时,才应该写入这些寄存器。
AFIRs的使用符合以下条件:
Extended Frames
All the bit fields (AIID [28…18], AISRR, AIIDE, AIID [17:0] and AIRTR) must be defined.
Standard Frames
Only AIID [28:18], AISRR and AIIDE need to be defined. AIID [17:0] and AIRTR should be written with 0.

用户必须确保对标准帧和扩展帧的IDE位进行正确的编程。如果用户将AMIR中的IDE位设置为0,则认为它仅是一个标准的帧ID检查。

Example: Program Acceptance Filter
每个验收过滤器都有自己的掩码,CAN.AFMR{1、2、3、4},和ID寄存器,CAN,AFIR{1,2,3,4}.

1. Disable acceptance filters. Write 0 to the can.AFR register.
2. Wait for filter to be not busy. Poll on can.SR[ACFBSY] for 0.
3. Write a filter mask and ID. Write to a pair of AFMR and AFIR registers (refer to the example 
below).
4. Write additional filter masks and IDs. Go to step 2.
5. Enable one or more Filters. To enable all filters, write 0x0000_000F to the can.AFR register.

Program the AFMR and AFIR Registers
The valid fields for sending Tx messages to the controller are summarized in Table 18-5. These fields are described in section 18.2.2 Message Format.
在这里插入图片描述
在AFMR掩码寄存器中,通过向位字段写入一个1,从而为传入的Rx CAN消息的每个字段启用(解除掩码)的比较函数。在AFIR寄存器中,写入要与即将到来的Tx CAN消息进行比较的值。

示例:为标准帧的AFMR和AFIR进行编程

本示例为标准帧设置接受过滤器。帧ID号显示为0x5DF,但可以设置为应用程序所需的值。

1. Configure filter mask for standard frames. Write 0xFFF8_0000 to the can.AFMR register:
a. Enable the compare for the standard message ID, [AMIDE] = 1.
b. Compare all bits in the standard message ID, [AMIDH] = 0x7FF.
c. Enable the compare for substitute remote transmission request, [AMSRR] = 1.
d. Zero-out the extended frame bits, [AMIDL, AMRTR] = 0.
2. Configure filter ID for standard frames. Write 0xABC0_0000 to the can.AFIR register:
a. Select the standard frame message mode, [AIIDE] = 0.
b. Program the standard message ID, [AIIDH] = 0x55E.
c. Disable substitute remote transmission request, [AISRR] = 0. 
d. Zero-out extended frame bits, [AIIDL, AIRTR] = 0.

示例:为扩展帧的AFMR和AFIR进行编程

本示例为扩展帧设置接受过滤器。帧ID号显示为0x5DF,但可以设置为应用程序所需的值。

1. Configure filter mask for extended frames. Write 0xFFFF_FFFF to the can.AFMR register:
a. Enable the substitute remote transmission request mask for frame, [AMSRR] = 1.
b. Compare all bits in the compare for the standard message ID, [AMIDH] = 0x7FF.
c. Enable the extended frame, [AMIDE] = 1.
d. Extended ID, [AMIDL] = 0x3FFFF
e. Remote transmission request bit for extended frame, [AMRTR] = 1.
2. Configure filter ID for extended frames. Write 0xABDF_9BDE to the can.AFIR register:
a. Standard ID, [AIIDH] = 0x55E.
b. Remote transmission request bit for standard frame, [AISRR] = 1.
c. Select standard/extended frame, [AIIDE] = 1.
d. Extended ID, [AIIDL] = 3CDEF.
e. Remote transmission request bit for extended frame, [AIRTR] = 0

总结:

设置代码如下:

	/*
	 * Enable individual acceptance filters.
	 * 下面函数的设置顺序不能改变
	 */
	XCanPs_AcceptFilterDisable(CanInstancePtr, XCANPS_AFR_UAF_ALL_MASK);
	if( FALSE ==  XCanPs_IsAcceptFilterBusy(CanInstancePtr) ){
		XCanPs_AcceptFilterSet(CanInstancePtr, XCANPS_AFR_UAF1_MASK, u32 MaskValue, u32 IdValue);//If (AFMR & Message_ID) == (AFMR & AFIR) then Capture Message
	}
	
	XCanPs_AcceptFilterEnable(CanInstancePtr, XCANPS_AFR_UAF1_MASK);

需要注意的问题:

according to the sources [1], the values for the filters need to be generated through the XCANPS_IDR_* macros rather than passed in literally.  So I would try changes along the following lines:
Your example:
s32 res1 = XCanPs_AcceptFilterSet(CanInstPtr, XCANPS_AFR_UAF1_MASK, 0x7ff, 0x200);
Change to:
s32 res1 = XCanPs_AcceptFilterSet(CanInstPtr, XCANPS_AFR_UAF1_MASK,
                                                           0x7ff << XCANPS_IDR_ID1_SHIFT,
                                                           0x200 << XCANPS_IDR_ID1_SHIFT);

参考链接:
https://github.com/Xilinx/embeddedsw/blob/master/XilinxProcessorIPLib/drivers/canps/src/xcanps.c#L688
https://support.xilinx.com/s/question/0D52E00006iHj5bSAC/can-filtering-on-zynq-ultrascale-1085-r5-baremetal?language=en_US

ZYNQ CAN 中断设置问题总结

中断使能问题

调试发现,用 XCANPS_IXR_ALL 函数可以进入中断,但是 XCANPS_IXR_RXOK_MASK 不可以进入中断。

	// 只使能接受中断
	// 调试发现,用 XCANPS_IXR_ALL 可以使能中断,但是 XCANPS_IXR_RXOK_MASK 不可以使能中断
	XCanPs_IntrEnable(CanInstancePtr, XCANPS_IXR_ALL);
//	XCanPs_IntrEnable(CanInstancePtr, XCANPS_IXR_RXOK_MASK | XCANPS_HANDLER_EVENT | XCANPS_IXR_RXUFLW_MASK);
	XCanPs_IntrEnable(CanInstancePtr, XCANPS_IXR_RXOK_MASK );
	XCanPs_IntrDisable(CanInstancePtr, XCANPS_IXR_TXOK_MASK );
//	XCanPs_IntrDisable(CanInstancePtr, XCANPS_IXR_TXOK_MASK | XCANPS_IXR_RXNEMP_MASK
//			| XCANPS_IXR_TXFLL_MASK | XCANPS_IXR_TXFWMEMP_MASK);

用调试助手发送:
在这里插入图片描述
接收数据如下:
在这里插入图片描述
在这里插入图片描述

0X0284F0F0对应二进制:
001010-0001-11-00-1111-0000-1111-00000
1-0100-0011-1001-1110000111100000 – > 1439E1E0
说明收到的第1个word顺序不变。
接收到的数据中第三个和第四个word中,每个u32 中高低字节相反。

接受的中断状态寄存器:

在这里插入图片描述
对应得中断分别是:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
只有如下中断是有效的:
Receive FIFO Not Empty Interrupt
但想要的是如下中断:
在这里插入图片描述

中断状态寄存器:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
查看状态寄存器:
在这里插入图片描述
XCANPS_SR_ESTAT_MASK(ESTAT),bit 8:7, 状态为01,表明异常状态。
01: Indicates Error Active State.

当设置如下过滤条件时:

	XCanPs_AcceptFilterSet(CanInstancePtr, XCANPS_AFR_UAF1_MASK, 0xFFE7FFFE, 0b0010100001000011110000000000000 );

发送帧ID 0284xxxx 都可以接受到,似乎ID2的18bit没有起到作用。后来发现,原因在于AFMR和AFIR中的第20bit-IDE位置1才会被视作扩展帧,开始此位一直被设置为0,所以ID2被忽略了。

在这里插入图片描述
这里的一个new message 是16个字节,FIFO容量为64*16字节。

程序稳定性

硬件不连接CAN 控制器,程序容易卡在某个地方。

  • 1
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值