基于FPGA驱动SJA1000T实现CAN通信:标准帧与扩展帧的奇妙之旅
基于FPGA的CAN通信,FPGA驱动SJA1000T芯片代码,实现标准帧与扩展帧的通信驱动,已上板调通 品牌型号 CAN SJA1000T 与市面上的不同,代码不是SJA1000T芯片代码,而是驱动该芯片的代码。
最近搞了个基于FPGA的CAN通信项目,成功驱动SJA1000T芯片,并且实现了标准帧与扩展帧的通信驱动,还顺利上板调通啦,迫不及待来和大家分享下。
为啥选FPGA和SJA1000T
FPGA(现场可编程门阵列)灵活性强,可根据需求定制硬件逻辑,对于实现CAN这种复杂通信协议特别合适。而SJA1000T是经典的CAN控制器芯片,很多老项目都在用,稳定性杠杠的。两者结合,就能打造一个可靠的CAN通信系统。
驱动代码关键部分及分析
初始化部分
module sja1000t_driver ( input wire clk, input wire rst_n, // 其他接口信号 ); reg [7:0] mode_reg; always @(posedge clk or negedge rst_n) begin if (!rst_n) begin mode_reg <= 8'h00; end else begin // 初始化模式寄存器,配置为复位模式 mode_reg <= 8'h04; end end这里定义了一个模式寄存器modereg,在复位信号rstn有效时,将其清零。正常工作时,设置为8'h04进入复位模式。在复位模式下,我们可以对芯片的其他寄存器进行配置,比如波特率设置、验收滤波器设置等。这就好比我们要开车,得先把车钥匙拧到“ON”位置,让车子各项系统准备好。
发送数据部分
always @(posedge clk or negedge rst_n) begin if (!rst_n) begin // 发送相关信号清零 end else begin if (send_enable) begin // 检查SJA1000T是否准备好接收数据 if (sja1000t_status[0]) begin // 将数据写入SJA1000T的发送缓冲区 sja1000t_write_address <= 8'h04; sja1000t_write_data <= send_data; sja1000t_write_enable <= 1'b1; end else begin sja1000t_write_enable <= 1'b0; end end else begin sja1000t_write_enable <= 1'b0; end end end当sendenable信号有效时,先检查SJA1000T芯片的状态信号sja1000tstatus[0],只有当它为高电平时,表示芯片准备好接收数据,我们才把要发送的数据senddata写入到芯片的发送缓冲区(地址8'h04),同时置sja1000twriteenable为高电平,就像把货物搬到传送带上,准备发送出去。如果芯片没准备好,那就先等等,把sja1000twrite_enable置为低电平。
接收数据部分
always @(posedge clk or negedge rst_n) begin if (!rst_n) begin // 接收相关信号清零 end else begin if (sja1000t_status[1]) begin // SJA1000T有数据可接收 sja1000t_read_address <= 8'h0C; sja1000t_read_enable <= 1'b1; receive_data <= sja1000t_read_data; end else begin sja1000t_read_enable <= 1'b0; end end end当sja1000tstatus[1]为高电平时,说明SJA1000T芯片有数据可接收啦。这时,我们把读取地址设置为8'h0C,这是接收缓冲区的地址,然后置sja1000treadenable为高电平,把数据读出来存到receivedata里,就像从信箱里把信拿出来一样。
标准帧与扩展帧处理
在驱动代码里,对标准帧和扩展帧的处理主要体现在数据的打包和解包上。对于标准帧,标识符(ID)是11位,而扩展帧的ID是29位。发送的时候,根据不同的帧类型,把ID和数据按相应格式组装好写入芯片;接收的时候,再按格式解析出来。
// 发送标准帧示例 if (frame_type == 1'b0) begin // 标准帧 sja1000t_write_data[10:0] <= standard_frame_id; // 其他数据位填充 end else begin // 扩展帧 sja1000t_write_data[28:0] <= extended_frame_id; // 其他数据位填充 end这里通过frame_type信号判断是标准帧还是扩展帧,然后把对应的ID写入到发送数据中。
上板调试的一些坑和解决办法
上板调试时,遇到了不少问题。比如一开始通信不稳定,老是丢帧。检查后发现是硬件连接有点小问题,重新焊接了一下SJA1000T芯片和FPGA之间的连接线,问题就解决了。还有波特率配置,一开始设置错了,导致两边通信对不上,仔细核对数据手册,重新调整波特率寄存器的值,通信就正常了。
基于FPGA的CAN通信,FPGA驱动SJA1000T芯片代码,实现标准帧与扩展帧的通信驱动,已上板调通 品牌型号 CAN SJA1000T 与市面上的不同,代码不是SJA1000T芯片代码,而是驱动该芯片的代码。
总之,基于FPGA驱动SJA1000T实现CAN通信,虽然过程有点曲折,但最终成功的那一刻,成就感满满。希望我的分享能给大家在类似项目中提供一些参考。
