0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

CAN通信物理層和協(xié)議層簡介

FPGA設(shè)計(jì)論壇 ? 來源:CSDN技術(shù)社區(qū) ? 作者:撕裂的牛仔褲 ? 2022-06-09 16:27 ? 次閱讀

1、CAN物理層和協(xié)議層

CAN與串口類似,都是異步通信,利用兩根差分線來進(jìn)行信號(hào)的傳輸。

在多節(jié)點(diǎn)進(jìn)行數(shù)據(jù)傳輸時(shí)主要分為遵循ISO11898標(biāo)準(zhǔn)的高速短距離閉環(huán)形式和遵循ISO11519標(biāo)準(zhǔn)的低速遠(yuǎn)距離開環(huán)網(wǎng)絡(luò)。這兩種形式主要是在硬件設(shè)計(jì)時(shí)根據(jù)實(shí)際應(yīng)用情況加入120歐姆或者2.2千歐姆電阻。

在CAN通信時(shí)信號(hào)邏輯和平時(shí)常用的電平表示不太一樣,根據(jù)標(biāo)準(zhǔn)電平表示形式如下圖:

b722c414-e7a9-11ec-ba43-dac502259ad0.png

b7434810-e7a9-11ec-ba43-dac502259ad0.png

CAN報(bào)文類型有5種,分別是數(shù)據(jù)幀、遙控幀、錯(cuò)誤幀、過載幀、幀間隔。而我們常用的是數(shù)據(jù)幀,數(shù)據(jù)幀分為標(biāo)準(zhǔn)數(shù)據(jù)幀和擴(kuò)展數(shù)據(jù)幀兩種。數(shù)據(jù)幀結(jié)構(gòu)如下圖:

b76ab81e-e7a9-11ec-ba43-dac502259ad0.png

數(shù)據(jù)幀是以一個(gè)下降沿的電平來開始界定開始的。以7個(gè)連續(xù)隱性電平結(jié)束的。數(shù)據(jù)幀中間包含幀起始、仲裁段、控制段、數(shù)據(jù)段、CRC段、ACK段和幀結(jié)束段。

幀起始SOF段(Start Of Frame),幀起始信號(hào)只有一個(gè)數(shù)據(jù)位,是一個(gè)顯性電平,它用于監(jiān)測(cè)數(shù)據(jù)傳輸?shù)拈_始,通過電平跳變沿來進(jìn)行數(shù)據(jù)起始位的確定。

仲裁段:內(nèi)容是數(shù)據(jù)幀的ID信息,標(biāo)準(zhǔn)幀ID長度是11位,擴(kuò)展幀為18位。CAN 協(xié)議不對(duì)掛載在它之上的節(jié)點(diǎn)分配優(yōu)先級(jí)和地址,對(duì)總線的占有權(quán)是由幀的ID決定的,對(duì)于重要信息給與一個(gè)優(yōu)先級(jí)較高的ID,這樣數(shù)據(jù)就能及時(shí)的發(fā)送出去。而ID優(yōu)先級(jí)的仲裁原則是由物理層決定的,總線狀態(tài)總是顯性電平掩蓋隱形電平,因此顯性ID優(yōu)先級(jí)較高。

仲裁段還包括(1)RTR 位(Remote Transmission Request Bit),譯作遠(yuǎn)程傳輸請(qǐng)求位,它是用于區(qū)分?jǐn)?shù)據(jù)幀和遙控幀的,當(dāng)它為顯性電平時(shí)表示數(shù)據(jù)幀,隱性電平時(shí)表示遙控幀。

(2) IDE 位(Identifier Extension Bit),譯作標(biāo)識(shí)符擴(kuò)展位,它是用于區(qū)分標(biāo)準(zhǔn)格式與擴(kuò)展格式,當(dāng)它為顯性電平時(shí)表示標(biāo)準(zhǔn)格式,隱性電平時(shí)表示擴(kuò)展格式。

(3) SRR 位(Substitute Remote Request Bit),只存在于擴(kuò)展格式,它用于替代標(biāo)準(zhǔn)格式中的

RTR 位。由于擴(kuò)展幀中的SRR 位為隱性位,RTR 在數(shù)據(jù)幀為顯性位,所以在兩個(gè)ID相同的標(biāo)準(zhǔn)格式報(bào)文與擴(kuò)展格式報(bào)文中,標(biāo)準(zhǔn)格式的優(yōu)先級(jí)較高。

控制段:在控制段中的r1 和r0 為保留位,默認(rèn)設(shè)置為顯性位。它最主要的是DLC 段(Data

Length Code),譯為數(shù)據(jù)長度碼,它由4 個(gè)數(shù)據(jù)位組成,用于表示本報(bào)文中的數(shù)據(jù)段含有多

少個(gè)字節(jié),DLC 段表示的數(shù)字為0~8。

數(shù)據(jù)段:數(shù)據(jù)段為數(shù)據(jù)幀的核心內(nèi)容,它是節(jié)點(diǎn)要發(fā)送的原始信息,由0~8 個(gè)字節(jié)組成,MSB先行。

CRC 段:為了保證報(bào)文的正確傳輸,CAN 的報(bào)文包含了一段15 位的CRC 校驗(yàn)碼,一旦接收節(jié)點(diǎn)算出的CRC 碼跟接收到的CRC 碼不同,則它會(huì)向發(fā)送節(jié)點(diǎn)反饋出錯(cuò)信息,利用錯(cuò)誤幀請(qǐng)求它重新發(fā)送。CRC 部分的計(jì)算一般由CAN 控制器硬件完成,出錯(cuò)時(shí)的處理則由軟件控制最大重發(fā)數(shù)。

ACK 段:ACK 段包括一個(gè)ACK 槽位,和ACK 界定符位。類似I2C 總線,在ACK 槽位中,發(fā)送節(jié)點(diǎn)發(fā)送的是隱性位,而接收節(jié)點(diǎn)則在這一位中發(fā)送顯性位以示應(yīng)答。在ACK 槽和幀結(jié)束之間由ACK 界定符間隔開。

幀結(jié)束EOF 段(End Of Frame),幀結(jié)束段由發(fā)送節(jié)點(diǎn)發(fā)送的7 個(gè)隱性位表示結(jié)束。

2、傳輸?shù)牟ㄌ芈?/span>

CAN由于是異步通信,通信波特率與串口波特率定義類似,波特率的定義有每個(gè)子的長度來確定的。CAN的通信距離與波特率存在負(fù)相關(guān)關(guān)系,波特率越高,傳輸距離越短。CAN通信波特率與傳輸距離關(guān)系如下圖:

b79623c8-e7a9-11ec-ba43-dac502259ad0.png

3、FPGA實(shí)現(xiàn)思路

在進(jìn)行FPGA實(shí)現(xiàn)時(shí)主要是實(shí)現(xiàn)一個(gè)完備的狀態(tài)轉(zhuǎn)移狀態(tài)機(jī)。在設(shè)計(jì)狀態(tài)機(jī)時(shí)需要對(duì)最復(fù)雜的包格式進(jìn)行設(shè)計(jì)。通過對(duì)控制段進(jìn)行判斷來跳轉(zhuǎn)到不同類型幀格式的狀態(tài),根據(jù)數(shù)據(jù)長度來完成對(duì)數(shù)據(jù)的接收和發(fā)送。由于FPGA實(shí)現(xiàn)完備的CAN收發(fā)驅(qū)動(dòng)并不是所有項(xiàng)目所必須的,因此根據(jù)不同項(xiàng)目來進(jìn)行特定包數(shù)據(jù)的收發(fā)。

通過上面描述對(duì)CAN數(shù)據(jù)格式有了一個(gè)基本上認(rèn)識(shí),下面是通過示波器抓取CAN標(biāo)準(zhǔn)數(shù)據(jù)幀波形,示波器正連接CANH端,示波器負(fù)極連接CANL端。波特率是10Kbps,有效數(shù)據(jù)長度8字節(jié)。

b7b8da26-e7a9-11ec-ba43-dac502259ad0.png

CAN數(shù)據(jù)收發(fā)架構(gòu)設(shè)計(jì)如下圖:

b8069f2c-e7a9-11ec-ba43-dac502259ad0.png

4、FPGA實(shí)現(xiàn)代碼

在實(shí)現(xiàn)波特率可調(diào)的數(shù)據(jù)收發(fā)控制時(shí)需要注意的是每個(gè)波特?cái)?shù)據(jù)的采樣點(diǎn)。CAN數(shù)據(jù)采樣時(shí)序如下圖所示,一般采樣點(diǎn)都是在數(shù)據(jù)穩(wěn)當(dāng)?shù)闹虚g點(diǎn)位置,因此在設(shè)計(jì)FPGA中CAN模塊的時(shí)鐘頻率應(yīng)當(dāng)是數(shù)據(jù)波特率的20倍。

b8529d50-e7a9-11ec-ba43-dac502259ad0.png

在以10Kbps采樣率位例,CAN收發(fā)模塊時(shí)鐘設(shè)計(jì)如下:

//

//數(shù)據(jù)速率位10Kbps,一個(gè)數(shù)據(jù)位時(shí)間為10us.數(shù)據(jù)采集在5us時(shí)刻。

CAN波特率設(shè)置

reg[7:0]can_div;//500倍分頻,一個(gè)數(shù)據(jù)位分為20份

regcan_clk;

always @(posedge clk_100m or negedge rst_n )begin

if(rst_n==1'b0) begin

can_div<= 'b0;

end else if (can_div==249) begin

can_div<= 'b0;

endelse begin

can_div<= can_div + 1'b1;

end

end

always @(posedge clk_100m or negedge rst_n )begin

if(rst_n==1'b0) begin

can_clk<= 'b0;

end else if (can_div==249) begin

can_clk<= can_clk + 1'b1;

end

end

//時(shí)鐘經(jīng)過BUFG緩沖

wirecan_clk_o;

BUFG can_clk_obuf (.I(can_clk), .O(can_clk_o));

數(shù)據(jù)的收發(fā)需要根據(jù)實(shí)際的項(xiàng)目情況進(jìn)行組包控制,這里就不進(jìn)行細(xì)致描述了。

CAN實(shí)現(xiàn)數(shù)據(jù)的收發(fā)兩個(gè)過程中對(duì)應(yīng)FPGA來說由于接收相對(duì)復(fù)雜,就以接收模塊進(jìn)行描述。

數(shù)據(jù)的接收過程就按照一般的狀態(tài)機(jī)進(jìn)行設(shè)計(jì)就行,需要注意的是不同類型幀的跳轉(zhuǎn)是在控制段進(jìn)行了,因此在控制段會(huì)發(fā)生狀態(tài)的跳轉(zhuǎn)。CAN接收狀態(tài)的狀態(tài)機(jī)實(shí)現(xiàn)如下圖:

b8804cd2-e7a9-11ec-ba43-dac502259ad0.png

這個(gè)狀態(tài)機(jī)的實(shí)現(xiàn)并不復(fù)雜,主要是對(duì)幀類型進(jìn)行判斷。然后根據(jù)數(shù)據(jù)長度把數(shù)據(jù)解析出來。下面是實(shí)現(xiàn)CAN數(shù)據(jù)接收代碼:

`timescale 1ns / 1ps

//

// Company:

// Engineer:

//

// Create Date:

// Design Name:

// Module Name: can_rx

// Project Name:

// Target Devices:

// Tool versions:

// Description:

//

// Dependencies:

//

// Revision:

// Revision 0.01 - File Created

// Additional Comments:

//

//

module can_rx(

input wire can_clk ,

input wire rst_n ,

inputwirecan_rx,

outputregcan_ack_out_low,

outputregcan_id_out_en,

outputreg[10:0]can_id_out,

outputregcan_data_out_en,

outputreg[63:0]can_data_out

);

reg[8:0]state;

regcan_rx_t;

regerror_state;

reg[9:0]error_data;

reg[4:0]one_bit_cont;

reg[10:0]can_id;

reg[6:0]bit_cont;

regid_en_flag;

regcontral_flag;

regdata_en_flag;

regcic_en_flag;

regcan_rx_en_flag;

regcan_rx_unen_flag;

reg[4:0]can_continuity_data;

regcan_continuity_data_flag;

reg[4:0]can_id_data_cont;

reg[3:0]can_contral_data_cont;

reg[6:0]can_data_data_cont;

reg[4:0]can_cic_data_cont;

always @(posedge can_clk or negedge rst_n )begin

if(rst_n==1'b0) begin

can_rx_t<= 'b0;

end else begin

can_rx_t<= can_rx;

end

end

parameterstate_idle = 9'b000000000;//狀態(tài)機(jī)初始化

parameterstate_start = 9'b000000001;//監(jiān)測(cè)到開始標(biāo)志

parameterstate_sof = 9'b000000010; //開始幀頭第一位SOF

parameterstate_id = 9'b000000100; //包ID

parameterstate_control = 9'b000001000; //標(biāo)準(zhǔn)幀控制段

parameterstate_data = 9'b000010000; //數(shù)據(jù)段

parameterstate_crc = 9'b000100000; //CRC段

parameterstate_ack = 9'b001000000; //ACK段

parameterstate_eof = 9'b010000000; //幀結(jié)束段

parameterstate_end = 9'b100000000; //狀態(tài)機(jī)結(jié)束狀態(tài)

parameterbit_flag_no = 5'b10011;

always @(posedge can_clk or negedge rst_n )begin

if(rst_n==1'b0) begin

state<= 'b0;

one_bit_cont<= 'b0;

bit_cont<= 'b0;

id_en_flag<= 'b0;

contral_flag<= 'b0;

data_en_flag <= 'b0;

cic_en_flag<= 'b0;

can_rx_en_flag <= 'b0;

can_ack_out_low<= 'b1;

end else case(state)

state_idle:begin if ((can_rx_t==1'b1)&&(can_rx==1'b0))begin

state<= state_sof;

one_bit_cont<= 'b0;

can_rx_en_flag <= 'b1;

end else begin

state<= state_idle;

one_bit_cont<= 'b0;

bit_cont<= 'b0;

id_en_flag<= 'b0;

contral_flag <= 'b0;

data_en_flag<= 'b0;

cic_en_flag <= 'b0;

can_rx_en_flag <= 'b0;

can_ack_out_low<= 'b1;

end

end

state_sof:begin if ((one_bit_cont==bit_flag_no)&&(can_rx==1'b0))begin

state<= state_id;

id_en_flag<= 'b1;

one_bit_cont<= 'b0;

end else if ((one_bit_cont

state<= state_sof;

one_bit_cont<= one_bit_cont + 1'b1;

end

end

state_id:begin if ((one_bit_cont==bit_flag_no)&&(bit_cont==can_id_data_cont))begin

state<= state_control;

id_en_flag<= 'b0;

contral_flag<= 'b1;

one_bit_cont<= 'b0;

bit_cont<= 'b0;

end else if ((one_bit_cont==bit_flag_no)&&(bit_cont

state<= state_id;

one_bit_cont<= 'b0;

bit_cont<= bit_cont + 1'b1;

end else if (one_bit_cont

state<= state_id;

one_bit_cont<= one_bit_cont + 1'b1;

end else begin

state<= state_idle;

end

end

state_control:begin if ((one_bit_cont==bit_flag_no)&&(bit_cont==can_contral_data_cont))begin

state<= state_data;

contral_flag<= 'b0;

one_bit_cont<= 'b0;

bit_cont<= 'b0;

data_en_flag <= 'b1;

end else if ((one_bit_cont==bit_flag_no)&&(bit_cont

state<= state_control;

one_bit_cont<= 'b0;

bit_cont<= bit_cont + 1'b1;

end else if (one_bit_cont

state<= state_control;

one_bit_cont<= one_bit_cont + 1'b1;

end else begin

state<= state_idle;

end

end

state_data:begin if ((one_bit_cont==bit_flag_no)&&(bit_cont==can_data_data_cont))begin

state<= state_crc;

one_bit_cont<= 'b0;

bit_cont<= 'b0;

data_en_flag <= 'b0;

cic_en_flag<= 'b1;

end else if ((one_bit_cont==bit_flag_no)&&(bit_cont

state<= state_data;

one_bit_cont<= 'b0;

bit_cont<= bit_cont + 1'b1;

end else if (one_bit_cont

state<= state_data;

one_bit_cont<= one_bit_cont + 1'b1;

end else begin

state<= state_idle;

end

end

state_crc:begin if ((one_bit_cont==bit_flag_no)&&(bit_cont==can_cic_data_cont))begin

state<= state_ack;

can_ack_out_low<= 'b0;

one_bit_cont<= 'b0;

bit_cont<= 'b0;

cic_en_flag<= 'b0;

end else if ((one_bit_cont==bit_flag_no)&&(bit_cont

state<= state_crc;

one_bit_cont<= 'b0;

bit_cont<= bit_cont + 1'b1;

end else if (one_bit_cont

state<= state_crc;

one_bit_cont<= one_bit_cont + 1'b1;

end else begin

state<= state_idle;

end

end

state_ack:begin if ((one_bit_cont==bit_flag_no)&&(bit_cont==1))begin

state<= state_eof;

can_ack_out_low<= 'b1;

one_bit_cont<= 'b0;

bit_cont<= 'b0;

end else if ((one_bit_cont==bit_flag_no)&&(bit_cont<1)) begin

state<= state_ack;

one_bit_cont<= 'b0;

bit_cont<= bit_cont + 1'b1;

end else if (one_bit_cont

state<= state_ack;

one_bit_cont<= one_bit_cont + 1'b1;

end else begin

state<= state_idle;

end

end

state_eof:begin if ((one_bit_cont==bit_flag_no)&&(bit_cont==5))begin

state<= state_end;

one_bit_cont<= 'b0;

bit_cont<= 'b0;

end else if ((one_bit_cont==bit_flag_no)&&(bit_cont<5)) begin

state<= state_eof;

one_bit_cont<= 'b0;

bit_cont<= bit_cont + 1'b1;

end else if (one_bit_cont

state<= state_eof;

one_bit_cont<= one_bit_cont + 1'b1;

end else begin

state<= state_idle;

end

end

state_end:begin

state<= state_idle;

one_bit_cont<= 'b0;

bit_cont<= 'b0;

id_en_flag<= 'b0;

contral_flag <= 'b0;

data_en_flag<= 'b0;

cic_en_flag <= 'b0;

can_rx_en_flag <= 'b0;

can_ack_out_low<= 'b1;

end

default:begin

state<= state_idle;

one_bit_cont<= 'b0;

bit_cont<= 'b0;

id_en_flag<= 'b0;

contral_flag <= 'b0;

data_en_flag<= 'b0;

cic_en_flag <= 'b0;

can_rx_en_flag <= 'b0;

can_ack_out_low<= 'b1;

end

endcase

end

//always @(posedge can_clk or negedge rst_n )begin

//if(rst_n==1'b0) begin

//error_data<= 'b0;

//end else if (can_rx_en_flag==1) begin

//error_data<= {error_data[9:0],can_rx};

//endelse if (one_bit_cont==11) begin

//can_rx_unen_flag<= 1'b0;

//end else if (can_rx_en_flag==0)

//can_rx_unen_flag<= 'b0;

//end

always @(posedge can_clk or negedge rst_n )begin

if(rst_n==1'b0) begin

can_continuity_data<= 5'b11111;

can_continuity_data_flag<= 'b0;

end else if ((one_bit_cont==9)&&(can_rx_en_flag==1)) begin

can_continuity_data<= {can_continuity_data[3:0],can_rx};

can_continuity_data_flag<= 'b0;

endelse if (((can_continuity_data==0)||(can_continuity_data==5'b11111))&&(one_bit_cont==10)&&(cic_en_flag==0)) begin

can_continuity_data_flag<= 'b1;

end else if (((can_continuity_data==0)||(can_continuity_data==5'b11111))&&(one_bit_cont==10)&&(cic_en_flag==1)&&(bit_cont<14)) begin

can_continuity_data_flag<= 'b1;

end else if (can_rx_en_flag==0) begin

can_continuity_data<= 5'b11111;

can_continuity_data_flag<= 'b0;

end else begin

can_continuity_data_flag<= 'b0;

end

end

always @(posedge can_clk or negedge rst_n )begin

if(rst_n==1'b0) begin

can_rx_unen_flag<= 'b0;

end else if ((can_rx_en_flag==1)&&(can_continuity_data_flag==1)&&(cic_en_flag==0)) begin

can_rx_unen_flag<= 1'b1;

end else if ((can_rx_en_flag==1)&&(can_continuity_data_flag==1)&&(cic_en_flag==1)&&(bit_cont<14)) begin

can_rx_unen_flag<= 1'b1;

end else if (one_bit_cont==11) begin

can_rx_unen_flag<= 1'b0;

end else if (can_rx_en_flag==0)

can_rx_unen_flag<= 'b0;

end

always @(posedge can_clk or negedge rst_n )begin

if(rst_n==1'b0) begin

can_id_data_cont<= 'd10;

end else if ((id_en_flag==1)&&(can_continuity_data_flag==1)) begin

can_id_data_cont<= can_id_data_cont+ 1'b1;

endelse if (id_en_flag==0)

can_id_data_cont<= 'd10;

end

always @(posedge can_clk or negedge rst_n )begin

if(rst_n==1'b0) begin

can_contral_data_cont<= 'd6;

end else if ((contral_flag==1)&&(can_continuity_data_flag==1)) begin

can_contral_data_cont<= can_contral_data_cont+ 1'b1;

endelse if (contral_flag==0)

can_contral_data_cont<= 'd6;

end

always @(posedge can_clk or negedge rst_n )begin

if(rst_n==1'b0) begin

can_data_data_cont<= 'd63;

end else if ((data_en_flag==1)&&(can_continuity_data_flag==1)) begin

can_data_data_cont<= can_data_data_cont+ 1'b1;

endelse if (data_en_flag==0)

can_data_data_cont<= 'd63;

end

always @(posedge can_clk or negedge rst_n )begin

if(rst_n==1'b0) begin

can_cic_data_cont<= 'd15;

end else if ((cic_en_flag==1)&&(can_continuity_data_flag==1)) begin

can_cic_data_cont<= can_cic_data_cont+ 1'b1;

end else if (cic_en_flag==0)

can_cic_data_cont<= 'd15;

end

///

always @(posedge can_clk or negedge rst_n )begin

if(rst_n==1'b0) begin

can_id_out<= 'b0;

end else if ((one_bit_cont==9)&&(id_en_flag==1)&&(can_rx_unen_flag==0)) begin

can_id_out<= {can_id_out[9:0],can_rx};

end

end

always @(posedge can_clk or negedge rst_n )begin

if(rst_n==1'b0) begin

can_id_out_en<= 'b0;

end else if ((one_bit_cont==9)&&(bit_cont==can_id_data_cont)&&(id_en_flag==1)) begin

can_id_out_en<= 1'b1;

endelse

can_id_out_en<= 'b0;

end

always @(posedge can_clk or negedge rst_n )begin

if(rst_n==1'b0) begin

can_data_out<= 'b0;

end else if ((one_bit_cont==9)&&(data_en_flag==1)&&(can_rx_unen_flag==0)) begin

can_data_out<= {can_data_out[62:0],can_rx};

end

end

always @(posedge can_clk or negedge rst_n )begin

if(rst_n==1'b0) begin

can_data_out_en<= 'b0;

end else if ((bit_cont==can_data_data_cont)&&(one_bit_cont==9)&&(data_en_flag==1)) begin

can_data_out_en<= 1'b1;

endelse

can_data_out_en<= 'b0;

end

/

endmodule

在完成上述代碼編寫后通過CAN收發(fā)器發(fā)送數(shù)據(jù)然后利用chipscop進(jìn)行數(shù)據(jù)的抓取。

數(shù)據(jù)發(fā)送如下圖所示:

b8a0f680-e7a9-11ec-ba43-dac502259ad0.png

對(duì)上述代碼測(cè)試時(shí)抓取到數(shù)據(jù)波形如下圖:

b8c4a0f8-e7a9-11ec-ba43-dac502259ad0.png

從圖中可以看出接收了一包完整的標(biāo)準(zhǔn)數(shù)據(jù)幀。在通過CAN調(diào)試工具進(jìn)行數(shù)據(jù)的發(fā)送測(cè)試時(shí):CAN調(diào)試工具每秒發(fā)送60包,測(cè)試了一個(gè)小時(shí),沒有出現(xiàn)接收數(shù)據(jù)錯(cuò)誤。

然而在實(shí)現(xiàn)CAN通信時(shí)在滿足一般的代碼編寫的情況下有兩點(diǎn)需要特別的注意:

1、CAN2.0的協(xié)議規(guī)定,連續(xù)5個(gè)顯性/隱性電平后,要填充一位隱性/顯性電平。

2、在can協(xié)議中將CAN_H和CAN_L的差值為高電平時(shí)定義為顯性,邏輯上表示為0,為低電平時(shí)定義為隱形,邏輯上表示為1。

原文標(biāo)題:FPGA實(shí)現(xiàn)CAN通信

文章出處:【微信公眾號(hào):FPGA設(shè)計(jì)論壇】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

審核編輯:湯梓紅
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • FPGA
    +關(guān)注

    關(guān)注

    1624

    文章

    21539

    瀏覽量

    600533
  • CAN
    CAN
    +關(guān)注

    關(guān)注

    57

    文章

    2686

    瀏覽量

    462928
  • 物理層
    +關(guān)注

    關(guān)注

    1

    文章

    147

    瀏覽量

    34258

原文標(biāo)題:FPGA實(shí)現(xiàn)CAN通信

文章出處:【微信號(hào):gh_9d70b445f494,微信公眾號(hào):FPGA設(shè)計(jì)論壇】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    Labview用在通信物理層可以做那些事?

    本人小菜鳥,剛開始接觸Labview,想知道Labview用在通信物理層可以做那些事,可以實(shí)現(xiàn)那些功能,還望各位大神不吝賜教!
    發(fā)表于 10-31 15:35

    CAN總線不同的物理層

    CAN總線使用不歸零(NRZ)的位填充。有兩種不同的信令狀態(tài):顯性(邏輯0)和隱性(邏輯1)。這些信令狀態(tài)對(duì)應(yīng)于所在物理層(存在幾種不同的物理層)的某種電平。模塊以線與邏輯連接到總線:哪怕只有一個(gè)節(jié)點(diǎn)發(fā)送邏輯0使得總線處于顯性狀
    發(fā)表于 05-23 07:35

    如何對(duì)CAN物理層進(jìn)行調(diào)試?

    本文為您介紹一種對(duì)CAN物理層進(jìn)行調(diào)試的較好工程方法。我們將介紹基礎(chǔ)調(diào)試步驟,并說明一個(gè)CAN物理層應(yīng)有的性能,以及找出問題的一些小技巧。
    發(fā)表于 04-19 08:02

    淺析串口通訊協(xié)議物理層和協(xié)議

    什么是串口通訊?串口通訊協(xié)議物理層的結(jié)構(gòu)是由哪些部分組成的?串口通訊協(xié)議協(xié)議的主要標(biāo)準(zhǔn)是什么?
    發(fā)表于 10-22 09:30

    串口通訊協(xié)議物理層和協(xié)議看完你就懂了

    串口通訊協(xié)議物理層和協(xié)議看完你就懂了
    發(fā)表于 12-10 06:00

    IIC物理層是由哪些部分組成的

    物理層和協(xié)議。物理層規(guī)定通訊系統(tǒng)中具有機(jī)械、電子功能部分的特性,確保原始數(shù)據(jù)在物理媒體的傳輸。協(xié)議
    發(fā)表于 12-13 08:09

    物理層和協(xié)議兩方面來了解I2C總線

    和時(shí)鐘線SCL構(gòu)成的串行總線,可發(fā)送和接收數(shù)據(jù)。在CPU與被控IC之間、IC與IC之間進(jìn)行雙向傳送,高速I2C總線一般可達(dá)400kbps以上。下面從物理層和協(xié)議兩方面來了解I2CI2C物理層
    發(fā)表于 12-13 07:37

    STM32的IIC協(xié)議簡介

    文章目錄(一)IIC協(xié)議簡介(二)物理層和協(xié)議簡介(三)IIC
    發(fā)表于 01-05 06:13

    串口通信物理層協(xié)議的相關(guān)資料推薦

    一.串口通信物理層協(xié)議物理層規(guī)定了通訊系統(tǒng)的機(jī)械、電子特性(相當(dāng)于規(guī)定了用嘴巴還是肢體交流)協(xié)議
    發(fā)表于 02-17 07:07

    串口通訊協(xié)議物理層和協(xié)議是什么樣的?

    串口通訊協(xié)議物理層和協(xié)議是什么樣的?
    發(fā)表于 02-18 07:30

    CSA7000系列通信信號(hào)分析儀在網(wǎng)絡(luò)通信物理層測(cè)試領(lǐng)域中的

    CSA7000系列通信信號(hào)分析儀在網(wǎng)絡(luò)通信物理層測(cè)試領(lǐng)域中的應(yīng)用電信與數(shù)據(jù)通信速率達(dá) 2.5 Gb/s 的電光信號(hào)物理層測(cè)試CSA7000 系列實(shí)時(shí)
    發(fā)表于 10-17 17:17 ?10次下載

    物理層的作用

    物理層的作用:物理層是提供數(shù)據(jù)傳輸?shù)?b class='flag-5'>物理媒體,物理層協(xié)議是各種網(wǎng)絡(luò)設(shè)備進(jìn)行互連時(shí)必須遵守的最低層協(xié)議
    發(fā)表于 07-22 15:48 ?6670次閱讀

    物理層及其協(xié)議

    物理層及其協(xié)議 物理層的定義
    發(fā)表于 07-22 15:50 ?1.2w次閱讀

    WLAN物理層關(guān)鍵通信技術(shù)

    今天繼續(xù)給大家介紹華為WLAN系列內(nèi)容,本文主要內(nèi)容是WLAN物理層關(guān)鍵通信技術(shù)。 一、WLAN物理層分層 在802.11協(xié)議中,將無線網(wǎng)絡(luò)物理層
    發(fā)表于 05-19 17:07 ?0次下載
    WLAN<b class='flag-5'>物理層</b>關(guān)鍵<b class='flag-5'>通信</b>技術(shù)

    如何搞定通信物理層?物理層包含哪些內(nèi)容?如何落地實(shí)現(xiàn)呢?

    通信物理層通信系統(tǒng)的基礎(chǔ),其任務(wù)是將數(shù)字信息轉(zhuǎn)換為模擬信號(hào)并傳輸?shù)浇邮斩耍缓髮⒛M信號(hào)轉(zhuǎn)換回?cái)?shù)字信息。
    的頭像 發(fā)表于 11-20 10:12 ?1557次閱讀
    如何搞定<b class='flag-5'>通信物理層</b>?<b class='flag-5'>物理層</b>包含哪些內(nèi)容?如何落地實(shí)現(xiàn)呢?