跳到主要内容 FPGA 实现 CAN 总线原理与 Verilog 代码详解 | 极客日志
编程语言
FPGA 实现 CAN 总线原理与 Verilog 代码详解 FPGA 实现 CAN 总线接口涉及物理层、协议层及核心模块设计。文章详解了 CAN 总线的差分信号特性、帧结构及仲裁机制,并提供了基于 50MHz 时钟的 Verilog 代码实现,包括位时序生成、CRC 校验、发送接收模块及顶层整合。同时涵盖硬件连接验证步骤与注意事项,适用于汽车电子及工业控制场景的嵌入式开发参考。
战神 发布于 2026/4/5 更新于 2026/4/13 1 浏览CAN(Controller Area Network,控制器局域网)是一种差分信号、多主从、异步串行通信总线 ,核心特点是高可靠性、实时性、抗干扰能力强,广泛应用于汽车电子、工业控制、智能家居等领域。FPGA 实现 CAN 接口的核心是通过硬件逻辑模拟 CAN 协议的位时序、帧结构、仲裁机制、错误处理,再配合 CAN 收发器(如 TJA1050)实现物理层连接。以下从原理、核心模块设计、Verilog 代码实现、硬件验证四方面详细说明:
一、CAN 总线核心原理
1. 物理层特性
总线电平 :采用差分信号传输,分为两种状态:
显性电平 (Dominant):CAN_H 比 CAN_L 高约 2V(总线电平为 0,优先级高);
隐性电平 (Recessive):CAN_H 与 CAN_L 电压差为 0V(总线电平为 1,优先级低);
总线拓扑 :多节点挂在 CAN_H 和 CAN_L 总线上,总线两端需接 120Ω 终端电阻;
收发器 :FPGA 需通过 CAN 收发器(如 TJA1050)连接总线,FPGA 输出的逻辑电平(TX)转换为差分信号,总线差分信号转换为逻辑电平(RX)给 FPGA。
2. 协议层核心概念
(1)位时序 CAN 的位时间由多个时间量子(TQ)组成,标准位时序划分(以 1Mbps 波特率为例):
同步段(SYNC_SEG) :1TQ,用于节点同步,检测总线电平跳变;
传播段(PROP_SEG) :1~8TQ,补偿总线传输延迟;
相位缓冲段 1(PHASE_SEG1) :1~8TQ,用于相位调整;
相位缓冲段 2(PHASE_SEG2) :1~8TQ,用于相位调整;
重同步跳转宽度(SJW) :1~4TQ,允许节点在同步时调整相位的最大范围;
总位时间 = SYNC_SEG + PROP_SEG + PHASE_SEG1 + PHASE_SEG2(通常为 8~25TQ)。
(2)帧结构(标准数据帧) CAN 帧分为数据帧、远程帧、错误帧、过载帧,最常用的是标准数据帧,结构如下:
字段 长度(位) 描述 帧起始(SOF) 1 显性电平(0),标志帧开始; 仲裁场 11+1 11 位标准 ID(优先级:ID 越小优先级越高)+ RTR 位(0 = 数据帧,1 = 远程帧); 控制场 6 IDE 位(0 = 标准帧,1 = 扩展帧)+ R0 位(保留)+ 4 位 DLC(数据长度 0~8); 数据场 0~64 数据长度由 DLC 决定(1 字节 = 8 位); CRC 场 15+1 15 位 CRC 校验码 + 1 位 CRC 界定符(隐性电平); ACK 场 2 1 位 ACK 位(接收方拉低为应答)+ 1 位 ACK 界定符(隐性电平); 帧结束(EOF) 7 7 位隐性电平,标志帧结束。
(3)关键机制
仲裁机制 :多节点同时发送时,通过 ID 竞争总线,ID 越小优先级越高,发送显性电平的节点获胜,其他节点转为接收;
位填充 :为保证同步,连续 5 个相同电平后插入 1 个相反电平(接收时需解除填充);
错误处理 :节点检测到错误(位错误、填充错误、CRC 错误等)时,发送错误帧(6 个显性电平),通知其他节点;
应答机制 :接收方正确接收数据后,在 ACK 位拉低总线(显性)应答。
二、FPGA 实现 CAN 的核心模块 FPGA 实现 CAN 接口需拆解为物理层接口、位时序模块、发送模块、接收模块、错误处理模块、控制模块,再通过顶层模块整合:
物理层接口 :连接 CAN 收发器(TJA1050),处理 TX/RX 信号;
位时序模块 :生成 CAN 位时间的 TQ 时钟,实现位同步和相位调整;
发送模块 :构建 CAN 帧(标准数据帧),实现位填充、CRC 计算、仲裁逻辑;
接收模块 :解析 CAN 帧,实现位同步、位填充解除、CRC 校验、应答检测;
错误处理模块 :检测总线错误,发送错误帧,管理节点错误状态;
控制模块 :协调各模块工作,提供外部配置接口(如波特率、ID、数据长度等)。
三、Verilog 代码实现(以 50MHz 时钟、500kHz 波特率为例)
1. 全局参数定义 // CAN 参数配置
parameter CLK_FREQ = 50_000_000; // 系统时钟频率(50MHz)
parameter CAN_BAUD = 500_000; // CAN 目标波特率(500kHz)
parameter TQ_COUNT = 10; // 每位包含的 TQ 数量(10TQ/位,2μs/位)
parameter SYNC_SEG = 1; // 同步段(1TQ)
parameter PROP_SEG = 3; // 传播段(3TQ)
parameter PHASE_SEG1 = 3; // 相位缓冲段 1(3TQ)
parameter PHASE_SEG2 = 3; // 相位缓冲段 2(3TQ)
parameter SJW = 2; // 重同步跳转宽度(2TQ)
// CAN 帧字段参数
parameter STD_ID_LEN = 11; // 标准 ID 长度(11 位)
parameter DLC_LEN = 4; // DLC 长度(4 位)
parameter DATA_MAX_LEN = 8; // 最大数据长度(8 字节)
parameter CRC_LEN = 15; // CRC 长度(15 位)
// 状态定义
typedef enum {IDLE, SYNC, ARBITRATION, CONTROL, DATA, CRC, ACK, EOF} can_state_t;
2. 位时序模块(CAN Bit Timing Generator) 功能:生成 TQ 时钟(位时间的最小单位),实现位同步和相位调整。
module can_bit_timing(
input logic clk, // 系统时钟(50MHz)
input logic rst_n, // 复位信号(低电平有效)
input logic can_rx, // CAN 接收信号(来自收发器)
output logic tq_clk, // TQ 时钟
output logic sync_seg, // 同步段标志
output logic prop_seg, // 传播段标志
output logic phase_seg1, // 相位缓冲段 1 标志
output logic phase_seg2, // 相位缓冲段 2 标志
output logic bit_start, // 位开始标志
output logic bit_end // 位结束标志
);
parameter TQ_CLK_FREQ = 5_000_000; // TQ 时钟频率=5MHz
parameter DIVISOR = CLK_FREQ / TQ_CLK_FREQ; // 分频系数=10
logic [3:0] tq_cnt = 4'd0; // TQ 计数器
logic [3:0] bit_cnt = 4'd0; // 位计数器
logic sync_detected = 1'b0; // 同步检测标志
logic can_rx_prev = 1'b1; // CAN 空闲时为隐性电平(1)
// 生成 TQ 时钟
always_ff @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
tq_cnt <= 4'd0;
tq_clk <= 1'b0;
end else begin
if (tq_cnt == DIVISOR/2 - 1) begin
tq_clk <= ~tq_clk;
tq_cnt <= tq_cnt + 1'b1;
end else if (tq_cnt == DIVISOR - 1) begin
tq_clk <= ~tq_clk;
tq_cnt <= 4'd0;
end else begin
tq_cnt <= tq_cnt + 1'b1;
end
end
end
// 位时序分段
always_ff @(posedge tq_clk or negedge rst_n) begin
if (!rst_n) begin
bit_cnt <= 4'd0;
sync_seg <= 1'b0; prop_seg <= 1'b0;
phase_seg1 <= 1'b0; phase_seg2 <= 1'b0;
bit_start <= 1'b0; bit_end <= 1'b0;
sync_detected <= 1'b0;
end else begin
// 同步检测
if (can_rx != can_rx_prev) begin
sync_detected <= 1'b1;
bit_cnt <= 4'd0;
end
// 位计数器递增
if (bit_cnt == TQ_COUNT - 1) begin
bit_cnt <= 4'd0;
bit_end <= 1'b1;
end else begin
bit_cnt <= bit_cnt + 1'b1;
bit_end <= 1'b0;
end
// 时序分段标志
sync_seg <= (bit_cnt < SYNC_SEG) ? 1'b1 : 1'b0;
prop_seg <= (bit_cnt >= SYNC_SEG && bit_cnt < SYNC_SEG + PROP_SEG) ? 1'b1 : 1'b0;
phase_seg1 <= (bit_cnt >= SYNC_SEG + PROP_SEG && bit_cnt < SYNC_SEG + PROP_SEG + PHASE_SEG1) ? 1'b1 : 1'b0;
phase_seg2 <= (bit_cnt >= SYNC_SEG + PROP_SEG + PHASE_SEG1 && bit_cnt < TQ_COUNT) ? 1'b1 : 1'b0;
// 位开始标志
bit_start <= (bit_cnt == 4'd0) ? 1'b1 : 1'b0;
// 同步检测标志清零
if (sync_seg) sync_detected <= 1'b0;
end
end
always_ff @(posedge tq_clk or negedge rst_n) begin
if (!rst_n) can_rx_prev <= 1'b1;
else can_rx_prev <= can_rx;
end
endmodule
3. CRC 计算模块(CAN CRC Generator) 功能:计算 CAN 帧(从 SOF 到数据场)的 15 位 CRC 校验码。
module can_crc(
input logic clk,
input logic rst_n,
input logic crc_en,
input logic data_bit,
output logic [CRC_LEN-1:0] crc_out,
output logic crc_done,
input logic [DLC_LEN-1:0] dlc
);
parameter CRC_LEN = 15;
parameter STD_ID_LEN = 11;
parameter DLC_LEN = 4;
parameter DATA_MAX_LEN = 8;
logic [CRC_LEN:0] crc_reg = {CRC_LEN+1{1'b1}}; // CRC 初始值为全 1
logic [3:0] bit_cnt = 4'd0;
logic total_bits;
always_comb begin
total_bits = 1 + STD_ID_LEN + 1 + 1 + 1 + DLC_LEN + (8 * dlc); // SOF + ID + RTR + IDE + R0 + DLC + 数据
end
always_ff @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
crc_reg <= {CRC_LEN+1{1'b1}};
bit_cnt <= 4'd0;
crc_done <= 1'b0;
end else if (crc_en) begin
// CAN CRC-15 多项式逻辑
crc_reg[0] <= data_bit ^ crc_reg[CRC_LEN];
crc_reg[1] <= crc_reg[0];
crc_reg[2] <= crc_reg[1];
crc_reg[3] <= crc_reg[2] ^ data_bit ^ crc_reg[CRC_LEN];
crc_reg[4] <= crc_reg[3] ^ data_bit ^ crc_reg[CRC_LEN];
crc_reg[5] <= crc_reg[4];
crc_reg[6] <= crc_reg[5];
crc_reg[7] <= crc_reg[6] ^ data_bit ^ crc_reg[CRC_LEN];
crc_reg[8] <= crc_reg[7] ^ data_bit ^ crc_reg[CRC_LEN];
crc_reg[9] <= crc_reg[8];
crc_reg[10] <= crc_reg[9] ^ data_bit ^ crc_reg[CRC_LEN];
crc_reg[11] <= crc_reg[10];
crc_reg[12] <= crc_reg[11];
crc_reg[13] <= crc_reg[12];
crc_reg[14] <= crc_reg[13] ^ data_bit ^ crc_reg[CRC_LEN];
crc_reg[15] <= crc_reg[14] ^ data_bit ^ crc_reg[CRC_LEN];
if (bit_cnt == total_bits - 1) begin
crc_done <= 1'b1;
bit_cnt <= 4'd0;
end else begin
bit_cnt <= bit_cnt + 1'b1;
crc_done <= 1'b0;
end
end else begin
crc_done <= 1'b0;
end
end
assign crc_out = crc_reg[CRC_LEN-1:0];
endmodule
4. 发送模块(CAN Transmitter) 功能:构建标准数据帧,实现位填充、CRC 计算、仲裁逻辑。
module can_transmitter(
input logic clk,
input logic rst_n,
input logic tq_clk,
input logic sync_seg,
input logic phase_seg1,
input logic phase_seg2,
input logic bit_end,
input logic can_rx,
input logic tx_en,
input logic [STD_ID_LEN-1:0] std_id,
input logic rtr,
input logic [DLC_LEN-1:0] dlc,
input logic [DATA_MAX_LEN*8-1:0] data,
output logic can_tx,
output logic tx_done,
output logic tx_error
);
typedef enum {IDLE, SYNC, ARBITRATION, CONTROL, DATA, CRC, ACK, EOF} can_state_t;
can_state_t state = IDLE;
logic [3:0] bit_cnt = 4'd0;
logic [7:0] data_byte = 8'd0;
logic [15:0] crc_val;
logic crc_en;
logic crc_done;
logic [5:0] stuff_cnt = 6'd0;
logic stuff_bit = 1'b0;
logic stuff_bit_prev = 1'b1;
logic data_bit;
// 实例化 CRC 模块
can_crc u_crc (
.clk(clk), .rst_n(rst_n), .crc_en(crc_en),
.data_bit(data_bit), .crc_out(crc_val), .crc_done(crc_done), .dlc(dlc)
);
// 状态机控制
always_ff @(posedge tq_clk or negedge rst_n) begin
if (!rst_n) begin
state <= IDLE; bit_cnt <= 4'd0; data_byte <= 8'd0;
can_tx <= 1'b1; tx_done <= 1'b0; tx_error <= 1'b0;
stuff_cnt <= 6'd0; stuff_bit <= 1'b0; crc_en <= 1'b0;
end else begin
case (state)
IDLE: begin
tx_done <= 1'b0; tx_error <= 1'b0; stuff_cnt <= 6'd0;
if (tx_en) begin
state <= SYNC; bit_cnt <= 4'd0;
can_tx <= 1'b0; crc_en <= 1'b1; data_bit <= 1'b0;
end else begin
can_tx <= 1'b1;
end
end
SYNC: begin
if (bit_end) begin
state <= ARBITRATION; bit_cnt <= 4'd0;
can_tx <= std_id[STD_ID_LEN-1 - bit_cnt];
data_bit <= std_id[STD_ID_LEN-1 - bit_cnt];
if (can_rx != can_tx) begin
state <= IDLE; tx_error <= 1'b1;
end
end else begin
if (can_tx == stuff_bit_prev) begin
stuff_cnt <= stuff_cnt + 1'b1;
if (stuff_cnt == 5'd5) begin
can_tx <= ~can_tx; stuff_cnt <= 6'd0; stuff_bit <= 1'b1; crc_en <= 1'b0;
end
end else begin
stuff_cnt <= 6'd0; stuff_bit <= 1'b0; crc_en <= 1'b1;
end
end
end
// 后续状态(ARBITRATION、CONTROL、DATA、CRC、ACK、EOF)按帧结构发送对应字段
// 此处省略详细状态跳转,核心逻辑:按帧字段顺序发送,位填充,仲裁检测,CRC 计算
EOF: begin
if (bit_end) begin
state <= IDLE; tx_done <= 1'b1;
end
end
default: state <= IDLE;
endcase
end
end
always_ff @(posedge tq_clk or negedge rst_n) begin
if (!rst_n) stuff_bit_prev <= 1'b1;
else stuff_bit_prev <= can_tx;
end
always_comb begin
case (state)
SYNC: data_bit <= 1'b0; // SOF
ARBITRATION: data_bit <= std_id[STD_ID_LEN-1 - bit_cnt]; // ID 位
CONTROL: data_bit <= (bit_cnt == 0) ? 1'b0 : (bit_cnt == 1) ? 1'b0 : (bit_cnt >= 2 && bit_cnt < 2+DLC_LEN) ? dlc[DLC_LEN-1 - (bit_cnt-2)] : 1'b0;
DATA: data_bit <= data_byte[7 - (bit_cnt % 8)]; // 数据位
default: data_bit <= 1'b0;
endcase
end
endmodule
5. 接收模块(CAN Receiver) 功能:解析 CAN 帧,实现位同步、位填充解除、CRC 校验、应答检测。
module can_receiver(
input logic clk,
input logic rst_n,
input logic tq_clk,
input logic sync_seg,
input logic phase_seg1,
input logic phase_seg2,
input logic bit_end,
input logic can_rx,
output logic rx_done,
output logic rx_error,
output logic [STD_ID_LEN-1:0] rx_std_id,
output logic rx_rtr,
output logic [DLC_LEN-1:0] rx_dlc,
output logic [DATA_MAX_LEN*8-1:0] rx_data
);
typedef enum {IDLE, SYNC, ARBITRATION, CONTROL, DATA, CRC, ACK, EOF} can_state_t;
can_state_t state = IDLE;
logic [3:0] bit_cnt = 4'd0;
logic [7:0] data_byte = 8'd0;
logic [15:0] crc_val;
logic [15:0] calc_crc;
logic crc_en;
logic crc_done;
logic [5:0] stuff_cnt = 6'd0;
logic stuff_bit = 1'b0;
logic stuff_bit_prev = 1'b1;
// 实例化 CRC 模块
can_crc u_crc (
.clk(clk), .rst_n(rst_n), .crc_en(crc_en),
.data_bit(can_rx), .crc_out(calc_crc), .crc_done(crc_done), .dlc(rx_dlc)
);
// 状态机控制
always_ff @(posedge tq_clk or negedge rst_n) begin
if (!rst_n) begin
state <= IDLE; bit_cnt <= 4'd0; data_byte <= 8'd0;
rx_done <= 1'b0; rx_error <= 1'b0;
rx_std_id <= {STD_ID_LEN{1'b0}}; rx_rtr <= 1'b0;
rx_dlc <= {DLC_LEN{1'b0}}; rx_data <= {DATA_MAX_LEN*8{1'b0}};
stuff_cnt <= 6'd0; stuff_bit <= 1'b0; crc_en <= 1'b0;
end else begin
case (state)
IDLE: begin
rx_done <= 1'b0; rx_error <= 1'b0; stuff_cnt <= 6'd0;
if (can_rx == 1'b0 && sync_seg) begin
state <= SYNC; bit_cnt <= 4'd0;
crc_en <= 1'b1;
end
end
SYNC: begin
if (bit_end) begin
state <= ARBITRATION; bit_cnt <= 4'd0;
end
if (can_rx == stuff_bit_prev) begin
stuff_cnt <= stuff_cnt + 1'b1;
if (stuff_cnt == 5'd5) begin
stuff_bit <= 1'b1; stuff_cnt <= 6'd0;
end
end else begin
stuff_cnt <= 6'd0; stuff_bit <= 1'b0;
end
end
ARBITRATION: begin
if (bit_end && !stuff_bit) begin
if (bit_cnt == STD_ID_LEN - 1) begin
rx_std_id[STD_ID_LEN-1 - bit_cnt] <= can_rx;
state <= CONTROL; bit_cnt <= 4'd0;
end else begin
rx_std_id[STD_ID_LEN-1 - bit_cnt] <= can_rx;
bit_cnt <= bit_cnt + 1'b1;
end
end else if (stuff_bit) begin
stuff_bit <= 1'b0;
end
crc_en <= !stuff_bit;
end
// 后续状态(CONTROL、DATA、CRC、ACK、EOF)类似,按帧结构接收对应字段,位填充解除,CRC 校验
EOF: begin
if (bit_end) begin
state <= IDLE; rx_done <= 1'b1;
if (calc_crc != crc_val) rx_error <= 1'b1;
end
end
default: state <= IDLE;
endcase
end
end
always_ff @(posedge tq_clk or negedge rst_n) begin
if (!rst_n) stuff_bit_prev <= 1'b1;
else stuff_bit_prev <= can_rx;
end
endmodule
6. 顶层模块(CAN Top Module) 功能:整合位时序、发送、接收模块,提供与 CAN 收发器的物理接口和外部配置接口。
module can_top(
input logic clk,
input logic rst_n,
input logic tx_en,
input logic [STD_ID_LEN-1:0] std_id,
input logic rtr,
input logic [DLC_LEN-1:0] dlc,
input logic [DATA_MAX_LEN*8-1:0] data,
output logic can_tx,
input logic can_rx,
output logic tx_done,
output logic tx_error,
output logic rx_done,
output logic rx_error,
output logic [STD_ID_LEN-1:0] rx_std_id,
output logic rx_rtr,
output logic [DLC_LEN-1:0] rx_dlc,
output logic [DATA_MAX_LEN*8-1:0] rx_data
);
logic tq_clk, sync_seg, prop_seg, phase_seg1, phase_seg2, bit_start, bit_end;
can_bit_timing u_bit_timing (
.clk(clk), .rst_n(rst_n), .can_rx(can_rx),
.tq_clk(tq_clk), .sync_seg(sync_seg), .prop_seg(prop_seg),
.phase_seg1(phase_seg1), .phase_seg2(phase_seg2),
.bit_start(bit_start), .bit_end(bit_end)
);
can_transmitter u_transmitter (
.clk(clk), .rst_n(rst_n), .tq_clk(tq_clk),
.sync_seg(sync_seg), .phase_seg1(phase_seg1), .phase_seg2(phase_seg2),
.bit_end(bit_end), .can_rx(can_rx), .tx_en(tx_en),
.std_id(std_id), .rtr(rtr), .dlc(dlc), .data(data),
.can_tx(can_tx), .tx_done(tx_done), .tx_error(tx_error)
);
can_receiver u_receiver (
.clk(clk), .rst_n(rst_n), .tq_clk(tq_clk),
.sync_seg(sync_seg), .phase_seg1(phase_seg1), .phase_seg2(phase_seg2),
.bit_end(bit_end), .can_rx(can_rx),
.rx_done(rx_done), .rx_error(rx_error),
.rx_std_id(rx_std_id), .rx_rtr(rx_rtr), .rx_dlc(rx_dlc), .rx_data(rx_data)
);
endmodule
四、硬件验证
1. 硬件连接
FPGA ↔ CAN 收发器(TJA1050) :
FPGA 的 can_tx → TJA1050 的 TXD;
FPGA 的 can_rx → TJA1050 的 RXD;
FPGA 的 VCC(3.3V)→ TJA1050 的 VCC;
FPGA 的 GND → TJA1050 的 GND;
CAN 收发器 ↔ CAN 总线 :
TJA1050 的 CAN_H → CAN 总线 CAN_H;
TJA1050 的 CAN_L → CAN 总线 CAN_L;
CAN 总线两端接 120Ω 终端电阻;
其他 :FPGA 需提供 50MHz 时钟和复位信号(可通过按键或外部电路实现)。
2. 验证步骤
参数配置 :通过 FPGA 的配置接口(如 JTAG)设置发送参数(ID=0x001,DLC=2,数据 = 0x1234,波特率 = 500kHz);
发送数据 :触发 tx_en 信号,FPGA 生成 CAN 标准数据帧并发送到总线;
接收验证 :
若总线上有其他 CAN 节点(如 CANoe 仿真节点、另一块 FPGA 开发板),可接收并解析该帧,验证 ID、数据、DLC 是否正确;
若只有一块 FPGA,可将 can_tx 直接连接到 can_rx(回环测试),FPGA 接收自己发送的数据,通过 rx_done 和 rx_data 确认接收正确;
错误测试 :故意修改发送数据,验证 rx_error 是否能检测到 CRC 错误。
五、关键注意事项与扩展功能
1. 注意事项
时序精确性 :CAN 位时序对传输可靠性至关重要,需严格按照协议规范设计 TQ 时钟和位段划分,避免非整数分频导致的时序误差;
位填充与解除 :发送时需正确插入填充位,接收时需准确解除填充,否则会导致帧解析错误;
仲裁机制 :多节点通信时,需确保仲裁逻辑正确,避免总线冲突;
收发器匹配 :CAN 收发器的电平需与 FPGA 的 IO 电平匹配(通常为 3.3V),否则需添加电平转换电路;
终端电阻 :CAN 总线必须接终端电阻,否则信号反射会导致通信失败。
2. 扩展功能
扩展帧支持 :在帧结构中添加 29 位扩展 ID,修改仲裁场和控制场的处理逻辑;
多帧发送 / 接收 :添加 FIFO 缓冲区,支持连续多帧数据的收发,避免数据丢失;
ID 过滤 :接收模块添加 ID 过滤逻辑,只接收特定 ID 的帧,减少无效数据处理;
错误管理 :完善错误处理模块,支持错误计数器管理和总线关闭恢复;
波特率自适应 :设计波特率检测逻辑,支持自动识别总线波特率。
六、总结 FPGA 实现 CAN 接口的核心是严格遵循 CAN 协议的时序和帧结构,通过硬件逻辑实现位时序生成、帧构建与解析、仲裁、错误处理等功能。相比单片机的 CAN 控制器,FPGA 的硬件实现具有实时性强、可定制性高、并行处理能力强的优势,适用于对通信速率和可靠性要求较高的场景。实际应用中,可根据需求扩展扩展帧、ID 过滤、多帧收发等功能,适配复杂的 CAN 总线系统。
微信扫一扫,关注极客日志 微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
相关免费在线工具 Base64 字符串编码/解码 将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
Base64 文件转换器 将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
Markdown 转 HTML 将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML 转 Markdown 互为补充。 在线工具,Markdown 转 HTML在线工具,online
HTML 转 Markdown 将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML 转 Markdown在线工具,online
JSON 压缩 通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online
JSON美化和格式化 将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online