[X]关闭

[米联客-XILINX-H3_CZ08_7100] FPGA_SDK入门篇连载-15PS CAN 总线实验

文档创建者:FPGA课程
浏览次数:441
最后更新:2024-09-26
文档课程分类-AMD-ZYNQ
AMD-ZYNQ: ZYNQ-SOC » 1_SDK应用方案(仅旗舰型号) » 1-SDK基础入门方案
本帖最后由 FPGA课程 于 2024-9-26 09:56 编辑

软件版本:VIVADO2021.1
操作系统:WIN10 64bit
硬件平台:适用 XILINX A7/K7/Z7/ZU/KU 系列 FPGA
实验平台:米联客-MLK-H3-CZ08-7100开发板
板卡获取平台:https://milianke.tmall.com/
登录“米联客”FPGA社区 http://www.uisrc.com 视频课程、答疑解惑!​
1概述
ZYNQ的PS中包含了2个CAN接口,兼容CAN 2.0A和CAN 2.0B,最高可支持1Mbps的波特率。CAN作为工业应用中的一个重要的总线标准,广泛应用于各行各业之中。本教程介绍了ZYNQ中PS端CAN接口的基本使用方法。
实验目的:
1:熟悉CAN总线协议
2:通过阅读ug585(ZYNQ) , ug1085 (MPSOC),熟悉ZYNQ CAN控制器的硬件资源
3:通过VITIS-SDK 实现CAN的收发测试程序
4:利用CAN分析仪以及配套的软件工具实现CAN协议的收发测试
5:能够修改不同的波特率进行CAN总线通信
2系统框图
93856382318c44bc94d086cf416c7c38.jpg
3CAN总线介绍
3.1CAN的电气特性
CAN总线采用差分驱动,CAN总线空闲或者默认状态输出隐性电平1,如下图所示,输出1的情况下, Vcan_H相比于中间电平,只是略高,Vcan_L比中间电平略低。当输出0的时候,Vcan_L远高于中间电平,而Vcan_H远低于中间电平。
9e531a9d717940d18d7b29ccaffc216c.jpg
3.2数据格式
CAN总线中的数据以帧为单位,一共包含5种类型的帧,分别为:数据帧、远程帧、错误帧、过载帧和帧间隔。

  • 数据帧:用于发送节点向接收节点传送数据的帧。
  • 远程帧:用于接收节点向具有相同ID的发送节点请求数据的帧。
  • 错误帧:用于当检测出错误时向其他节点通知错误的帧。
  • 过载帧:用于接收节点通知其尚未做好接受准备的帧。
  • 帧间隔:用于将数据帧及远程帧与前面的帧分离开来。
CAN帧格式如下图所示,CAN 2.0A中使用的是标准帧,CAN 2.0B中使用的是扩展帧。标准帧和扩展帧的区别在于扩展帧增加了18bit的扩展标识符。一般情况下,与用户直接相关的只有数据帧和远程帧。数据帧和远程帧都可以使用标准帧格式或者扩展帧格式。
e2c6eca63b724bf2a85e6ecc44ba8c3e.jpg
以上对关键的概念解释如下:
SOF代表CAN的起始位,显性显示0
RTR的全称为“远程发送请求(Remote TransmissionRequest)”,数据帧中位显性0,远程帧中位隐性1
IDE (Identifier Extension,标志符扩展)位如果是显性0代表是标准帧,否则隐性1代表是扩展帧。
SRR替代远程请求(Substitute Remote Request,SRR)位为隐性1
R0,R1保留位
DLC,数据长度最大8
数据域,最大64bits
CRC校验 15 bits
CRC分隔符1bit
ACK 2 bits
EOF 7 bits
3.3数据帧
一个数据帧由7个不同的部分组成,分别为:帧起始、仲裁段、控制段、数据段、 CRC段、ACK应答段、帧结尾。如下图所示。
f54d21e10b204a1aa02b29f1f6005751.jpg
1:帧起始和结尾
帧起始和帧结尾说明如下图所示。
帧起始和帧结束用于界定一个数据帧,无论是标准数据帧或扩展数据帧都包含这两个段。
127ad7a8a547426ebe77145f6c83d24d.jpg
2:仲裁段
仲裁段说明如下图所示。
CAN-bus是如何解决多个节点同时发送数据,即总线竞争的问题?该问题由仲裁段给出答案。
3bc929aca3a143039d289fa58995e40b.jpg
3:控制段
控制段说明如下图所示。
控制段共6位,标准帧的控制段由扩展帧标志位IDE、保留位r0和数据长度代码DLC组成;扩展帧控制段则由IDE、r1、r0和DLC组成。
5d03d6beb1f0417ab81feb5bebdea6be.jpg
4:数据段
数据段说明如下图所示。
个数据帧传输的数据量为0~8个字节,这种短帧结构使得CAN-bus实时性很高,非常适合汽车和工控应用场合。
6c76033e5f734980855d2f700cff38ac.jpg
5:CRC段
CRC段说明如下图所示。
CAN-bus使用CRC校验进行数据检错,CRC校验值存放于CRC段。CRC校验段由15CRC值和1CRC界定符构成。
064e32888c8a4043a38a22c149ec04a1.jpg
6:ACK段
ACK段说明如下图所示。
当一个接收节点接收的帧起始到CRC段之间的内容没发生错误时,它将在ACK段发送一个显性电平。
d583d266789f41738884524c277e74aa.jpg
3.4远程帧
远程帧结构如下图所示。与数据帧相比只缺少了数据段。
与数据帧相比,远程帧结构上无数据段,由6个段组成,同理分为标准格式和扩展格式,且RTR位为1(隐性电平)。
2dfd3c4025124471b8a7d8f6f15fc76a.jpg
3.5数据帧与远程帧对比
数据帧与远程帧的对比如下图所示。
                        
比较内容
                        
                        
数据帧
                        
                        
远程帧
                        
                        
ID
                        
                        
发送节点的ID
                        
                        
被请求发送节点的ID
                        
                        
SRR
                        
                        
0(显性电平)
                        
                        
1(隐性电平)
                        
                        
RTR
                        
                        
0(显性电平)
                        
                        
1(隐性电平)
                        
                        
DLC
                        
                        
发送数据长度
                        
                        
请求的数据长度
                        
                        
是否有数据段
                        
                        
                        
                        
                        
                        
CRC校验范围
                        
                        
帧起始+冲裁段+控制段+数据段
                        
                        
帧起始+仲裁段+控制段
                        

3.6波特率
f4f0c4381fdc4a76a169a0a4e973012e.jpg
在CAN的底层协议里将CAN数据的每一位时间(TBit)分为许多的时间段(Tscl),这些时间段包括:
A. 位同步时间(Tsync)
B. 时间段1(Tseg1)
C. 时间段2(Tseg2)
其中位同步时间占用1个Tscl;时间段1占用(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)
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%。
d485d0aebf504452a15c2ff4c3a61f3f.jpg
与采样时间相关的有如下几个重要参数。
                        
参数
                        
                        
取值范围
                        
                        
说明
                        
                        
Sync_Seg
                        
                        
1 tq
                        
                        
同步段。固定长度,总线输入与系统时钟同步,用于同步总线上不同的节点。在此段内期望有一个 CAN 总线电平边沿出现。如果边沿出现在 Sync_Seg 之外,那么它与 Sync_Seg 之间的长度叫做边沿相位误差 。
                        
                        
Prog_Seg
                        
                        
1~8 tq
                        
                        
传播时间段。用于补偿信号在CAN网络内部的传输过程中的物理延时时间,与网络的拓补结构和长度有关。是信号在总线上的传播时间、接收电路延时及总线驱动器延时的总和的 2 倍。
                        
                        
Phase_Seg1
                        
                        
1~8 tq
                        
                        
相位缓冲段1。用于补偿跳变沿的相位误差,在重同步时可能被延长。
                        
                        
Phase_Seg2
                        
                        
1~8 tq
                        
                        
相位缓冲段2。用于补偿跳变沿的相位误差,在同步时可能被缩短。
                        
                        
TSJW
                        
                        
1~4 tq
                        
                        
(重)同步跳转宽度。决定重同步会时将采样点移动多远,移动距离的上限由用于补偿沿相位误差的相位缓冲段Phase_Seg1和Phase_Seg2给定。该参数不参与采样时间的计算。
                        
这个参数也表示CAN总线对波特率范围的容差度,设置较大的值可以提高波特率的适应性。
                        
                        
信息处理时间
                        
                        
0~2 tq
                        
                        
信息处理时间是一个以采样点作为起始的时间段。用于计算后续位的电平。该参数不参与采样时间的计算,与Phase_Seg2的取值相关。
                        
确定Prog_Seg、Phase_Seg1、Phase_Seg2 、TSJW的值需要遵循如下几个原则:

  • 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采样时间点位置的选取,网上有很多不同的说法,有75%、80%、87.5%、80%~90%等等,CiA官网也没有给出标准值。那么CAN的采样时间应该设置为多少才算合理?对于这个问题并没有1个绝对固定的标准值。对于不同的行业,不同的CAN高层协议(CANopen、DeviceNet等),以及不同的国家都有不同的经验值。
以应用较为广泛的CANopen协议为例,在2002年的CANopen CiA301 v4.0.2版本规范中,对于采用时间的建议值如下图所示。500k及以下波特率,采样时间建议值为14/16=87.5%,800k为8/10=80%,1M为6/8=75%。
468b93f5ee7a4ee988b9683797317cf9.jpg
然而,在2011年的最新版本CiA301 v4.2.0中,对于采样时间作了细微调整,将建议值均统一成了87.5%。而且给出了有效采样时间的可选范围。如下图所示。
e6742ae9326d4fd28a4b5e2b5104ae70.jpg
因此,采样时间的选择并没有1个绝对的标准值,针对不同应用和不同行业都会存在变化。但是要确保在同一个CAN网络中所有节点设备的采样时间均保持一致,这样才能保证CAN通信的稳定性。
广州周立功作为国内CAN产品的领先者,使用了CiA CANopen的建议值,即采样时间为87.5%,SJW=1 tq。因此,我们以此作为CAN接口的设计参考标准。
2:波特率及采样时间参数计算
波特率与采样时间的计算互相关联。计算步骤如下:

  • 首先计算CAN接口参考时钟和波特率的比值,该值为分频系数BRP与总tq个数的乘积。
  • 根据比值确定BRP和总tq的个数,两者必须都为整数,tq个数范围是8~25;
  • 将总tq的个数减1(去掉Sync_Seg)后得到Prog_Seg、Phase_Seg1、Phase_Seg2三个参数的和;
  • 然后派发Prog_Seg、Phase_Seg1、Phase_Seg2各占有的tq数。在计算时,一般将Prog_Seg与Phase_Seg1合为一个整体TS1进行计算,Phase_Seg2作为TS2进行计算。
手动逐个计算这些参数相对比较繁琐,可以借助广州周立功提供的一款波特率计算工具BtrCal自动计算各项参数。下载页面:CANalyst应用协议分析工具-广州致远电子股份有限公司.
816c19c416434212aeaeeb3d2b473c83.jpg
如下图所示,CAN接口参考时钟为100M,TSJW=0+1时,计算500k波特率的参数。选择误差为0,87.5%采样率下的参数。TS1=5+1=6,TS2=0+1=1。
根据公式:BitRate = Fpclk/( (BRP+1) * ((Tseg1+1)+(Tseg2+1)+1)
其中BitRate=0.5MHZ, Fpclk=100MHZ,可以算出
Fpclk/ BitRate=( (BRP+1) * ((Tseg1+1)+( Tseg1+1)+ 1)
200=( (BRP+1) * ((5+1)+( 0+1)+(0+1))
BRP=24
63b79c05c63a4ae99897240c8ab3c662.jpg

daf2bedef46c4aafaf18e8282e8a1c6c.jpg
6a1e4f74b2de463fbe4283fb7e341972.jpg
若所需要的波特率计算结果无法满足误差为0时获得87.5%的采样点,则可以取相对较近的值,且适当增大SJW,以提高波特率的适应性。例如,800k波特率计算结果,如下图所示。取80%(满足75%~90%)采样点时的参数,TS1=2+1=3,TS2=0+1=1,BRP=24+1=25。
dff6b94995b04bac8c9c6660719985d9.jpg
4CAN控制器介绍
ZYNQ包含2个CAN控制器,分别是CAN0和CAN1,可以引出到MIO上,也可以引出到PL的EMIO。对应的全局中断号分别是IRQ #ID 60 和IRQ #ID 83,CAN的参考时钟可以通过内部PLL设置也可以外部提供。波特率计算公式如下,其中BRP是预分频寄存器的分频系数。
78b79ac9676a41fc919044e67a0241b5.jpg
005d1c08bc944b0fbc3cf5d022cdd281.jpg

CAN控制器的功能模块包括了对象层(用于缓存数据和过滤数据),以及数据协议层。数据协议层主要依据CAN协议格式完成数据bitstream 流的收发。
对象层主要包括了发送数据通道、接收数据通道、配置寄存器。
其中发送数据通道包含了TX FIFO、TX HPB、TX 极性逻辑;接收数据通道包含了RX接收过滤器、RX FIFO。

2c029e1942b64189a675fdff9b09db0b.jpg
4.1:数据缓存过滤层
1:FIFO
CAN控制器有一个发送TXFIFO和一个接收RXFIFO,每个FIFO具有缓存64条消息。从TXFIFO发送数据的总延迟是2倍的TX驱动器延迟+传播延迟+ RX驱动器延迟。
2:TX HPB
每个控制器还具有一个传输高优先级缓冲区(TXHPB),该缓冲区为一条发送消息提供存储。写入此缓冲区的消息具有最大的传输优先级。 它们在当前传输完成后立即排队等待传输,从而抢占了TXFIFO中的任何消息。
3:TX Priority Logic
    TX发送优先权控制逻辑
4:RX过滤器
接收过滤器使用用户定义的接收掩码和ID寄存器对传入的消息进行排序,以确定是将消息存储在RXFIFO中,还是确认并丢弃它们。通过接收过滤器传递的消息存储在RXFIFO中。
5:CAN的工作模式
配置寄存器用于对CAN的工作模式当执行以下任何操作时,无论运行模式如何,CAN控制器都会进入配置模式。
•向SRR寄存器的[CEN]位写入0。
•向SRR寄存器的[SRST]位写入1。 重置软件后,控制器立即进入配置模式。
•在复位输入上驱动0。 只要复位为0,控制器就将继续处于复位状态。在将复位取反为1后,控制器将进入配置模式。

e3ee5a9ed49544f6b994366c64abaed2.jpg
以下对CAN的工作模式做简单介绍
5-1:普通模式
根据Bosch和IEEE规范定义的TX和RX I / O信号发送和接收消息。
5-2:睡眠模式
睡眠模式可用于在空闲时间节省少量电量。在睡眠模式下,控制器可以转换到正常模式或配置模式。睡眠模式包括以下操作。
•当另一个节点发送消息时,控制器接收到该消息并退出睡眠模式。
•当有新的TX请求时,控制器将切换到正常模式并为该请求提供服务。
•当控制器进入睡眠模式时,可能会产生中断。
•控制器唤醒时可能会产生中断。
当CAN总线活动或TXFIFO或TXHPB中有请求时,硬件会退出睡眠模式。当控制器退出睡眠模式时,硬件会将can.MSR [SLEEP]设置为0,并且会产生中断。
当[MSR]中的[LBACK]位为0,MSR寄存器中的[SLEEP]位为1,SRR寄存器中的[CEN]位为1时,CAN控制器将从配置模式进入睡眠模式。CAN 仅当没有来自TXFIFO或TX高优先级缓冲器的未决发送请求时,控制器才进入睡眠模式。
仅当[SLEEP]位为1,CAN总线空闲,并且没有来自TXFIFO或TX高优先级缓冲器(TXHPB)的挂起传输请求时,CAN控制器才从正常模式进入睡眠模式。
当另一个节点发送消息时,CAN控制器接收到发送的消息并退出睡眠模式。当控制器处于睡眠模式时,如果有来自TXFIFO或TXHPB的新传输请求,这些请求将得到处理,并且CAN控制器将退出睡眠模式。当CAN控制器进入睡眠模式或从睡眠模式唤醒时,将产生中断。从睡眠模式,CAN控制器可以进入配置模式或正常模式。
5-3:回环模式(诊断)
回送模式用于诊断目的。在环回模式下,必须将控制器编程为进入配置模式或发出一个复位信号。在环回模式下,将发生以下操作。
•控制器将隐性位流传输到CAN_PHY_TX总线信号上。
•TX消息在内部循环回到RX线路并得到确认。
•TX消息不在CAN_PHY_TX总线信号上发送。 控制器接收其发送的所有消息。
•控制器未收到其他CAN节点发送的任何消息。
5-4:侦听模式(诊断)
监听模式用于诊断目的。在侦听模式下,必须将控制器编程为进入配置模式或保持复位状态。 在监听模式下,将发生以下操作。
•控制器将隐性位流传输到CAN总线上。
•控制器不参与正常的总线通讯。
•控制器接收其他CAN节点发送的消息。
•软件可以对验收过滤器进行编程,以动态启用/禁用和更改标准。 错误计数器被禁用并清除为0。读取错误计数器寄存器将返回0。
5-5:模式转换
支持的模式转换如图20-3所示。 转换主要由复位,[CEN]位,MSR寄存器设置和硬件唤醒机制控制。
要从配置模式进入普通模式,必须执行以下步骤。
•清除can.MSR [LBACK,SNOOP,SLEEP] = 0。
•设置can.SRR [CEN] = 1。
要从正常模式进入睡眠模式(产生中断),请设置can.MSR [SLEEP] = 1。
导致控制器退出睡眠模式(产生中断)的事件包括以下步骤。
•RX信号活动(硬件设置can.MSR [SLEEP] = 0)。
•TXFIFO或TXHPB活动(硬件集can.MSR [SLEEP] = 0)。
•软件将0写入can.MSR [SLEEP]。
4.2CAN协议引擎层
CAN协议引擎主要由位定时逻辑(BTL)和位流处理器(BSP)模块组成。下图给出了CAN协议引擎的框图。
c53eab903ac24d8ea99be52a591dcb1c.jpg
1:RX / TX位时序逻辑
位定时逻辑(BTL)模块的主要功能如下。
•为位流处理器(BSP)生成RX采样时钟。
•使CAN控制器与总线上的CAN通信同步。
•在接收期间对总线进行采样并从总线中提取数据流。
•在传输过程中将传输位流插入总线。

位时间时钟周期的标称长度基于CAN_REF_CLK时钟频率,波特率发生器分频器(can.BRPR寄存器)和段长度(can.BTR寄存器)。
位定时逻辑模块使用can.BTR [SJW]位字段中的同步宽度参数来管理CAN的重新同步功能。 CAN位时序如下图所示。
同步段计数始终等于一个时间量子周期。可使用can.BTR [TS1,TS2]位字段对TS 1和TS 2周期计数进行编程。 当控制器处于配置模式时,将写入这些寄存器。 传播段的宽度(PROP_SEG)必须小于实际传播延迟。
53247474c7004fe1b0f8c419d1c58c1e.jpg
2:时间量子时钟
时间量子时钟(TQ_CLK)由控制器参考时钟(CAN_REF_CLK)除以波特率预分频器(BRP)得到。
tTQ_CLK = tCAN_REF_CLK * (can.BRPR[BRP] + 1) freqTQ_CLK
= freqCAN_REF_CLK / (can.BRPR[BRP] + 1)

tSYNC_SEGMENT = 1 * tTQ_CLK tTIME_SEGMENT1
= tTQ_CLK * (can.BPR[TS1] + 1) tTIME_SEGMENT2
= tTQ_CLK * (can.BPR[TS2] + 1) tBIT_RATE
= tSYNC_SEGMENT + tTIME_SEGMENT1 + tTIME_SEGMENT2 freqBIT_RATE
= freqCAN_REF_CLK / ((can.BRPR[BRP] + 1) * (3 + can.BTR[TS1] + can.BTR[TS2]))
3:比特流处理器
比特流处理器(BSP)模块在发送和接收CAN消息时执行多种功能。BSP从TXFIFO或TXHPB获得要发送的消息,并在将比特流传递给BTL之前执行以下功能。
在传输期间,BSP同时监视RX数据并执行总线仲裁任务。然后,当赢得仲裁时,它将发送完整的帧;当仲裁丢失时,将重试。
•序列化消息。
•在传输过程中插入填充位,CRC位和其他协议定义的字段。
在传输期间,BSP同时监视RX数据并执行总线仲裁任务。当赢得仲裁时,它将发送完整的帧;当仲裁丢失时,将重试。
在接收期间,BSP从接收到的比特流中删除填充位,CRC比特和其他协议字段。BSP状态机还在发送和接收期间分析总线通信量和接收格式以及CRC、ACK、填充和位冲突。然后,状态机执行错误信号和错误限制任务。CAN控制器不会自动生成过载帧,但会响应总线上检测到的过载标志。
该模块确定CAN控制器的错误状态:主动错误,被动错误或总线关闭。当在总线上观察到TX或RX错误时,BSP将根据CAN 2.0A,CAN 2.0B和ISO 11898-1标准中定义的规则更新发送和接收错误计数器。基于这些计数器的值,BSP将更新CAN控制器的错误状态。
4.3消息格式
RXFIFO,TXFIFO和TXHPB使用相同的消息格式,每个消息包括四个字(16个字节), 无论消息中的数据字节和有效字段的实际数量如何,软件都必须读写所有四个字。
25b218fb7d8a4b079654e41eec110c25.jpg
写入:如果不需要位字段或数据字节,则写入零。
读取:数据从字节0开始,并持续DLC中的计数数。
4.4CAN的中断
每个CAN控制器都有一个向通用中断控制器(GIC)发出的中断信号。
CAN 0连接到IRQ ID#55,CAN 1连接到ID#56。 中断源可以分为以下之一。
•TXFIFO和TXHPB
•RXFIFO
•消息传递和仲裁
•睡眠模式和总线关闭状态
使用can.IER寄存器启用和禁用中断。使用can.ISR寄存器检查中断的初始状态。通过向can.ICR寄存器写入1来清除中断。
ba466cd2d0ed4f99836030a5555577e6.jpg
6a9467825d7b40f0a267565d22b25241.jpg
d3e0ab767d574e50a81b1adb8dd82016.jpg
4.5编程模型
5b881504feac48b2877a30ca30cffd77.jpg
5硬件电路分析
f7a00cf29f0d4090b06cb0afdc3318b5.jpg
6搭建SOC系统工程
详细的搭建过程这里不再重复,对于初学读者如果还不清楚如何创建SOC工程的,请学习“01Vitis Soc开发入门”这篇文章。
6.1SOC系统工程
54402191c652442c8202cbb3229f5468.jpg
ZYNQ IP中设置CAN0
82c51da1e7694095825370f862209998.jpg
ZYNQ IP中设置CAN的参考时钟,不同的参考时钟波特率计算方法不一样.
8398764ef33e47ed90c98b6676f63600.jpg
6.2编译并导出平台文件
以下步骤简写,有不清楚的看第一篇文章。
1:单击Block文件à右键àGenerate the Output ProductsàGlobalàGenerate。
2:单击Block文件à右键à Create a HDL wrapper(生成HDL顶层文件)àLet vivado manager wrapper and auto-update(自动更新)。
3:添加配套工程路径下uisrc/04_pin/fpga_pin.xdc约束文件
4:生成Bit文件。
5:导出到硬件: FileàExport HardwareàInclude bitstream
6:导出完成后,对应工程路径的soc_hw路径下有硬件平台文件:system_wrapper.xsa的文件。根据硬件平台文件system_wrapper.xsa来创建需要Platform平台。
ddea3d988a1045a2b7b3cac76d73cbe8.jpg
7搭建Vitis-sdk工程
创建soc_base sdk platform和APP工程的过程不再重复,如果不清楚请参考本章节第一个demo。
7.1创建SDK Platform工程
f2e00c8502694924ab952e2cc3d3254c.jpg
右击soc_base编译,编译的时间可能会有点长
7.2创建APP工程
bfe3898ae4cc44098eca50a98204a7e0.jpg
8程序分析8.1Init_CanPsIntr(&CanInstance, CAN_DEVICE_ID)函数1:XCanPs_LookupConfig(DeviceId)
f74012361e3344bfb544d9dbc3fab69c.jpg
首先依然是通过查找配置程序来获取CAN控制器的硬件配置。我们跟踪这个程序,看看他获取的配置是什么。
f63676013cc04e76b06e1de4498e47f2.jpg
这个结构体中定义了CAN的ID 以及CAN的基地址,可以看到我们这里使用的是PS 的CAN1
28cf309838f74b11ada94e7031c13b95.jpg
进一步跟踪,可以在xparameters.h中查到CAN基地址的具体定义,以及CAN的参考时钟,这里和我们MPSOC IP中设置一样,参考时钟100M
056576936f004a37a754bb50ac7b3f92.jpg
2:XCanPs_CfgInitialize(CanInstPtr,ConfigPtr,ConfigPtr->BaseAddr)
这个函数用于初始化回调函数的函数指针,为中断部分设置回调函数,做好准备。可以看到CAN的部分中断回调函数根据不同的状态信息,调用了不同的函数。
6233ed39531a459085bca33a125173cd.jpg
在这个函数的最后,调用了XCanPs_Reset(InstancePtr);函数复位CAN控制器,我们看下这个函数操作的寄存器.
685b94aa6fde47ee8537ae5464eb0462.jpg
CAN的软件复位寄存器:地址偏移XCANPS_SRR_OFFSET=x00000000
4c26c680faa344de89f72fa520bebbc2.jpg
bit0:写1复位CAN控制器
bit1:写0 CAN处于配置模式,写1可以处于环路模式,休眠模式,或者正常模式
a59da2314c854d61888c5d996f4dba47.jpg
3:Can_Config(CanInstPtr,rate_500kbps)
这个函数中设置CAN的波特率
1eb815d1a79c42cfbdbf06756e76da51.jpg
3.1:XCanPs_EnterMode(CanInstPtr, XCANPS_MODE_CONFIG)函数
首先根据输入的参数XCANPS_MODE_CONFIG,对寄存器进行设置。
48e07121090541cb87cb9b21bf7a7c60.jpg
以上代码首先通过XCanPs_GetMode(InstancePtr)函数读取模式状态:
2ad4befc8adc44e399dc5fe298863758.jpg
这个函数通过XCanPs_GetStatus(InstancePtr)函数读取CAN状态寄存器的状态:
daa22557fa7f4f739889fb30afcc1c07.jpg
CAN状态寄存器的偏移地址XCANPS_SR_OFFSET= 0x00000018
bcc463daae0e43fcb1c78eb1d8dbd9bd.jpg
21e4ed46641f43a9a0e51bf7e0897950.jpg
之后通过判断当然模式和需要的配置模式参数进行状态的切换,分三种情况:
1需要设置的配置模式为休眠模式&当前的模式为正常模式,则切换到休眠模式
2需要设置的配置模式为正常模式&当前的模式为休眠模式,则切换到正常模式
3以上两种情况都是,则执行else分支代码设置复位寄存器,并且继续执行:
725d82d242e24004b0c781b7b1bfe17f.jpg
以上代码中对软件复位寄存器,以及模式选择选择寄存器进行设置。这里介绍下模式选择寄存器。
模式选择寄存器的偏移地址XCANPS_MSR_OFFSET= 0x00000004
30dc073b5d604ba7b3214bba2b7fa150.jpg
3.2:can_bit_timing_config参数列表
8303cef172de41788b698a45b90e92a2.jpg
can_bit_timing结构体定义了CAN控制的:
1) BaudRate-波特率
2) BaudRatePrescaler-波特率预分频系数
3) TimeSegment1-时间段1
4) TimeSegment2-时间段2
5) SyncJumpWidth-同步跳转宽度
6b2cb7f0b1b44d91a99f22320affec40.jpg
关于波特率分频系数的计算在3小节有介绍。
3.3: XCanPs_SetBaudRatePrescaler(CanInstPtr, can_bit_timing_config.BaudRatePrescaler)
a7875bf59191423aba975669021c7a22.jpg
这个函数中,对波特率寄存器进行设置。
波特率寄存器的偏移地址XCANPS_BRPR_OFFSET = 0x00000008
06d9b30b1bac4ff48f24f16016cf4c8b.jpg
3.4:XCanPs_SetBitTiming(XCanPs *InstancePtr, u8 SyncJumpWidth,u8 TimeSegment2, u8 TimeSegment1)
设个函数用于设置CAN控制器的时间段1、时间段2、以及同步跳转宽度

ede286840539482fbc52dfdd3a427369.jpg
如果需要设置这些参数,首先确保CAN处于配置模式。
位时间寄存器的偏移地址XCANPS_BTR_OFFSET=0x0000000C
2f44c7c080c04b879eb04f7c8dcf8ac1.jpg
4:配置正常模式
当配置完成后,将CAN配置为正常模式
af38a22a351c43838ef85cd1055f034d.jpg
8.2CanPs_Setup_IntrSystem(&Intc, &CanInstance, CAN_INTR_VEC_ID)
ed66413e174e4cf496fa7123b5940966.jpg
1:XScuGic_Connect(IntcInstancePtr, CanIntrId, (Xil_InterruptHandler)XCanPs_IntrHandler, (void *)CanInstancePtr)函数 8c434b6e2515471b9cb84076f2938c0d.jpg
这个函数负责把对应中断号从回调函数,以及回调参数,连接到之前在Init_Intr_System(&Intc)函数中定义的回调函数。
2:设置用户回调函数
1e8c9a1af57c4c15a577a776abb83a7d.jpg
当CAN的中断产生后,通过以上设置的函数指针会调用对应的函数,分析的最后部分我再介绍每个中断函数。
3:XScuGic_Enable(IntcInstancePtr, CanIntrId)
在以下代码中,首先绑定中断号,CPU号,我们也可以进一步分中断
2c5023587e794befa5e0cd7545e99041.jpg
XScuGic_InterruptMaptoCpu(InstancePtr, Cpu_Id, Int_Id)函数
在这个函数中具体中断和CPU如何关联,如何设置SPI(共享外设中断)中断寄存器的相关位我们无法进一步分分析,到此为止。
efc5873e9c9b489781e93017955b737f.jpg
4:XCanPs_IntrEnable(CanInstancePtr, XCANPS_IXR_ALL)
06586f4cbc374d5291c7fb4954b06b6e.jpg
CAN的中断使能寄存器偏移地址:XCANPS_IER_OFFSET= 0x00000020
1141d85e5a834688b26ab0990dd7829b.jpg
e00ddbfcd6274172b57fc28d5f173da4.jpg
3c299c93bdfa412da470f92de7097fb1.jpg
2ea77bc892b547c6bd62f01bc5e1983e.jpg
5:void can_SendHandler(void *CallBackRef)函数
CAN帧发送成功后回调
3aac3d1475cc4914898747331156db90.jpg
6:void can_RecvHandler(void *CallBackRef)函数
接收到正确数据后回调,在接收中断中打印帧信息。
21aa51ac0c7d4e138b19b4758afa764e.jpg
7:void can_ErrorHandler(void *CallBackRef, u32 ErrorMask)函数
当发生ACK错误、bit错误、帧错误、CRC错误、填充错误,错误回调函数执行
7109a10310d64ae39fd5fc13e99236a7.jpg
8:void can_EventHandler(void *CallBackRef, u32 IntrMask)
当发生bus_off状态、RX FIFO溢出、RX FIFO 满、TX FIFO满、TX优先缓存满、从睡眠唤醒、总线仲裁丢失,会回调以下函数。
8ebd561177f84fa09c3c09bec32b548b.jpg
8:Can_send(&CanInstance, &msg)函数
559015a01f824b6890bd16957a15eb5c.jpg
以上函数中首先填写帧信息
然后通过调用函数XCanPs_IsTxFifoFull(InstancePtr)获取发送FIFO的状态。
9ca0d5f0345c4429958d32ba6ed595b7.jpg
最后调用XCanPs_Send(InstancePtr, TxFrame)函数发送帧
941c8aa090484b7d9cf0bec429ba4525.jpg
以上函数中,帧信息需要写入以下寄存器:

  • TX的FIFO ID寄存器 偏移地址XCANPS_TXFIFO_ID_OFFSET= 0x00000030
f09752b9446c4bec85c30aa3c87b8969.jpg
2)TX FIFO 数据长度寄存器偏移地址:XCANPS_TXFIFO_DLC_OFFSET=0x00000034
a732e8fa82c94b29b44f06cab82de8c0.jpg
3) TX FIFO的数据字1寄存器偏移地址:XCANPS_TXFIFO_DW1_OFFSET= 0x00000038
682d82dd3fed4217a7c3185cc14656f3.jpg
4) TX FIFO的数据字2寄存器偏移地址:XCANPS_TXFIFO_DW2_OFFSET= 0x0000003C
0680145b76a64cef8fb7ddda1e87e3a9.jpg
9方案演示
9.1硬件准备
53de17cc263149129225d0dcb49f4f26.jpg
9.2实验结果
1:软件安装
根据安装说明安装软件,CAN分析仪软件为“USB_CAN TOOLSetup(V9.05).exe”
8b91dd18b8c6454b81a5c8800676d09d.jpg
2:CAN分析仪的使用
main.c中的宏定义:#define TEST_RX_ONLY注释。重新编译工程。
CAN分析仪与电脑连接,使用CAN分析仪连接CAN模块,再将CAN模块连接开发板。
打开USB-CAN Tool,选择500kbps的波特率连接CAN分析仪。
bdcda0a1fadc4af1b1b89dd3a805e75e.jpg
通过SDK将程序下载至开发板运行,此时,在USB-CAN Tool软件中便可抓取开发板每隔1s向外发送的CAN数据帧,如下图所示。数据帧,每个数据帧的第1个字节数据不断递增。
2267af9453694770ba81b862cb4f313b.jpg
3:数据接收测试
还原main.c中的宏定义:#define TEST_RX_ONLY。重新编译工程。将程序下载到开发板中运行。
4:数据帧接收
打开USB-CAN Tool软件的数据发送功能,设置如下图所示。通过软件向开发板发送数据长度为8字节的数据帧。发送的第一个字节的数据不断递增。然后,点击立即发送。
c4ab2d2ddaac44a6a1dc62c7b0b6baca.jpg
同时,开发板通过串口将每次接收到的数据帧信息在SDK中打印出来,如下图所示。可以看到第一个字节的数据在递增。
2e4c9148c9be499ebcd167a8c411a88b.jpg
5:远程帧接收
db513d5f589a46378837298f4c19e808.jpg
fbf9f407f009401a82be230ab65582de.jpg
6:数据收发同时进行
将main.c中的宏定义:#define TEST_RX_ONLY注释,重新编译工程。然后将程序下载到开发板中运行。同时,通过软件向开发板连续发送数据长度为8字节的数据帧。如下图所示。
fcf6fe6c09d04d0892102de7466d5c48.jpg
2dfd3c4025124471b8a7d8f6f15fc76a.jpg
f4f0c4381fdc4a76a169a0a4e973012e.jpg
d485d0aebf504452a15c2ff4c3a61f3f.jpg
468b93f5ee7a4ee988b9683797317cf9.jpg
e6742ae9326d4fd28a4b5e2b5104ae70.jpg
816c19c416434212aeaeeb3d2b473c83.jpg
63b79c05c63a4ae99897240c8ab3c662.jpg
daf2bedef46c4aafaf18e8282e8a1c6c.jpg
6a1e4f74b2de463fbe4283fb7e341972.jpg
dff6b94995b04bac8c9c6660719985d9.jpg
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则