1. 程式人生 > >ARM9與FPGA並口通訊的實現

ARM9與FPGA並口通訊的實現



並口通訊是最常用基礎功能,實現ARM9與FPGA的並口通訊有兩種方式,一種頗為巧妙,利用SMC(Static Memory Controllor),其中的使能點都通過暫存器可以輕鬆控制;另一種方式就是通過GPIO來完成。

由於我拿到板子硬體的DRAM_CSN0DRAM_WENDRAM_RDN在前期PCB設計時沒有充分考慮過SMC可能被使用,故使用接外掛上其他引腳進行代替,使用了圖1中畫圈的三根引腳SPI0_MOSISPI0_SCKSPI0_CS。因為這三根引腳可以複用為GPIO,所以在並口除錯中將這三根引腳當作GPIO來使用。

1

2

3

1

SPI功能

GPIO

FPGA引腳

功能

SPI0_MOSI

PA1

W21

寫使能

SPI0_SCK

PA2

W22

讀使能

SPI0_CS

PA3

W20

片選

硬體連線對應情況如圖2、圖3和表1所示。到此,你應該已經瞭解了實現通訊需要關注的引腳了吧。

工程步驟:

1重設Pin Planner

根據當前硬體的實際連線情況,對Quartus中的Pin Planner進行更新,將訊號i_rd_cpui_wr_cpui_select對應的location

改為PIN_W22PIN_W21PIN_W20。如圖4所示。


4

2PIOA的暫存器組重新初始化

在最初的驅動程式中包括了對GPIO的初始化,經過試驗觀察PIO可讀暫存器的內容發現暫存器的配置不能滿足本任務的完成,使用已有的初始化會干擾到使能訊號的操作,於是要對GPIO進行重新初始化,對暫存器進行配置。

2.1PIO_PER暫存器

5

該暫存器是用來啟用PIOA各個引腳的GPIO模式,如圖5所示,每一位都對應控制著一根GPIO管腳,通過給P1P2P31激活了PA1PA2PA3GPIO模式,同時也等於關閉了複用外圍AB的模式。

2.2
PIO_OER暫存器

6

該暫存器有預設的設定,觀察發現最低4位預設為1100。本專案需要用到GPIO的輸出模式,所以需要對該暫存器進行重新配置,給P1P2P31,開啟引腳的輸出功能。

2.3PIO_PUDR暫存器

7

通過觀察PIO_PUSR暫存器可以發現預設的上拉暫存器是全部開啟的,上拉暫存器的啟用會影響GPIO的正常輸出,所以通過PIO_PUDR暫存器將上拉暫存器關閉,為之後正常操控GPIO提供基礎。

資料的寫入:

1概況

PIO_SODRPIO_CODR這兩個暫存器可以將指定位的GPIO電平置10。由於這裡設計的讀寫使能為低電平有效,在程式中首先將涉及的訊號均拉高,相當於對訊號進行一個復位。之後就可以進行資料的傳送工作。

8

9

8為連續傳送0x1122,0x3344,0x5566等多個數據時的情況,在寫使能的上升沿對資料匯流排和地址總線上的資訊進行取樣;圖9中顯示當寫使能訊號上升沿的時刻,資料匯流排上的資訊為0x5566,地址總線上的資訊為0x0005,即將0x5566儲存到RAM0x0005地址中。(上圖SignalTap取樣時鐘為125MHz

在一個傳送週期中,經歷以下過程:

0:地址總線上出現地址資訊;

1:片選訊號拉低;

2:寫使能訊號拉低;

3:資料放到資料匯流排上;

4:寫使能拉高,同時在上升沿時刻對資料取樣;

5:片選訊號拉高。

DATASHEET的SMC一章中有對並口的傳送時序進行描述,當前實驗結果也符合資料手冊中通過SMC實現並口通訊的說明,如圖10、圖11所示。可見,其實兩種方式大同小異,實現的結果相同。

10

11

2ARM中資料的傳送

通過FPGA_WriteData函式完成資料的傳送工作,其中使用了PIO暫存器中的PIO_CODRPIO_SODRPIO_ODSR三個暫存器,分別實現使能拉低,使能拉高,和標誌位判斷的功能。

語句中,(volatileunsigned short *)(x)x定義為了一個地址指標,再通過*取內容,這樣就可以將資料寫到這個地址上,在之後的程式中只要直接呼叫WREG()就可以方便的向地址寫資料。

3FPGA中資料的儲存

reg uprise_wr_dly;

always @(posedgei_clk,negedge i_rst_n)

begin

if(!i_rst_n)

uprise_wr_dly <= 1'b0;

else

uprise_wr_dly <= i_wr_cpu_pre;

end

reg wr;

always @(posedgei_clk,negedge i_rst_n)

begin

if(!i_rst_n)

wr <= 1'b0;

else if((i_wr_cpu_pre == 1'b1) && (uprise_wr_dly ==1'b0))

wr <= 1'b1;

else

wr <= wr;

end

以上程式製作了一個比寫使能訊號延後一個clock的訊號,再通過兩個訊號的組合判斷實現了寫使能上升沿訊號的處理。這在FPGA的程式中是很常見的處理方式。

最後通過RAM程式中的介面程式,將已經處理好的資料匯流排訊號、地址匯流排訊號和使能訊號、時鐘訊號新增進介面當中,功能便實現了。

資料的讀取:

資料讀取時的使能訊號同樣使用了PIO_CODRPIO_SODR這兩個關鍵的暫存器,按照時序控制這兩個暫存器的值即可。

資料讀取的情況如圖12所示:

12

通過對FPGA程式設計將資料0x3456放到資料匯流排上,在ARM的程式中對資料匯流排所在的地址進行讀取,就可以將資料讀出。這裡將讀出的資料儲存到了PIOC暫存器中,你也可以把它放到變數中來觀察,驗證對錯。在IAR裡檢視PIOC的只讀暫存器PIOC_ODSR就可以看到資料已經被存放到了暫存器當中。

關於涉及到的暫存器、暫存器的控制方式、使能訊號的時序以及相關軟體的使用和程式設計思路,讀取與寫入是大致一樣的,這裡不再重複描述。