CAN控制器——MCP2518FD的FPGA调式

近期完成了CAN模块数据收发的调试,用到的芯片有CAN控制器:MCP2518FD和CAN收发器:ADM3057E。通过FPGA-XC7A35T开发板的SPI接口与分别与两个MCP2518FD相连,分别对其进行寄存器的读写以及RAM的读写,控制其中一个发送数据,另一个接收数据,从而实现了CAN协议数据发送与接收功能的调试。

一、SPI通信:

首先要实现FPGA与MPC2518FD的SPI通信,从而实现对其寄存器的读写配置。新建vivado工程,Creat block design,添加软核以及两个自己的SPI核,进行连线等后续工作。最终的block design如图所示

为两个SPI核分配地址。Generate output products,然后Create HDL wapper,生成HDL顶层文件,将PS端当做一个IP核来使用。新建V文件,例化Wrapper核并添加ILA进行两组SPI 8个信号的监控。创建XDC文件,将物理引脚进行管脚约束和时钟约束。

编译综合后生成bit文件,Export Hardware,Launch SDK,启动 SDK 开发环境。在SDK里进行C语言的编程,实现通过SPI对MCP2518FD寄存器的读和写。将自己的SPI核对应的C语言读写函数直接拿来用,发现无法进行读写,仔细对比芯片手册的SPI读写时序和自己的SPI读写时序,发现并解决了问题:

手册SPI时序:

错误(写不进去):

正确(能写进去):

错误原因:数据位最后一位末与cs信号上升沿重合,正确的时序为cs信号再过至少半个周期再拉高。

解决方法:ps端发数的时候要多发一位,即数据位要发9位(2进制表示时)或者12位(16进制表示时),即可将前8位正确写入寄存器中。(该方法仅针对自己的SPI IP核)

二、芯片初始化:

实现了FPGA与MPC2518FD的SPI通信后,我们可以对其寄存器进行读写配置了。接下来要做的是阅读MPC2518FD的芯片手册,找到需要配置的寄存器,将其功能配置为一个发送数据,一个接收数据。芯片手册上有每个寄存器具体到每一个位的功能,然而只看这些对于直接写整个程序还是有一定难度的。于是我去微芯的官网www.microchip.com上下载了该芯片的开发手册,以及底层驱动的C语言库。

开发手册上介绍了芯片初始化、发送数据、接收数据的步骤。如图是初始化的例子

虽然手册上给了初始化步骤和例程代码,但是没有具体告诉你需要配哪个寄存器以及每个位怎么配置,所以我们要看官网上下载的底层驱动的C语言库,看懂他例程代码底层具体配了哪个寄存器,每个位具体怎么配的,然后转换成自己SPI读写的代码。我们按手册的步骤配置每个需要配置的寄存器,将两个芯片初始化,并且将两个寄存器C1FIFOCON1的TXEN位分别置1和0,其功能配置为一个发送数据,一个接收数据。

三、数据的发送:

发送数据有两种方式:FIFO发送和队列发送,这里我们采用FIFO发送。不管哪种发送方式,都要将待发送的数据存入RAM里。RAM起始地址为0x400,待发送数据的地址为:

当然我们也可以自己计算数据的起始地址。如图所示,RAM里存放数据的位置是根据TEF,TX Queue,FIFOn的顺序排列的,TEF的起始地址永远为0x400,TX Queue地址为0x400地址加上TEF中数据的字节数,FIFO1的起始地址为0x400地址加上TEF和TX Queue中数据的字节数。我们这里只采用FIFO1发送数据,所以我们配置C1CON寄存器,关闭TEF和TX Queue使能位,此时它们不再占用RAM的空间。所以我们用FIFO1发送数据的起始地址就是0x400。

找到了RAM的起始地址后,我们要将数据写进RAM里,这里和写寄存器不一样,必须要一次性写4或4的倍数个字节,才能将数据写入RAM里。我们对SPI底层读写代码进行了修改,将第二行改为了(value>>32)&0xffffffff000fffff,成功的一次性写和读了4个字节,将数据写进了RAM并能成功读出来。注意写的时候也是要在4个字节后多写一位才能写进去。

接下来查看需要发送的数据的CAN帧格式,如图所示:

这里我们发送标准帧,将SID配置为0x300。FDF位置1将帧类型选择为CAN FD,置0则选择为CAN 2.0 。DLC位配置为8,即令数据字节一共有8个。数据字节我们发送01-08的递增数。这样一个完整的标准帧就拼好了,我们将其写到RAM里。

接来下将发送使能位:寄存器C1FIFOCON1的TXREQ位置1,完成数据发送。

四、数据的接收:

数据接收采用另一个芯片的FIFO1,也是先配置C1CON寄存器,关闭TEF和TX Queue使能位,此时它们不再占用RAM的空间。所以我们用FIFO1接收数据的起始地址也是0x400。

数据接收时,还需要配置一个过滤器,只接收指定ID的CAN报文。根据手册例程,配置相应寄存器,使能过滤器,只接收SID为0x300-0x30F的CAN报文。

接收时的CAN帧格式如图所示

R2只有在CiFIFOCONm.RXTSEN置1时存在,这里我们置0,即R2不存在。所以我们发送的数据帧格式也符合接收的数据帧格式。

我们从RAM里4个字节一组读发送的数据,并存在rxd这个数组里。

五、调试与结果

我们将两个ADM3057E芯片的CAN_H脚互连,CAN_L脚互连,CAN_GND脚互连,FPGA通过8个脚分别连两个MCP2518芯片的SPI接口,并且共地。两个MCP2518芯片的MCP25_*INT脚互连。给FPGA下载verilog程序,SDK里加载C语言程序。C语言要注意先初始化两个芯片,再使能数据发送,最后进行数据读取。

最终我们成功的在rxd数组里读取到了发送的数据。

发送的数据

接收的数据

   如图所示,可见收到的数据和发送的数据是一样的,成功实现了CAN协议数据一发一收的功能。

  • 6
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值