日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當前位置:首頁 > > ZYNQ


常用外設設計


使用UART與ZYBO進行通信

ZYNQ學習過程中一個重要環(huán)節(jié)是進行調試,當然在SDK中進行調試時,設置斷點進行單步調試非常高效。但是ZYNQ中畢竟涉及到FPGA的硬件部分,于是如果可以通過UART與ZYNQ器件進行雙向的通信會使得調試非常方便。


Step1: 確認ZYBO板上硬件連接。


在ZYBO的用戶手冊中有以下描述,如圖 21所示。

圖 21


其ZYBO開發(fā)板的原理圖也可知MIO Bank的電壓為1.8V。


于是可以得到以下幾點:

1. 硬件上連接串口的IO為MIO48和MIO49。

2. IO的電壓為1.8V。

3. 默認使用的參數(shù)為:115200波特率以及其他對應參數(shù),見圖 21。


Step2: 在Vivado的Block Design中配置ZYNQ7 Processing System時,需要配置UART外設,如圖 22所示。

圖 22


Step3: 按照“Vivado中進行ZYNQ硬件部分設計”中介紹的,直到在SDK中編寫C代碼步驟。需要使用UART進行通行,分為通過UART向外發(fā)送數(shù)據(jù)和通過UART接收數(shù)據(jù)。


Step4: PC上安裝串口調試助手,硬件上連接串口線到PC。向ZYNQ中下載硬件配置后,在Windows Device Manager查看UART所使用的端口,如圖 23所示。

圖 23


并將串口調試助手設置成相應的配置,如圖 24所示。

圖 24


Step5: 至此就可以在C代碼中發(fā)送或者讀取數(shù)據(jù)了,下面給出一段示例代碼。

圖 25


程序首先運行,輸出” Please enter any number from 0~9”。此后會停在等待輸入處,直到通過串口助手鍵入了數(shù)字之后,才會跳到下一行代碼,并將鍵入的數(shù)字輸出在串口調試助手中。

圖 26


至此可以通過串口輸出各種信息(因為可以輸出字符串),同時也可以通過串口輸入進行菜單選擇,因為雖然不能接收字符串,但可以鍵入10個數(shù)字以及26個英文字母,這也應該足夠了。


Step6: 除了使用外部的串口調試助手外,SDK內(nèi)部也提供了Terminal工具。通過如下圖所示的方式顯示Terminal窗口且進行配置,同樣可以當作串口調試助手使用,如圖 28所示。

圖 27


圖 28


將用戶邏輯設計封裝成IP

參考工程見“ZYBO_demo_packageIP.xpr”。


ZYNQ中PS與PL的聯(lián)系主要有兩個,分別是GP端口和HP端口。其中HP端口可以理解為PS和PL可以訪問同一片存儲空間,于是可以以DDR空間為中介,進行大量的數(shù)據(jù)通信。而平時在純FPGA設計中的那些邏輯模塊與PS的通信方式就是依靠GP端口完成的。


純RTL邏輯模塊的控制或者輸出都是通過模塊的輸入輸出端口實現(xiàn)的。在ZYNQ的架構下,就是將這些輸入輸出端口改為寄存器,原來的輸入端口改為只寫的控制寄存器;原來的輸出端口改為只讀的狀態(tài)寄存器。于是每個邏輯模塊都有一個標準的AXI-Lite Slave接口,用于與PS相連接,使得PS可以控制讀寫邏輯模塊內(nèi)的寄存器。于是每一個邏輯模塊就相當于PS的一個外設,與PS自帶的外設,如UART、I2C控制器控制器來是一樣的。這就是ZYNQ的硬件可擴展性,通俗的說就是當ARM需要各種要求的外設時,都可以通過在PL端進行邏輯設計實現(xiàn)。


下面就介紹如何一步一步的完成一個PL端的邏輯設計,并將其封裝成為IP,并在ZYNQ的Block Design中加入到硬件設計中,并在SDK中通過代碼來控制該外設。


本例中所涉及的邏輯模塊功能為:IP的外部接口為4盞LED,內(nèi)部寄存器有3個,分別是工作模式寄存器(MODE),使能寄存器(ENABLE)和狀態(tài)寄存器(STATUS),如圖 29所示。

圖 29


Step1: 在Vivado GUI中,選擇Tool?Create and Package New IP…。一般情況下,選擇“Create a new AXI4 Peripheral”,這種IP就是之前提到的,由PS讀寫寄存器進而控制的IP,在后面的菜單中選擇該IP的Interface接口以及內(nèi)部需要多少寄存器,如圖 30所示。

圖 30


一般來說,IP首先需要一個AXI-Lite的Slave接口,用于與PS連接。除此以外還可以增加其他AXI接口,例如增加一個AXI4的Master接口,用于邏輯設計中訪問PS端的存儲器;又比如可以增加一個AXI-Lite的Master,用于讀寫其他邏輯模塊的寄存器等等。在這里選擇好接口后,工具在生成IP的時候會自動生成相應的AXI接口代碼,用戶可以直接使用或者稍作修改即可。


另外就是選擇寄存器的個數(shù),因為稍后生成的代碼中會自動完成指定數(shù)量寄存器的讀寫控制代碼,于是如果設置少了,后面需要手工添加代碼,會比較麻煩,不如配置時將寄存器個數(shù)設置的多一些。


Step2: 完成配置后工具自動生成代碼,在生成的代碼中進行修改。

圖 31


在自動生成的代碼中,結構如下:

圖 32


需要注意的是自動生成的代碼只是簡單完成了指定數(shù)量寄存器的讀寫時序,至于每個寄存器的邏輯功能和含義是沒有的,需要用戶將這些寄存器引到S00_AXI模塊的上層,與用戶設計的邏輯進行通信。同時自動生成的代碼中所有的寄存器都是可讀可寫的,如果需要設置只讀或者只寫的寄存器,需要在S00_AXI模塊中自行修改代碼。


Step3: 為邏輯設計增加外部接口以及全局參數(shù)。


該例程中需要設置4個外部輸出管腳,控制外部LED。并且設置一個全局參數(shù)為4盞LED的初始狀態(tài)。首先在代碼中指定位置進行修改,如圖 33所示。

圖 33


保存修改后,會在GUI界面中看到“Customization Parameter”、“Ports and Interfaces”以及“Customization GUI”的標識都變了,代表檢測到了代碼中的變化。

圖 34


點擊GUI中如下所示的指令后,工具自動完成更新。

圖 35


Step4: 在GUI如圖 34所示的界面中修改參數(shù)設置,對IP進行配置。


Step5: 完成IP的封裝,如圖 36所示,在Review and Package中點擊Re-Package IP。

圖 36


此時會關閉IP封裝界面,回到ZYNQ Block Design界面。在IP Catalog中會出現(xiàn)剛才封裝完成的IP。

圖 37


此后的操作就和“Vivado中進行ZYNQ硬件部分設計”中介紹的一樣,將該IP當成與其他IP一樣的外設,進行Block Design設計,同樣需要對于外接接口添加約束文件,之后生成Bit文件。


Step6: 在Block Design中需要將封裝的邏輯模塊IP需要引到外部的IO進行設置。


右擊需要引出的端口,點擊“Make External”。之后重新生成HDL Wrapper即可。

圖 38


Step7: 在Block Design中的Address Editor中給IP分配總線地址。

圖 39


Step8: 封裝好的IP進行底層修改。


如果需要對已經(jīng)設計好的IP進行底層修改,就在IP Catalog中顯示的該IP處右擊,選擇“Customize IP”。需要注意的是,工具會默認彈出一個路徑,作為修改IP的工作路徑,但是該路徑是一個臨時路徑,與之前存放IP的路徑不同。

圖 40


IP底層修改完成之后,重新Re-Package IP后,回到Block Design中工具自動檢測到IP有更新,只要通過工具的提示進行IP的更新即可。

圖 41


Step9: 封裝好的IP的BSP以及SDK程序的編寫。


首先封裝的IP有自己在AXI總線上的地址,于是IP內(nèi)部的所有寄存器的地址就是IP的Base地址加上各個寄存器的偏移量。于是在SDK代碼中就可以通過唯一的地址訪問到這些寄存器。由于內(nèi)部的寄存器都是用戶自己設計的,所以不需要BSP封裝太多的函數(shù),BSP也無法知道用戶設計的邏輯,從而也無法自動封裝API。用戶直接通過底層調用Xil_Out32()和Xil_In32()完成對于封裝邏輯模塊IP的控制。如果需要,用戶可以自行封裝更上層的API函數(shù)。

使用Zynq processor仿真Customized IP


由于ZYNQ中除了常用的FPGA邏輯部分外還有ARM內(nèi)核部分,所以在進行類似于FPGA設計仿真時會遇到問題,就是如果仿真ARM內(nèi)核部分。Xilinx提供的一個方案是Zynq BFM(Bus Functional Model),其介紹如下。

圖 42


但是該Model是需要額外購買的,該章節(jié)介紹一種無需購買Zynq BFM就可以仿真Customized IP的方法?;舅悸肥菍τ赑L端的Customized IP而言,控制端是ZYNQ中的ARM內(nèi)核還是普通FPGA中的MicroBlaze都是一樣的,所以可以將Customized IP例化到以MicroBlaze為處理器的Block Design中,由于MicroBlaze的仿真無需額外的License,所以可以將SDK的程序導入到MicroBlaze的內(nèi)核,進而仿真Customized IP。


Step1: 按照“將用戶邏輯設計封裝成IP”中介紹的,完成Customized IP的設計和封裝;在Block Design中加入MicroBlaze和Customized IP,完成Block Design設計;完成硬件平臺的綜合、實現(xiàn)、生成Bit文件,并導入SDK;在SDK中完成軟件設計。綜上就是完成“將用戶邏輯設計封裝成IP”中的Step9,區(qū)別只是用MicroBlaze替代了ZYNQ Processing System。

圖 43


Step2:對SDK中設計的軟件程序完成編譯,工具自動生成elf文件。默認的存放地址為SDK project下Src文件夾中。例如:C:\***\A7_microblaze\A7_microblaze.sdk\microblaze_customized_ip\Debug

圖 44


Step3:回到Vivado開發(fā)平臺,將elf文件導入至Simulation Source中。

圖 45


Step4:將導入的elf文件鏈接到對應的處理器,使其作為該處理器的啟動程序。注意,elf文件只允許associate至Microblaze,工具不支持鏈接到ZYNQ。

圖 46


Step5:正常啟動仿真。


可以看到MicroBlaze核發(fā)出的AXI通信協(xié)議,如圖 47所示。

圖 47


于是對應的IP的輸出可以看到如“將用戶邏輯設計封裝成IP”中模式2設計的一樣,輸出的4路LED不斷反轉。

圖 48

ZYNQ對Memory的操作
參考工程見“ZYBO_Memory_GPIO_Interrupt_demo.xpr”。ZYNQ有專用的DDR Controller接口,如果外部硬件連接了DDR器件,于是在ZYNQ Processing System中正確配置了相應的信號和參數(shù)后,DDR就可以成為ZYNQ的內(nèi)存,在SDK中可以直接使用memcpy、memset以及類似的函數(shù)對于Memory空間進行操作。Step1:查看ZYBO的原理圖,找到相應的配置。ZYBO原理圖中與DDR相關的部分如圖 49所示。圖 49于是得到兩個信息,第一個所使用的芯片是MT41J128M16JT-125,第二個是兩片DDR3顆粒是通過位拼接完成的,也就是數(shù)據(jù)位寬為32bit。Step2:在Block Design中對DDR部分的參數(shù)進行配置。圖 50Step3:完成Block Design設計,產(chǎn)生Bitstream,導入SDK。圖 51Step4:在SDK中編寫Memory測試代碼。
#include #include #include "platform.h"#include "xil_printf.h"#include "xil_types.h"#include "xil_io.h"int main(){ u32 test_src[100]; int i; int readback;  init_platform(); u32 *result = (u32*) malloc(sizeof(u32) * 100);  if (result) { memset(result, 0, sizeof(u32) * 100); } else { return 0; }  for(i=0;i<99;i++) { test_src[i]=i; }  memcpy(result,test_src,100 * sizeof(u32));  for(i=0;i<100;i++) { readback = Xil_In32(result+i);

其中特別需要學習的就是malloc與memcpy的使用方法。

ZYNQ中MIO/EMIO GPIO的使用

參考工程見“ZYBO_Memory_GPIO_Interrupt_demo.xpr”。

MIO是PS端的外部引腳,共有54個;EMIO是PL端的外部引腳,共有64個。ZYNQ支持通過配置將PS的控制器信號通過EMIO輸出,例如PS自帶的UART Controller,如果正常選擇引腳只能選擇MIO引腳輸出,但是通過設置可以選擇連接到EMIO引腳。同時EMIO引腳也可以作為PS端的擴展引腳,即經(jīng)過擴展PS一共可以控制118個引腳。

該例程演示將4個EMIO設置為PS的擴展引腳,這4個EMIO連接著LED。于是,與“將用戶邏輯設計封裝成IP”中的實驗相比,同樣是控制外部4個LED,就不需要另外設計一個邏輯模塊,并封裝成IP作為PS的外設了,可以直接通過SDK的程序進行控制。

注意:

1. 用于擴展GPIO的EMIO和用于擴展外設的EMIO是完全獨立的,GPIO的EMIO共有64個,由2個bank組成,如圖 52所示。

圖 52

2. EMIO的內(nèi)部排序按照EMIO54、EMIO55... ... EMIO117,以此類推。有了EMIO的編號之后就與內(nèi)部控制EMIO的寄存器一一對應;而EMIO在外部與外部引腳的對應關系又是可以通過管腳約束進行更改的。于是可以得出:不能通過EMIO的外部引腳的關系確定其內(nèi)部寄存器的地址。工具對于EMIO GPIO的連接關系是按照從EMIO54開始依次向上排列。

Step1:在Block Design中加入ZYNQ7 Processing System,在ZYNQ7 Processing System配置中添加EMIO GPIO,如圖 53所示。通過設置EMIO GPIO Width來選擇擴展EMIO GPIO的個數(shù),此時就完成了與內(nèi)部寄存器之間的對應關系,規(guī)則就是從EMIO54開始向上排列。

圖 53

Step2:將ZYNQ的EMIO連接到外部引腳。右擊生成的GPIO信號,點擊Make External。圖 54Step3:約束EMIO與外部引腳Pad的對應關系以及EMIO的電平標準。方法有兩種:
  • 第一種是通過XDC約束文件進行約束,需要先將Block Design生成HDL Wrapper,這樣才能知道其引腳名稱。

圖 55
  • 第二種方法就是Open Elaborated Design,在GUI中設置電平和引腳。

圖 56

Step4:完成Block Design的綜合、實現(xiàn)、生成Bitstream并導入SDK。

Step5:SDK中完成代碼的編寫,EMIO的代碼編寫需要包含的庫文件是"xgpiops.h"。

#include "xgpiops.h"static XGpioPs emio;#define EMIO_54   54#define EMIO_55   55#define EMIO_56   56#define EMIO_57   57 int main(){ //定義GPIOPS型指針,用于初始化時綁定硬件 XGpioPs_Config *ConfigPtrPS; init_platform(); //初始化GPIOPS,將ConfigPtrPS與硬件綁定 ConfigPtrPS = XGpioPs_LookupConfig(0); XGpioPs_CfgInitialize(&emio, ConfigPtrPS, ConfigPtrPS- > BaseAddr); //設置EMIO的方向,并使能EMIO XGpioPs_SetDirectionPin(&emio, EMIO_54, 1); XGpioPs_SetOutputEnablePin(&emio, EMIO_54, 1); XGpioPs_SetDirectionPin(&emio, EMIO_55, 1); XGpioPs_SetOutputEnablePin(&emio, EMIO_55, 1); XGpioPs_SetDirectionPin(&emio, EMIO_56, 1); XGpioPs_SetOutputEnablePin(&emio, EMIO_56, 1); XGpioPs_SetDirectionPin(&emio, EMIO_57, 1); XGpioPs_SetOutputEnablePin(&emio, EMIO_57, 1);  while(1) { // 向EMIO寫入數(shù)據(jù),即驅動EMIO引腳 XGpioPs_WritePin(&emio, EMIO_54, 0x0); XGpioPs_WritePin(&emio, EMIO_55, 0x0); XGpioPs_WritePin(&emio, EMIO_56, 0x0); XGpioPs_WritePin(&emio, EMIO_57, 0x0); usleep(200000); XGpioPs_WritePin(&emio, EMIO_54, 0x1); XGpioPs_WritePin(&emio, EMIO_55, 0x1); XGpioPs_WritePin(&emio, EMIO_56, 0x1); XGpioPs_WritePin(&emio, EMIO_57, 0x1); usleep(200000); }  cleanup_platform(); return 0;}


Step6:如果需要將EMIO作為輸入端口,只需要將IO的方向設置為input。對于IO,作為輸出的時候需要Enable,但是作為輸入是永遠使能的,不需要額外的Enable。具體代碼如圖 57所示。

圖 57

補充說明:MIO和EMIO都屬于PS的GPIO,用于指示的變量類型為XGpioPs;而使用AXI_GPIO外設的GPIO,由于是屬于PL的,所以指示這些IO的變量類型為XGpio。MIO和EMIO的控制對于SDK是完全相同的,其地址偏移量也是排在一起的,MIO從0排到53,EMIO接著從54開始。示例代碼中顯示的是EMIO作為輸出和MIO作為輸入,只需要將引腳編號的宏定義改為需要的MIO或者EMIO編號即可使用。在硬件配置時MIO的配置方法與EMIO有所不同,EMIO的配置如圖 53所示。而MIO由于不像EMIO,外部管腳是確定的,所以可以在ZYNQ7 Processing System配置時同時完成屬性以及電平的設置,如圖 58所示。

圖 58

ZYNQ中Interrupt使用參考工程見“ZYBO_Memory_GPIO_Interrupt_demo.xpr”。ZYNQ中的中斷管理是通過Generic Interrupt Controller(GIC)完成的。任何的中斷功能都需要兩步,第一步是配置相應的中斷,第二步是設置中斷觸發(fā)之后的服務函數(shù)。配置相應中斷分以下幾個步驟:1. 使能相應的功能,例如GPIO中斷需要首先使能和配置GPIO;Timer中斷需要首先使能和配置Timer;

圖 59

2. 初始化并配置使能GIC,還要使能異常處理。第1步中的操作對于每個中斷源來說都不相同,但是這一步的配置對于不同中斷源而言是類似的。不同之處在于有一個參數(shù):中斷ID,即例子中的52是變化的,52是GPIO的中斷號,其他中端需要使用不同的ID。該值可以在UG585中斷的相關章節(jié)查詢到,如圖 61所示。另一個區(qū)別就是XScuGic_Connect時的服務子函數(shù)不同。

圖 60

圖 61

3. 編寫中斷服務函數(shù),需要注意的是進入服務函數(shù)后首先需要禁止中斷,保證在處理中斷時不會再次因觸發(fā)中斷而程序跳轉;另外就是需要清除中斷標志位,否則會不斷觸發(fā)中斷。

圖 62

源代碼見附件。

ZYNQ CPU內(nèi)部任何有定時器,在Vivado的ZYNQ配置中無需任何操作就可以在SDK中直接使用。與GPIO中斷類似,Timer的中斷也包含相同的幾步操作,下面給出各個階段的代碼片段,完整代碼見附件。

1. 初始化Timer。

圖 63

2. 初始化GIC,設置中斷服務函數(shù)入口。

圖 64

3. 配置Timer工作模式,導入計數(shù)初值,使能中斷。

圖 65

4. 編寫中斷服務函數(shù),進入中斷后首先Disable中斷,清楚中斷標志位;然后進行中斷處理;退出中斷服務函數(shù)前重新使能中斷。

圖 66

Appendix 1: 配套工程

本站聲明: 本文章由作者或相關機構授權發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權益,請及時聯(lián)系本站刪除。
關閉