FPGA 实现CAN通信

使用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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值