0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

基于FPGA的轻量级CAN总线控制器实现方案

FPGA设计论坛 来源:FPGA设计论坛 2026-04-03 10:10 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

简介

CAN总线作为工业和汽车领域最常用的通信总线,具有拓扑结构简洁、可靠性高、传输距离长等优点。CAN总线的非破坏性仲裁机制依赖于帧ID,CAN2.0A和CAN2.0B分别规定了11bit-ID(短ID)的标准帧和29bit-ID(长ID)的扩展帧,另外,还有远程帧这种数据请求机制。关于CAN总线的更多知识可以参考这个科普文章。

本库实现了一个轻量化但完备的FPGA CAN总线控制器,特点如下:

平台无关:纯 Verilog 编写,可以在 Altera 和 Xilinx 等各种 FPGA 上运行。

本地ID可固定配置为任意短ID。

发送: 仅支持以本地ID发送数据长度为4Byte的帧。

接收: 支持接收短ID或长ID的帧,接收帧的数据长度没有限制 (即支持0~8Byte) 。

接收帧过滤: 可针对短ID和长ID独立设置过滤器,只接收和过滤器匹配的数据帧。

自动响应远程帧: 当收到的远程帧与本地ID匹配时,自动将发送缓存中的下一个数据发送出去。若缓存为空,则重复发送上次发过的数据。

设计文件

RTL 文件夹包含3个设计代码文件,各文件功能如下表。你只需将这3个文件包含进工程,就可以调用顶层模块can_top.v进行CAN通信业务的开发。

文件名 功能 备注
can_top.v CAN控制器的顶层
can_level_packet.v 帧级控制器,负责解析或生成帧,并实现非破坏性仲裁 被can_top.v调用
can_level_bit.v 位级控制器,负责收发bit,具有抗频率偏移的下降沿对齐机制 被can_level_packet.v调用

仿真文件

仿真相关的文件都在 SIM 文件夹中,其中:

tb_can_top.v 是针对 can_top.v 的 testbench 。

tb_can_top_run_iverilog.bat 包含了运行 iverilog 仿真的命令。

tb_can_top.v 描述了4个CAN总线设备互相进行通信的场景,每个设备都是一个 can_top 的例化,图1是每个设备的详细属性,各个设备互相接收的关系可以画成左侧的图,箭头代表了各个设备之间的接收关系。另外,每个CAN设备的驱动时钟并不严格是50MHz,而是有不同的±1%的偏移,这是为了模拟更糟糕的实际情况下,CAN控制器的“自动对齐”机制能否奏效。

394bbef0-2d97-11f1-90a1-92fbcf53809c.png


图1:仿真中的4个CAN设备的详细参数

使用 iverilog 进行仿真前,需要安装 iverilog ,见:iverilog_usage

然后双击 tb_can_top_run_iverilog.bat 运行仿真。仿真运行完后,可以打开生成的 dump.vcd 文件查看波形。

顶层模块说明

本节介绍如何使用can_top.v,它的接口如下表。

信号 方向 宽度 功能 备注
rstn 输入 1 低电平复位 在开始工作前需要拉低复位一下
clk 输入 1 驱动时钟 频率需要是CAN总线波特率的10倍以上,内部分频产生波特率
can_rx 输入 1 CAN-PHY RX 应通过FPGA的普通IO引出,接CAN-PHY芯片 (例如TJA1050)
can_tx 输出 1 CAN-PHY TX 应通过FPGA的普通IO引出,接CAN-PHY芯片 (例如TJA1050)
tx_valid 输入 1 发送有效 当=1时,若发送缓存未满(即tx_ready=1),则tx_data被送入发送缓存
tx_ready 输出 1 发送就绪 当=1时,说明发送缓存未满。与 tx_valid 构成一对握手信号
tx_data 输入 32 发送数据 当tx_valid=1时需要同步给出待发送数据 tx_data
rx_valid 输出 1 接收有效 当=1时,rx_data上产生1字节的有效接收数据
rx_last 输出 1 接收最后字节指示 当=1时,说明当前的rx_data是一个帧的最后一个数据字节
rx_data 输出 8 接收数据 当rx_valid=1时,rx_data上产生1字节的有效接收数据
rx_id 输出 29 接收ID 指示当前接收帧的ID,若为短ID则低11bit有效
rx_ide 输出 1 接收ID类型 =1 说明当前接收帧是长ID,否则为短ID

接入CAN总线

can_top.v的can_rx和can_tx接口需要引出到FPGA引脚上,并接CAN-PHY芯片(比如TJA1050),如图2。

3b013c48-2d97-11f1-90a1-92fbcf53809c.png

图2:接入CAN总线的方式

注:这里注意一个坑,虽然FPGA的引脚(can_rx,can_tx)可以是3.3V电平的,但CAN-PHY的电源必须是5V的,否则对CAN总线的驱动力不够。另外,CAN-PHY要和FPGA共地。

用户发送接口

can_top.v的tx_valid,tx_ready,tx_data构成了流式输入接口,它们都与clk的上升沿对齐,用于向发送缓存中写入一个数据。只要发送缓冲区不为空,其中的数据会逐个被CAN控制器发送到CAN总线上。

tx_valid和tx_ready是一对握手信号,波形如下图,只有当tx_valid和tx_ready都为1时,tx_data才被写入缓存。tx_ready=0说明缓存已满,此时即使tx_valid=1,也无法写入缓存。不过,当发送频率不高而不至于让 CAN 总线达到饱和时,可以不用考虑缓存满(即tx_ready=0)的情况。

下图中,D0,D1,D2这3个数据被写入缓存,D0写入后,缓存已满,导致tx_ready=0,之后的3个周期D1都没有成功写入,但在第4个时钟周期tx_ready变成1,D1被写入。之后发送方主动空闲2个时钟周期后,D3也被写入。

每个数据都是4Byte(32bit)的,只要FIFO不为空,该CAN控制器就自动地每次发送一个帧,每帧一个数据,帧数据长度为4Byte。

     _  __  __  __  __  __  __  __  __  __  __  __ clk    \__/ \__/ \__/ \__/ \__/ \__/ \__/ \__/ \__/ \__/ \__/            _____________________________       _____tx_valid ___________/               \___________/   \________     _________________          ________________________________tx_ready          \_________________/           _____ _______________________       _____tx_data  XXXXXXXXXXXX__D0_X___________D1__________XXXXXXXXXXXXX__D3_XXXXXXXXX

用户接收接口

can_top.v的rx_valid,rx_last,rx_data,rx_id,rx_ide构成了接收接口,它们都与clk的上升沿对齐。

当CAN总线上收到了一个与ID过滤器匹配的数据帧后,会将这一帧的字节逐个发送出来。设数据帧长为n字节,则rx_valid上会连续产生n个周期的高电平,同时rx_data上每拍时钟会产生一个收到的数据字节,在最后一拍会让rx_last=1,指示一帧的结束。在整个过程中,rx_id上出现该帧的ID(若为短ID,则只有低11bit有效),同时,rx_ide指示该帧为长ID还是短ID。

接收接口的波形图举例如下,该例中模块先后收到了一个短ID的,数据长度为4的数据帧,和一个长ID的,数据长度为2的数据帧。

      __  __  __  __  __  __  __  __  __  __  __ clk   __/ \__/ \__/ \__/ \__/ \__/ \__/ \__/ \__/ \__/ \__/ \_          _______________________       ___________rx_valid _________/            \___________/      \_________                   _____          _____rx_last  ___________________________/   \_________________/   \_________          _____ _____ _____ _____       _____ _____rx_data  XXXXXXXXXX__0__X__1__X__2__X__3__XXXXXXXXXXXXX__0__X__1__XXXXXXXXXX          _______________________       ___________rx_id   XXXXXXXXXX__________ID1__________XXXXXXXXXXXXX____ID2____XXXXXXXXXX                            _____________________rx_ide  _____________________________________________/

与发送接口不同,接收接口无握手机制,只要收到数据就让rx_valid=1来发出,不会等待接收方是否能接受。

配置本地ID

can_top.v有一个11bit的参数(parameter)叫LOCAL_ID,它决定了该模块发送的帧的ID;同时,当can_top接收的远程帧的ID与LOCAL_ID匹配时,就会进行响应(ACK),并自动回复一个数据帧(如果发送缓存为空,则自动重复回复上次发过的数据)。

配置ID过滤器

can_top.v的RX_ID_SHORT_FILTER和RX_ID_SHORT_MASK参数用来配置短ID过滤器。设收到的数据帧的ID是rxid(短),匹配表达式为:

rxid & RX_ID_SHORT_MASK == RX_ID_SHORT_FILTER & RX_ID_SHORT_MASK

以上表达式满足 Verilog 或 C 语言的语法。表达式为真时,rxid与过滤器匹配,这样的数据帧才能被模块响应(ACK),并将其数据转发到用户接受接口上。表达式为假时,rxid与过滤器不匹配,该数据帧不仅不会被响应(ACK),也不会被转发到用户接受接口上。

同理,RX_ID_LONG_FILTER和RX_ID_LONG_MASK参数用来配置长ID过滤器。设收到的数据帧的ID是rxid(长),匹配表达式为:

rxid & RX_ID_LONG_MASK == RX_ID_LONG_FILTER & RX_ID_LONG_MASK

MASK参数可以被称为通配掩码,掩码=1的位必须匹配FILTER,掩码=0的位我们不在乎,既可以匹配1也可以匹配0。

例如你想接收 0x122, 0x123, 0x1a2, 0x1a3 这4种短ID,则可配置为:

RX_ID_SHORT_FILTER = 11'h122,RX_ID_SHORT_MASK  = 11'h17e

配置时序参数

can_top.v的default_c_PTS,default_c_PBS1,default_c_PBS2这3个时序参数决定了CAN总线上的一个位的3个段(PTS段, PBS1段, PBS2段)的默认长度,这3个段的含义详见这个科普文章。总的来说,分频系数计算如下:

分频系数 = default_c_PTS + default_c_PBS1 + default_c_PBS2 + 1

而CAN总线的波特率计算方法为:

CAN波特率 = clk频率 / 分频系数

例如,在 clk=50MHz的情况下,可以使用如下参数组合来配置出各种常见的波特率。

分频系数 波特率 default_c_PTS default_c_PBS1 default_c_PBS2
50 1MHz 16'd34 16'd5 16'd10
100 500kHz 16'd69 16'd10 16'd20
500 100kHz 16'd349 16'd50 16'd100
5000 10kHz 16'd3499 16'd500 16'd1000
10000 5kHz 16'd6999 16'd1000 16'd2000

示例程序

FPGA 目录里的fpga_top.v是一个调用can_top.v进行简单的 CAN 通信的案例。要运行该案例,请建立 FPGA 工程,并加入以下源文件:

FPGA 目录里的 fpga_top.v 、 uart_tx.v 。

RTL 目录里的 can_top.v 、 can_level_packet.v 、 can_level_bit.v 。

fpga_top.v 是项目的顶层,其引脚连接方法如下:

module fpga_top (  // clock ,连接到 FPGA 板上晶振,频率必须为 50MHz   input wire      CLK50M,  // UART (TX only), 连接到电脑串口(比如通过 USB 转 UART 模块),不方便接 UART 可以不接  outputwire      UART_TX,  // CAN bus, 连接到 CAN PHY 芯片,然后 CAN PHY 连接到 CAN 总线(如图2)  input wire      CAN_RX,  outputwire      CAN_TX);

该案例的行为是:

本地 (也就是 FPGA) 的 CAN ID 配置为 0x456 ,因此所有发出的数据帧的 ID 都为 0x456 。

ID 过滤器配置为只接收短ID=0x123或长ID=0x12345678的数据帧。

每一秒向发送缓存中送入一个递增的数据,该数据帧并会被发送到 CAN 总线上。

将 CAN 总线上接收到的(也就是符合过滤器配置)的数据帧通过 UART 发送给电脑。

注:该案例中,CAN 的波特率为 1MHz ; UART 的格式为 115200,8,n,1

3f61610a-2d97-11f1-90a1-92fbcf53809c.jpg

图3:硬件连接

我在测试该例子时,将 CAN 总线与一台USB-CAN调试器相连,如图3。然后编译工程并下载FPGA,打开USB-CAN调试器的配套软件,可以看到如下现象:

软件中每秒会收到一个 FPGA 发来的帧,数据长度DLC=4,值递增。如图4中没框的部分。

在软件中发送短ID=0x123或长ID=0x12345678的数据帧,会显示“发送成功”,如图4中蓝框的部分,说明该帧被 FPGA 响应了。同时,如果你把FPGA的UART连接到了电脑的串口,则可以在“串口助手”或“HyperTerminal”等软件上看到打印出的数据内容。

在软件中发送短ID=0x456的远程帧,FPGA 会立即响应一个数据帧,如图4中红框的部分。

3fbd3764-2d97-11f1-90a1-92fbcf53809c.png

图4:USB-CAN调试器的配套软件上观察到的现象

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • FPGA
    +关注

    关注

    1663

    文章

    22492

    浏览量

    638937
  • 控制器
    +关注

    关注

    114

    文章

    17860

    浏览量

    195016
  • CAN总线
    +关注

    关注

    146

    文章

    2050

    浏览量

    135472
  • Xilinx
    +关注

    关注

    73

    文章

    2205

    浏览量

    131819

原文标题:基于 FPGA 的轻量级CAN总线控制器

文章出处:【微信号:gh_9d70b445f494,微信公众号:FPGA设计论坛】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    基于CAN总线的家庭控制器的设计与实现

    基于CAN总线的家庭控制器的设计与实现  引言   CAN(Controller Area Network)
    发表于 11-07 09:30 956次阅读
    基于<b class='flag-5'>CAN</b><b class='flag-5'>总线</b>的家庭<b class='flag-5'>控制器</b>的设计与<b class='flag-5'>实现</b>

    基于STM32和FPGACAN总线运动控制器的设计

    运用低功耗C0rtex-M3微控制器STM32F103VBT6和FPGA芯片设计一种基于CAN总线的运动控制器。介绍系统的体系结构、主要硬件
    发表于 01-31 14:33 45次下载
    基于STM32和<b class='flag-5'>FPGA</b>的<b class='flag-5'>CAN</b><b class='flag-5'>总线</b>运动<b class='flag-5'>控制器</b>的设计

    FPGA实现CAN总线控制器源码

    Xilinx FPGA工程例子源码:FPGA实现CAN总线控制器源码
    发表于 06-07 14:13 97次下载

    基于FPGACAN控制器MCP2515设计惯导系统的CAN总线

    接口控制新型的CAN 控制器MCP2515,使惯导系统不仅具备了接入CAN 总线的能力,而且在系统实现
    发表于 07-13 17:43 0次下载

    基于DSP_FPGACAN总线的跟踪控制器设计

    基于DSP_FPGACAN总线的跟踪控制器设计
    发表于 10-21 08:52 5次下载
    基于DSP_<b class='flag-5'>FPGA</b>与<b class='flag-5'>CAN</b><b class='flag-5'>总线</b>的跟踪<b class='flag-5'>控制器</b>设计

    基于FPGA的VME总线CAN总线之间的传输转换方案设计

    为了扩展VME总线CAN总线的应用范围,充分利用两种总线的不同传输特点,采用了模块设计方法,提出一种基于FPGA和MCU的
    发表于 07-17 10:11 4321次阅读
    基于<b class='flag-5'>FPGA</b>的VME<b class='flag-5'>总线</b>和<b class='flag-5'>CAN</b><b class='flag-5'>总线</b>之间的传输转换<b class='flag-5'>方案</b>设计

    基于FPGACAN总线控制器SJA1000软核的设计方案解析

    单片机,实现CAN控制器的通信联络。FPGA/SOPC技术是实现嵌入式系统的最高形式,基于IP软核的设计与应用也必将成为替代硬核的一种发展
    发表于 12-07 11:20 30次下载
    基于<b class='flag-5'>FPGA</b>的<b class='flag-5'>CAN</b><b class='flag-5'>总线</b><b class='flag-5'>控制器</b>SJA1000软核的设计<b class='flag-5'>方案</b>解析

    如何使用FPGA进行CAN控制器软核的设计与实现

    和Altera 公司部分FPGA 上的资源利用和性能情况。此外,基于SOPC技术将处理软核和CAN 控制器软核集成在单片FPGA 中,构建
    发表于 07-19 17:48 29次下载
    如何使用<b class='flag-5'>FPGA</b>进行<b class='flag-5'>CAN</b><b class='flag-5'>控制器</b>软核的设计与<b class='flag-5'>实现</b>

    采用CAN总线控制器SJA1000实现控制电路接口的设计

    硬件电路的设计主要是CAN通信控制器与微处理之间和CAN总线收发与物理
    发表于 03-13 10:45 9117次阅读
    采用<b class='flag-5'>CAN</b><b class='flag-5'>总线</b><b class='flag-5'>控制器</b>SJA1000<b class='flag-5'>实现</b><b class='flag-5'>控制</b>电路接口的设计

    如何使用FPGACAN控制器MCP2515实现惯导系统的CAN总线接口的设计

    接口控制新型的CAN 控制器MCP2515,使惯导系统不仅具备了接入CAN 总线的能力,而且在系统实现
    发表于 01-27 15:52 17次下载
    如何使用<b class='flag-5'>FPGA</b>和<b class='flag-5'>CAN</b><b class='flag-5'>控制器</b>MCP2515<b class='flag-5'>实现</b>惯导系统的<b class='flag-5'>CAN</b><b class='flag-5'>总线</b>接口的设计

    如何用FPGA实现CAN总线通信控制器

    CAN 总线插卡可以任意插在 PC AT XT 兼容机上,方便地构成分布式监控系统。因此,用 FPGA 实现 CAN
    发表于 07-29 09:43 3643次阅读

    基于FPGACAN总线控制器的设计

    今天给大侠带来基于FPGACAN总线控制器的设计,由于篇幅较长,分三篇。今天带来第一篇,上篇,CAN
    的头像 发表于 05-18 09:21 2617次阅读
    基于<b class='flag-5'>FPGA</b>的<b class='flag-5'>CAN</b><b class='flag-5'>总线</b><b class='flag-5'>控制器</b>的设计

    基于FPGACAN总线通信节点设计

    点击上方 蓝字 关注我们 摘要:以FPGA 代替传统的单片机和外围扩展芯片, 给出了CAN 总线通信节点的详细设计方案。其中以SJA1000为CAN
    的头像 发表于 06-18 11:15 4533次阅读

    基于FPGA轻量级CAN总线控制器

    ISO11898 定义了通信速率为 125 kbps~1 Mbps 的高速 CAN 通信标准,属于闭环总线,传输速率可达1Mbps,总线长度 ≤ 40米。
    的头像 发表于 01-05 09:42 3884次阅读
    基于<b class='flag-5'>FPGA</b>的<b class='flag-5'>轻量级</b><b class='flag-5'>CAN</b><b class='flag-5'>总线</b><b class='flag-5'>控制器</b>

    CAN总线控制器是什么意思

    CAN总线控制器(Controller Area Network Bus Controller)是CAN总线通信系统中的核心部件,它扮演着接
    的头像 发表于 09-03 14:16 3882次阅读