新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 利用FPGA實現外設通信接口之: 典型實例-USB 2.0接口的設計與實現

        利用FPGA實現外設通信接口之: 典型實例-USB 2.0接口的設計與實現

        作者: 時間:2017-06-05 來源:網絡 收藏

        本文引用地址:http://www.104case.com/article/201706/348803.htm

        10.7典型實例17:接口的設計與實現

        10.7.1實例的內容及目標

        1.實例的主要內容

        本節旨在設計實現了通過接口芯片與PC機進行高速數據通信,分為讀數據、寫數據和讀寫數據3部分內容。幫助讀者進一步了解USB接口芯片的工作原理和設計方法。

        2.實例目標

        通過本實例,讀者應達到如下目標。

        ·了解CY7C68013芯片的工作原理和SlaveFIFO模式時序。

        ·了解的固件設計以及USB驅動程序設計。

        ·熟練掌握狀態機的使用。

        ·實現與PC機之間的USB接口通信。

        10.7.2USB接口通信實戰步驟

        首先創建工程并為工程添加文件,如圖10.30所示。

        然后編譯工程并下載至硬件,如圖10.31所示。

        圖10.30創建工程并添加文件 圖10.31編譯工程并下載

        接下來可以加載固件了,固件程序的載入有兩種方式。

        (1)通過芯片的I2C總線連接外部的EEPROM,固件代碼事先通過燒寫器寫入EEPROM中,USB設備上電運行時,通過I2C總線將EEPROM中固件代碼載入。EZ-USB支持外部EEPROM通過總線來下載固件,這種方式使開發者可以從外圍硬件來下載8051程序代碼,但是不利于在設備開發階段使用。

        (2)使用該芯片特有軟配置功能,將固件程序存儲在計算機中,當該設備接入USB電纜時,由于EZ-USB具有重新枚舉的能力,所以在初始化枚舉以后,用戶只需要通過Cypress公司提供的開發軟件USBControlPanel中Download項,就可以將固件載入到控制芯片中。該方法完全是軟操作,不需要額外的硬件設備,方便程序的修改調試。

        使用USBControlPanel進行固件程序下載的界面如圖10.32所示。

        圖10.32USBControlPanel界面

        單擊“Download…”按鈕,選擇“slavefifo.hex”。下載固件成功以后顯示如圖10.33信息。

        圖10.33下載固件程序

        其中,通過單擊“GetPipes”按鈕可以查看通道信息。

        現在固件程序后,即可進行USB通信測試。

        根據不同的程序,選擇相應的測試軟件,測試USB接口的傳輸速度。如圖10.34所示是RedLogic工作室提供的基于紅色颶風II的USB測試軟件。

        圖10.34USB測試軟件

        10.7.3USB接口通信實例結果

        實現與PC機之間的USB通信,并且在PC機的超級終端上面測試USB的讀寫速度,如圖10.35和圖10.36所示。關于EZ-USB的詳細內容,可參見工程文件夾中提供的相關文檔。

        圖10.35USB測試結果

        圖10.36USB測試結果

        10.7.4FPGA代碼的設計實現

        本程序功能是配合CY68013的SlaveFIFO接口時序。它完成接收從主機下傳的60KB數據,寫入板上SRAM里,然后從板上SRAM中讀出,再上傳至主機。整個傳輸過程通過CY68013的SlaveFIFO來交互。

        整個程序由一個狀態機構成,包括以下狀態:

        ParameterIDLE=H0,

        READ_EVENT=H1,

        POINT_TO_OUT_FIFO=H2,

        DATA_READY=H3,

        READ_INTERVAL=H4,

        READ=H5,

        READ_END=H6,

        WRITE_EVENT=H7,

        POINT_TO_IN_FIFO=H8,

        WRITE_READY=H9,

        WRITE=HA,

        WRITE_END=HB;

        每個狀態的作用描述如下。

        ·IDLE:整個操作過程(包括讀SLAVEFIFO和寫SLAVEFIFO)的入口。對相關的寄存器進行初始化,然后轉入READ_EVENT狀態,開始讀SLAVEFIFO操作。

        ·READ_EVENT:把u_addr[1:0]置為’b00,指向輸出FIFO(對應端點6),然后轉入POINT_TO_OUT_FIFO狀態。

        ·POINT_TO_OUT_FIFO:判斷u_flagc是否為高(u_flagc為高指示輸出FIFO為空,即輸出FIFO中有數據),如果為高,則啟動讀過程,把u_sloe置為低,轉入DATA_READY狀態,第一個16位數據出現在總線上;否則說明輸出FIFO中無數據,等待。

        ·DATA_READY:判斷u_flagc是否為高,如果為高,把u_slrd拉低,繼續讀取下16位數據。同時為把上一16位數據寫入SRAM做準備(主要是SRAM的三態總線),同時轉入READ狀態,否則轉入POINT_TO_OUT_FIFO,等待下一次讀取過程。

        ·READ:把上一16位數據寫入SRAM,同時把u_slrd拉高,當前16位數據讀取結束。判斷是否是60KB數據,如果不是,則轉入DATA_READY狀態,繼續讀操作;否則轉入READ_END狀態,讀操作結束。

        ·READ_END:把相關寄存器置為初始態,轉入WRITE_EVENT狀態,開始寫操作。

        ·POINT_TO_IN_FIFO:為從SRAM中讀取數據作準備,轉入WRITE_READY狀態。

        ·WRITE_READY:判斷u_flagb是否為高(u_flagb為高指示輸入FIFO非滿),如果為高,則啟動寫過程,從SRAM中讀取數據并送到SLAVEFIFO總線上,把u_lswr置為低,轉入WRITE狀態;否則說明輸入FIFO已滿,等待。

        ·WRITE:把u_slwr置為高,當前數據寫入SLAVEFIFO。判斷是否是60KB數據,如果不是,則轉入WRITE_READY狀態,繼續寫操作;否則轉入WRITE_END狀態,寫操作結束。

        ·WRITE_END:把相關寄存器置為初始態,轉入IDLE狀態,開始下一個60KB的讀寫操作。

        狀態機的源代碼如下:

        case(STATE)

        IDLE:

        begin

        //添加RESET狀態

        data_wr=h0; //USB接口信號初始化

        u_slwr=b1;

        u_slrd=b1;

        u_sloe=b1;

        u_addr0=b1;

        u_addr1=b1;

        oe=b0;

        sram_d_i=h0; //SRAM的控制信號初始化

        sram_a=h3ffff;

        sram_re=b1;

        sram_wr=b1;

        wr_flag=b0;

        STATE=READ_EVENT;

        end

        READ_EVENT:

        begin

        wr_flag=b1; //設定讀寫標志

        u_addr0=b0; //指定端點FIFO

        u_addr1=b0;

        STATE=POINT_TO_OUT_FIFO;

        end

        POINT_TO_OUT_FIFO:

        begin

        if(u_flagc) //如果flagc高,FIFO不空,開始讀數據

        begin

        u_sloe=b0; //開始從FX2的端點FIFO讀數據

        u_slrd=b1;

        STATE=DATA_READY;

        end

        else

        begin //如果flagc為低,FIFO為空,等待FIFO有數據

        u_sloe=b1; //停止從FX2的端點FIFO讀數據

        u_slrd=b1;

        STATE=POINT_TO_OUT_FIFO;

        end

        end

        DATA_READY:

        begin

        if(u_flagc) //如果flagc為高,繼續讀取下一個數據

        begin

        u_slrd=b0;

        sram_a=sram_a+1; //把上一個讀取的數據寫入SRAM

        sram_d_i=data;

        sram_wr=b0;

        sram_re=b1;

        STATE=READ; //完成數據寫入后,進入讀數據狀態

        end

        else

        begin

        u_slrd=b1; //如果FIFO空,回到等待狀態

        u_sloe=b1;

        STATE=POINT_TO_OUT_FIFO;

        end

        end

        READ:

        Begin

        u_slrd=b1; //完成上一個數據的SRAM寫周期

        sram_re=b1;

        sram_wr=b1;

        if(sram_a!=ADDR_FULL) //如果SRAM地址沒有到最大值,繼續讀操作

        STATE=DATA_READY;

        else

        STATE=READ_END; //如果SRAM地址到達最大值,結束讀操作

        end

        READ_END:

        begin

        u_slrd=b1; //回到初始狀態,準備寫操作

        u_sloe=b1;

        u_addr0=b0;

        u_addr1=b0;

        sram_a=h3ffff;

        STATE=WRITE_EVENT;

        end

        WRITE_EVENT:

        begin

        u_addr0=b0; //指定寫數據的端點FIFO

        u_addr1=b1;

        oe=b1;

        wr_flag=b0;

        STATE=POINT_TO_IN_FIFO;

        end

        POINT_TO_IN_FIFO:

        begin

        sram_a=sram_a+1; //從SRAM中讀取一個數據

        sram_re=b0;

        sram_wr=b1;

        STATE=WRITE_READY;

        end

        WRITE_READY:

        begin

        if(u_flagb)

        begin //如果FIFO不滿,開始寫數據到FX2的FIFO

        data_wr=sram_d;

        u_slwr=b0;

        u_slrd=b1;

        STATE=WRITE;

        end

        else

        begin

        u_slwr=b1; //如果FIFO已滿,等待

        u_slrd=b1;

        STATE=WRITE_READY;

        end

        end

        WRITE:

        begin

        u_slwr=b1;

        u_slrd=b1;

        if(sram_a!=ADDR_FULL)

        begin

        sram_a=sram_a+1; //如果SRAM地址沒有達到最大值,繼續從SRAM讀數據

        sram_wr=b1;

        sram_re=b0;

        STATE=WRITE_READY;

        end

        else

        begin

        sram_a=h3ffff;//如果SRAM地址達到最大值,復位SRAM地址,進入寫結束

        sram_wr=b1;

        sram_re=b1;

        STATE=WRITE_END;

        end

        end

        WRITE_END:

        begin

        wr_flag=b0; //結束寫FX2FIFO狀態,回到初始的IDLE狀態

        sram_a=h3ffff;

        u_addr0=b1;

        u_addr1=b1;

        STATE=IDLE;

        end

        default:

        STATE=IDLE;

        endcase

        10.7.5小結

        本節對利用USB接口芯片FX2來完成FPGA和PC機的做了介紹,并通過編譯下載在紅色颶風的開發板上實現了預定功能。



        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 成武县| 长宁县| 蕲春县| 攀枝花市| 岑巩县| 沂源县| 岳普湖县| 曲松县| 浦江县| 万载县| 晋宁县| 壶关县| 定南县| 毕节市| 溆浦县| 常德市| 湘潭县| 桂林市| 日照市| 江西省| 南丰县| 磴口县| 阿图什市| 吉木萨尔县| 大邑县| 神农架林区| 获嘉县| 明星| 都江堰市| 缙云县| 金平| 儋州市| 平泉县| 崇仁县| 会同县| 昔阳县| 保康县| 巴中市| 鄂伦春自治旗| 中江县| 崇礼县|