使用FPGA+SJA 1000芯片实现CAN通信。核心思路是对集成CAN协议的芯片尽心配置,来进行CAN通信。核心顶层代码:
//-- Company:
//-- Engineer:
//--
//-- Create Date: 11:18:25 12/01/2021
//-- Design Name:
//-- Module Name: con_port - Behavioral
//-- Project Name:
//-- Target Devices:
//-- Tool versions:
//-- Description: peliCAN
//-- Dependencies:
//-- -- Revision date author description
//-- v1.0 12/01/2021 HLC File Created
// ???sja1000???????? FPGA up?????sja1000 up?????????????????
//2020?12?26?14:43:01
//???????????????????????????????
//??????????????
//2021?1?14?11:17:04 ??????????????
module can_port (
input clk_in ,//clk==40m
input reset ,
input re_config ,//????? ????????????????sja1000
input can_auto_reset ,//CAN????? 5s?????????????sja1000
/*input [7:0] CAN_ID0_tx ,//ID1-4???????ID?
input [7:0] CAN_ID1_tx ,//ID0????(frame information)
input [7:0] CAN_ID2_tx ,
input [7:0] CAN_ID3_tx ,//EFF
input [7:0] CAN_ID4_tx ,//EFF
input [7:0] CAN_DATA1_tx ,//?????8????
input [7:0] CAN_DATA2_tx ,
input [7:0] CAN_DATA3_tx ,
input [7:0] CAN_DATA4_tx ,
input [7:0] CAN_DATA5_tx ,
input [7:0] CAN_DATA6_tx ,
input [7:0] CAN_DATA7_tx ,
input [7:0] CAN_DATA8_tx ,*/
output reg[7:0]CAN_ID0_rx ,//ID1-4???????ID?
output reg[7:0]CAN_ID1_rx ,//ID0????(frame information)
output reg[7:0]CAN_ID2_rx ,
output reg[7:0]CAN_ID3_rx ,//EFF
output reg[7:0]CAN_ID4_rx ,//EFF
output reg[7:0]CAN_DATA1_rx ,//????8????
output reg[7:0]CAN_DATA2_rx ,
output reg[7:0]CAN_DATA3_rx ,
output reg[7:0]CAN_DATA4_rx ,
output reg[7:0]CAN_DATA5_rx ,
output reg[7:0]CAN_DATA6_rx ,
output reg[7:0]CAN_DATA7_rx ,
output reg[7:0]CAN_DATA8_rx ,
//ATTENTION! The real CAN_ID received, is equal to
//{3'b000, CAN_ID1_rx, CAN_ID2_rx, CAN_ID3_rx, CAN_ID4_rx[7:3]};
//which seems like right shift 3 bits.
input CAN_DATA_SEND_EN ,//?????? ???????????
output reg CAN_DATA_SEND_DONE ,//???????? ?????????????
output reg CAN_DATA_RECV_DONE ,//???????? ?????????CAN_DATA_rx???
output reg DATA_RECEIVE_DO ,//????????????????
output CAN_ALE ,//??sja1000?????
output CAN_WR ,//??sja1000?????
output CAN_RD ,//??sja1000?????
output CAN_CS ,//??sja1000?????
output reg CAN_RST ,//??sja1000?????
// CAN_clk_in ,//??sja1000?????
inout [7:0] DATA_CAN ,//??sja1000???ad??
output en //?????? DATA_CAN????SJA1000??????? en?????????
);
//for watching
(*KEEP = "TRUE"*) reg[7:0]tmp_CAN_ID0_rx;
(*KEEP = "TRUE"*) reg[7:0]tmp_CAN_ID1_rx;
(*KEEP = "TRUE"*) reg[7:0]tmp_CAN_ID2_rx;
(*KEEP = "TRUE"*) reg[7:0]tmp_CAN_ID3_rx;
(*KEEP = "TRUE"*) reg[7:0]tmp_CAN_ID4_rx;
(*KEEP = "TRUE"*) reg[7:0]tmp_CAN_DATA1_rx;
(*KEEP = "TRUE"*) reg[7:0]tmp_CAN_DATA2_rx;
(*KEEP = "TRUE"*) reg[7:0]tmp_CAN_DATA3_rx;
(*KEEP = "TRUE"*) reg[7:0]tmp_CAN_DATA4_rx;
(*KEEP = "TRUE"*) reg[7:0]tmp_CAN_DATA5_rx;
(*KEEP = "TRUE"*) reg[7:0]tmp_CAN_DATA6_rx;
(*KEEP = "TRUE"*) reg[7:0]tmp_CAN_DATA7_rx;
(*KEEP = "TRUE"*) reg[7:0]tmp_CAN_DATA8_rx;
always @ (posedge clk_in or posedge reset) begin
if (reset) begin
tmp_CAN_ID0_rx <= 8'h00;
tmp_CAN_ID1_rx <= 8'h00;
tmp_CAN_ID2_rx <= 8'h00;
tmp_CAN_ID3_rx <= 8'h00;
tmp_CAN_ID4_rx <= 8'h00;
tmp_CAN_DATA1_rx <= 8'h00;
tmp_CAN_DATA2_rx <= 8'h00;
tmp_CAN_DATA3_rx <= 8'h00;
tmp_CAN_DATA4_rx <= 8'h00;
tmp_CAN_DATA5_rx <= 8'h00;
tmp_CAN_DATA6_rx <= 8'h00;
tmp_CAN_DATA7_rx <= 8'h00;
tmp_CAN_DATA8_rx <= 8'h00;
end
else if (DATA_RECEIVE_DO) begin
tmp_CAN_ID0_rx <= CAN_ID0_rx;
tmp_CAN_ID1_rx <= CAN_ID1_rx;
tmp_CAN_ID2_rx <= CAN_ID2_rx;
tmp_CAN_ID3_rx <= CAN_ID3_rx;
tmp_CAN_ID4_rx <= CAN_ID4_rx;
tmp_CAN_DATA1_rx <= CAN_DATA1_rx;
tmp_CAN_DATA2_rx <= CAN_DATA2_rx;
tmp_CAN_DATA3_rx <= CAN_DATA3_rx;
tmp_CAN_DATA4_rx <= CAN_DATA4_rx;
tmp_CAN_DATA5_rx <= CAN_DATA5_rx;
tmp_CAN_DATA6_rx <= CAN_DATA6_rx;
tmp_CAN_DATA7_rx <= CAN_DATA7_rx;
tmp_CAN_DATA8_rx <= CAN_DATA8_rx;
end
else begin
tmp_CAN_ID0_rx <= tmp_CAN_ID0_rx ;
tmp_CAN_ID1_rx <= tmp_CAN_ID1_rx ;
tmp_CAN_ID2_rx <= tmp_CAN_ID2_rx ;
tmp_CAN_ID3_rx <= tmp_CAN_ID3_rx ;
tmp_CAN_ID4_rx <= tmp_CAN_ID4_rx ;
tmp_CAN_DATA1_rx <= tmp_CAN_DATA1_rx ;
tmp_CAN_DATA2_rx <= tmp_CAN_DATA2_rx ;
tmp_CAN_DATA3_rx <= tmp_CAN_DATA3_rx ;
tmp_CAN_DATA4_rx <= tmp_CAN_DATA4_rx ;
tmp_CAN_DATA5_rx <= tmp_CAN_DATA5_rx ;
tmp_CAN_DATA6_rx <= tmp_CAN_DATA6_rx ;
tmp_CAN_DATA7_rx <= tmp_CAN_DATA7_rx ;
tmp_CAN_DATA8_rx <= tmp_CAN_DATA8_rx ;
end
end
//===================================================================================
//??ID???????? at 2021?1?13?14:35:51
//SJA1000T????29??ID28-ID0????ID????ID??3bit?
//?CAN???????ID?????????????3bit??????? ID_test ??
//CAN?????ID??SJA1000T????ID???3bit?????ID????3bit??
//real_recv_id = {3'b000, CAN_ID1_rx, CAN_ID2_rx, CAN_ID3_rx, CAN_ID4_rx[7:3]};
//====================================================================================
reg [31:0] real_recv_id;
//wire real_recv_id = CAN_DATA_RECV_DONE ? {3'b000, CAN_ID1_rx, CAN_ID2_rx, CAN_ID3_rx, CAN_ID4_rx[7:3]} : 32'b0;
always @ (posedge clk_in or posedge reset) begin
if (reset)
real_recv_id <= 32'b0;
else if (CAN_DATA_RECV_DONE)
real_recv_id <= {3'b000, CAN_ID1_rx, CAN_ID2_rx, CAN_ID3_rx, CAN_ID4_rx[7:3]};
else
real_recv_id <= real_recv_id;
end
//?????????????IO banks??????????input???????
//???????????????
//?????????
parameter ID_test = 32'h0C080C00; //ID_test[31:0];
parameter CAN_ID0_tx = 8'b1000_1000;//{FF, RTR, 0, 0, DLC3, DLC2, DLC1, DLC0};
parameter CAN_ID1_tx = ID_test[28:21];
parameter CAN_ID2_tx = ID_test[20:13];
parameter CAN_ID3_tx = ID_test[12:05];
parameter CAN_ID4_tx = {ID_test[4:0], 3'b000};//this seems like left shift 3 bits.
parameter CAN_DATA1_tx = 8'h90; //??DYT??????3547200ms, ?'h8A90
parameter CAN_DATA2_tx = 8'h8A; //????????????????
parameter CAN_DATA3_tx = 8'h06; //??'h90_8A_00_00_00_00_00_00
parameter CAN_DATA4_tx = 8'h05; //????????CAN_DATA?????00???
parameter CAN_DATA5_tx = 8'h04;
parameter CAN_DATA6_tx = 8'h03;
parameter CAN_DATA7_tx = 8'h02;
parameter CAN_DATA8_tx = 8'h01;
parameter INIT_RESET =5'b00001,
INIT =5'b00010,
IDLE =5'b00100,
DATA_READ =5'b01000,
DATA_SEND =5'b10000;
reg [4:0] state_c,state_n;
//********************************************
reg read_act_path;
reg read_write0 ;
reg [7:0] read_addr_path;
reg [7:0] read_data_path;
reg [3:0] read_state ;
reg [3:0] read_cnt ;
reg read_finish ;//********************************************
//**************************************************************************************
reg act ;
reg write0 ;
wire recv_done_path ;
wire send_done_path ;
reg [7:0] need_addr_path ;
wire[7:0] recv_data_path ;
reg [7:0] s_data_path ;
//new adding at 2021?1?14?11:18:01
(*KEEP = "TRUE"*) reg [3:0] tx_DLC; //tx data length counter
(*KEEP = "TRUE"*) reg [3:0] rx_DLC; //rx data length counter
always @ (posedge clk_in or posedge reset) begin
if (reset)
tx_DLC <= 4'h0;
else if (state_n == DATA_SEND) begin
tx_DLC <= ((CAN_ID0_tx[3] << 3) + (CAN_ID0_tx[2] << 2) + (CAN_ID0_tx[1] << 1) + CAN_ID0_tx[0]);
end
else
tx_DLC <= 4'h0;
end
always @ (posedge clk_in or posedge reset) begin
if (reset)
rx_DLC <= 4'h0;
else if ((state_n == DATA_READ)) begin
if ((read_cnt == 4'd1) && recv_done_path)
rx_DLC <= ((CAN_ID0_rx[3] << 3) + (CAN_ID0_rx[2] << 2) + (CAN_ID0_rx[1] << 1) + CAN_ID0_rx[0]);
else
rx_DLC <= rx_DLC;
end
else
rx_DLC <= 4'h0;
end
//========================================================
//for watching
//========================================================
(*KEEP

最低0.47元/天 解锁文章
1万+

被折叠的 条评论
为什么被折叠?



