加入星計(jì)劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴(kuò)散
  • 作品版權(quán)保護(hù)
  • 300W+ 專(zhuān)業(yè)用戶(hù)
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長(zhǎng)期合作伙伴
立即加入
  • 正文
    • 四、程序的仿真與測(cè)試
    • 五、總結(jié)
  • 推薦器件
  • 相關(guān)推薦
申請(qǐng)入駐 產(chǎn)業(yè)圖譜

基于FPGA的CAN總線控制器的設(shè)計(jì)(附代碼)

2024/09/20
1.1萬(wàn)
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

今天給大俠帶來(lái)基于FPGA的CAN總線控制器的設(shè)計(jì),由于篇幅較長(zhǎng),分三篇。今天帶來(lái)第三篇,下篇,程序的仿真與測(cè)試以及總結(jié)。話不多說(shuō),上貨。

CAN 總線(Controller Area Network)是控制器局域網(wǎng)的簡(jiǎn)稱(chēng),是 20 世紀(jì) 80 年代初德國(guó) BOSCH 公司為解決現(xiàn)代汽車(chē)中眾多的控制與測(cè)試儀器之間的數(shù)據(jù)交換而開(kāi)發(fā)的一種串行數(shù)據(jù)通信協(xié)議。目前,CAN 總線已經(jīng)被列入 ISO 國(guó)際標(biāo)準(zhǔn),稱(chēng)為 ISO11898。CAN 總線已經(jīng)成為工業(yè)數(shù)據(jù)通信的主流技術(shù)之一。

CAN 總線作為數(shù)字式串行通信技術(shù),與其他同類(lèi)技術(shù)相比,在可靠性、實(shí)時(shí)性和靈活性方面具有獨(dú)特的技術(shù)優(yōu)勢(shì),主要特點(diǎn)如下:

    CAN 總線是一種多主總線,總線上任意節(jié)點(diǎn)可在任意時(shí)刻主動(dòng)地向網(wǎng)絡(luò)上其他節(jié)點(diǎn)發(fā)送信息而不分主次,因此可在各節(jié)點(diǎn)之間實(shí)現(xiàn)自由通信。
    CAN 總線采用非破壞性總線仲裁技術(shù)。但多個(gè)節(jié)點(diǎn)同時(shí)向總線發(fā)送信息時(shí),優(yōu)先級(jí)低的節(jié)點(diǎn)會(huì)主動(dòng)退出發(fā)送,而最高優(yōu)先級(jí)的節(jié)點(diǎn)可以不受影響地繼續(xù)傳輸數(shù)據(jù),從而大大節(jié)省總線沖突的仲裁時(shí)間。即使在網(wǎng)絡(luò)負(fù)載很重的情況下也不會(huì)發(fā)生網(wǎng)絡(luò)癱瘓情況。
    CAN 總線的通信介質(zhì)可以是雙絞線、同軸電纜或光導(dǎo)纖維,選擇靈活。
    CAN 總線的通信速率可達(dá) 1Mbit/s(此時(shí)通信距離最長(zhǎng)為 40 米),通信距離最遠(yuǎn)可達(dá) 10km(速率在 5kbit/s 以下)。
    ?CAN 總線上的節(jié)點(diǎn)信息分成不同的優(yōu)先級(jí),可以滿足不同級(jí)別的實(shí)時(shí)要求,高優(yōu)先級(jí)的數(shù)據(jù)可以在 134μs 內(nèi)得到傳輸。
    CAN 總線通過(guò)報(bào)文濾波即可實(shí)現(xiàn)點(diǎn)對(duì)點(diǎn)、一點(diǎn)對(duì)多點(diǎn)及全局廣播等幾種方式傳送數(shù)據(jù),無(wú)需專(zhuān)門(mén)的調(diào)度。
    CAN 總線的數(shù)據(jù)采用短幀結(jié)構(gòu),傳輸時(shí)間短,受干擾概率低,具有極好的檢錯(cuò)效果。
    CAN 總線采用 CRC 檢驗(yàn)并可提供相應(yīng)的錯(cuò)誤處理功能,保證了數(shù)據(jù)通信的可靠性。
    CAN 總線上的器件可被置于無(wú)任何內(nèi)部活動(dòng)的睡眠方式,相當(dāng)于未連接到總線上,可以有效降低系統(tǒng)功耗。

CAN 總線上的節(jié)點(diǎn)在錯(cuò)誤嚴(yán)重的情況下具有自動(dòng)關(guān)閉輸出的功能,以使總線上其他節(jié)點(diǎn)的操作不受影響。CAN 總線卓越的特性、極高的可靠性和獨(dú)特的設(shè)計(jì),特別適合工業(yè)過(guò)程中監(jiān)控設(shè)備的互連,因此,越來(lái)越受到工業(yè)界的重視,并被公認(rèn)為是最有前途的現(xiàn)場(chǎng)總線之一。另外,CAN 總線協(xié)議已被國(guó)際標(biāo)準(zhǔn)化組織認(rèn)可,技術(shù)比較成熟,控制的芯片已經(jīng)商品化,性?xún)r(jià)比高,特別適用于分布式測(cè)控系統(tǒng)之間的數(shù)通訊。

CAN 總線插卡可以任意插在 PC AT XT 兼容機(jī)上,方便地構(gòu)成分布式監(jiān)控系統(tǒng)。因此,用 FPGA 實(shí)現(xiàn) CAN 總線通信控制器具有非常重要的應(yīng)用價(jià)值。本篇將通過(guò)一個(gè)實(shí)例講解利用 FPGA 實(shí)現(xiàn) CAN 總線通信控制器的實(shí)現(xiàn)方法。

第三篇內(nèi)容摘要:本篇會(huì)介紹程序的仿真與測(cè)試以及總結(jié)等相關(guān)內(nèi)容。

四、程序的仿真與測(cè)試

CAN 總線通信控制器的仿真程序,需要模擬數(shù)據(jù)的發(fā)送和接收。

下面是測(cè)試程序的部分代碼:

//連接 can_top 模塊  can_top?i_can_top(                    .cs_can_i(cs_can),                    .clk_i(clk),                    .rx_i(rx_and_tx),                    .tx_o(tx),                    .irq_on(irq),                    .clkout_o(clkout)???????????????????);
//產(chǎn)生 24 MHz 時(shí)鐘  initial  begin    clk=0;    forever #21 clk = ~clk;  end
//初始化  initial  begin    start_tb = 0;    cs_can = 0;    rx = 1;    extended_mode = 0;    tx_bypassed = 0;    rst_i = 1'b0;    ale_i = 1'b0;    rd_i = 1'b0;    wr_i = 1'b0;    port_0_o = 8'h0;    port_0_en = 0;    port_free = 1;    rst_i = 1;    #200 rst_i = 0;    #200 start_tb = 1;  end
//產(chǎn)生延遲的 tx 信號(hào)(CAN 發(fā)送器延遲)  always  begin    wait (tx);    repeat (4*BRP) @ (posedge clk); // 4 time quants delay    #1 delayed_tx = tx;    wait (~tx);    repeat (4*BRP) @ (posedge clk); // 4 time quants delay    #1 delayed_tx = tx;  end    assign rx_and_tx = rx & (delayed_tx | tx_bypassed); // When this signal is on, tx is not  looped back to the rx.  //主程序  initial  begin    wait(start_tb);
//設(shè)置總線時(shí)序寄存器    write_register(8'd6, {`CAN_TIMING0_SJW, `CAN_TIMING0_BRP});    write_register(8'd7, {`CAN_TIMING1_SAM, `CAN_TIMING1_TSEG2, `CAN_TIMING1_TSEG1});
// 設(shè)置時(shí)鐘分頻寄存器    extended_mode = 1'b0;    write_register(8'd31, {extended_mode, 3'h0, 1'b0, 3'h0}); // Setting the normal mode (not    extended)
//設(shè)置接收代碼和接收寄存器    write_register(8'd16, 8'ha6); // acceptance code 0    write_register(8'd17, 8'hb0); // acceptance code 1    write_register(8'd18, 8'h12); // acceptance code 2    write_register(8'd19, 8'h30); // acceptance code 3    write_register(8'd20, 8'h0); // acceptance mask 0    write_register(8'd21, 8'h0); // acceptance mask 1    write_register(8'd22, 8'h00); // acceptance mask 2    write_register(8'd23, 8'h00); // acceptance mask 3    write_register(8'd4, 8'he8); // acceptance code    write_register(8'd5, 8'h0f); // acceptance mask    #10;    repeat (1000) @ (posedge clk);  //開(kāi)關(guān)復(fù)位模式    write_register(8'd0, {7'h0, ~(`CAN_MODE_RESET)});    repeat (BRP) @ (posedge clk);  // 在復(fù)位后設(shè)置總線空閑    repeat (11) send_bit(1);    test_full_fifo; // test currently switched on    send_frame; // test currently switched off    bus_off_test; // test currently switched off    forced_bus_off; // test currently switched off    send_frame_basic; // test currently switched off    send_frame_extended; // test currently switched off    self_reception_request; // test currently switched off    manual_frame_basic; // test currently switched off    manual_frame_ext; // test currently switched off    $display("CAN Testbench finished !");  $stop;  end

在測(cè)試過(guò)程中通過(guò)多個(gè)任務(wù)來(lái)分別驗(yàn)證程序的各個(gè)功能模塊。下面的程序用于驗(yàn)證強(qiáng)制關(guān)閉總線任務(wù):

//強(qiáng)制關(guān)閉總線任務(wù)task forced_bus_off; // Forcing bus-off by writinf to tx_err_cnt registerbegin//切換到復(fù)位模式write_register(8'd0, {7'h0, `CAN_MODE_RESET});// 設(shè)置時(shí)鐘分頻寄存器write_register(8'd31, {1'b1, 7'h0}); // Setting the extended mode (not normal)// 寫(xiě)數(shù)據(jù)到寄存器中write_register(8'd15, 255);// 切換復(fù)位模式write_register(8'd0, {7'h0, ~(`CAN_MODE_RESET)});#2500000;// 切換復(fù)位模式write_register(8'd0, {7'h0, `CAN_MODE_RESET});// 寫(xiě)數(shù)據(jù)到寄存器中write_register(8'd15, 245);//關(guān)閉復(fù)位模式write_register(8'd0, {7'h0, ~(`CAN_MODE_RESET)});#1000000;endendtask // forced_bus_off

下面的程序驗(yàn)證如何發(fā)送一個(gè)基本格式的幀數(shù)據(jù):

//發(fā)送一個(gè)基本格式的幀task manual_frame_basic;begin// 切換到復(fù)位模式  write_register(8'd0, {7'h0, (`CAN_MODE_RESET)});//設(shè)置寄存器  write_register(8'd4, 8'h28); // acceptance code  write_register(8'd5, 8'hff); // acceptance mask  repeat (100) @ (posedge clk);// 切換復(fù)位模式  write_register(8'd0, {7'h0, ~(`CAN_MODE_RESET)});// 模塊復(fù)位后設(shè)置總線空閑  repeat (11) send_bit(1);  write_register(8'd10, 8'h55); // Writing ID[10:3] = 0x55  write_register(8'd11, 8'h57); // Writing ID[2:0] = 0x2, rtr = 1, length = 7  write_register(8'd12, 8'h00); // data byte 1  write_register(8'd13, 8'h00); // data byte 2  write_register(8'd14, 8'h00); // data byte 3  write_register(8'd15, 8'h00); // data byte 4  write_register(8'd16, 8'h00); // data byte 5  write_register(8'd17, 8'h00); // data byte 6  write_register(8'd18, 8'h00); // data byte 7  write_register(8'd19, 8'h00); // data byte 8  tx_bypassed = 1; // When this signal is on, tx is not looped back to the rx.    fork    begin    self_reception_request_command;    end        begin      #2200;      repeat (1)      //開(kāi)始發(fā)送數(shù)據(jù)      begin        send_bit(0); // 幀起始        send_bit(0); // ID        send_bit(1); // ID        send_bit(0); // ID        send_bit(1); // ID        send_bit(0); // ID        send_bit(1); // ID        send_bit(0); // ID        send_bit(1); // ID        send_bit(0); // ID        send_bit(1); // ID        send_bit(0); // ID        send_bit(1); // RTR        send_bit(0); // IDE        send_bit(0); // r0        send_bit(0); // DLC        send_bit(1); // DLC        send_bit(1); // DLC        send_bit(1); // DLC        send_bit(1); // CRC        send_bit(1); // CRC        send_bit(0); // CRC stuff        send_bit(0); // CRC 6        send_bit(0); // CRC        send_bit(0); // CRC        send_bit(0); // CRC        send_bit(1); // CRC stuff        send_bit(0); // CRC 0        send_bit(0); // CRC        send_bit(1); // CRC        send_bit(0); // CRC        send_bit(1); // CRC 5        send_bit(1); // CRC        send_bit(0); // CRC        send_bit(1); // CRC        send_bit(1); // CRC b        send_bit(1); // CRC DELIM        send_bit(0); // ACK        send_bit(1); // ACK DELIM        send_bit(1); // EOF        send_bit(1); // EOF        send_bit(1); // EOF        send_bit(1); // EOF        send_bit(1); // EOF        send_bit(1); // EOF        send_bit(1); // EOF        send_bit(1); // INTER        send_bit(1); // INTER        send_bit(1); // INTER        end // repeat      end          join    //從接收緩沖中讀取數(shù)據(jù)    read_receive_buffer;    release_rx_buffer_command;    read_receive_buffer;    release_rx_buffer_command;    read_receive_buffer;    #4000000;      endendtask // manual_frame_basic

五、總結(jié)

本篇通過(guò)一個(gè)實(shí)例講解如何用 FPGA 實(shí)現(xiàn) CAN 總線通信控制器。首先講解了 CAN 總線協(xié)議的有關(guān)內(nèi)容,然后介紹了一種常用的 CAN 通信控制器 SJA1000 的主要特點(diǎn)。接下來(lái)講解程序的主要框架和具體代碼。最后通過(guò)一個(gè)測(cè)試程序驗(yàn)證了程序。這個(gè)實(shí)例為讀者實(shí)現(xiàn)自己的 CAN總線通信控制器提供了一個(gè)可以應(yīng)用的案例。

本篇到此結(jié)束,各位大俠有緣再見(jiàn)!

推薦器件

更多器件
器件型號(hào) 數(shù)量 器件廠商 器件描述 數(shù)據(jù)手冊(cè) ECAD模型 風(fēng)險(xiǎn)等級(jí) 參考價(jià)格 更多信息
EPM240M100C5N 1 Altera Corporation Flash PLD, 7.5ns, 192-Cell, CMOS, PBGA100, 6 X 6 MM, 0.50 MM PITCH, LEAD FREE, MICRO, FBGA-100
$80.18 查看
A3P1000-PQG208I 1 Microsemi FPGA & SoC Field Programmable Gate Array, 1000000 Gates, CMOS, PQFP208, 0.50 MM PITCH, GREEN, PLASTIC, QFP-208
$79.9 查看
10M02SCU169C8G 1 Intel Corporation Field Programmable Gate Array, PBGA169, 11 X 11 MM, 0.80 MM PITCH, ROHS COMPLIANT, UBGA-169

ECAD模型

下載ECAD模型
$7.63 查看

相關(guān)推薦

登錄即可解鎖
  • 海量技術(shù)文章
  • 設(shè)計(jì)資源下載
  • 產(chǎn)業(yè)鏈客戶(hù)資源
  • 寫(xiě)文章/發(fā)需求
立即登錄

任何技術(shù)的學(xué)習(xí)就好比一個(gè)江湖,對(duì)于每一位俠客都需要不斷的歷練,從初入江湖的小白到歸隱山林的隱世高人,需要不斷的自我感悟自己修煉,讓我們一起仗劍闖FPGA乃至更大的江湖。