本篇文章主要介紹外設(PL)產生的中斷請求,在PS端進行處理。
在PL端通過按鍵產生中斷,PS接受到之后點亮相應的LED.
本文所使用的開發板是Miz702 PC 開發環境版本:Vivado 2015.4 Xilinx SDK 2015.4
13.0本章難度系數★★☆☆☆☆☆
13.1 ZYNQ 中斷介紹
13.1.1 ZYNQ中斷框圖
可以看到本例子中PL到PS部分的中斷經過ICD控制器分發后后同時進入CPU1 和CPU0。從下面的表格中可以看到中斷向量的具體值。PL到PS部分一共有20個中斷可以使用。其中4個是快速中斷。剩余的16個是本章中涉及了,可以任意定義。如下表所示。
13.1.2 ZYNQ CPU軟件中斷 (SGI)
ZYNQ 2個CPU 都具備各自16個軟件中斷。
13.1.3 ZYNQ CPU 私有端口中斷
這些中斷都是固定死的,不能修改。這里有2個PL到CPU的快速中斷nFIQ
13.2 搭建硬件工程
Step1:新建一個名為為Miz702_sys的工程
Step2:選擇RTL Project 勾選Do not specify source at this time
Step3:由於Miz702兼容zedboard 因此選擇zedboard開發包
Step4:單擊Finish
13.3使用IP Integrator創建硬件系統
Step1:單擊Create Block Design
Step2:輸入system
Step4:搜素單詞z選擇ZYNQ7 Processing System,然后雙擊
Step5:添加進來了ZYNQ CPU IP,然后單擊Run Block Automation
Step6:直接單擊OK
Step7:在你點擊了OK后,你會發現DDR以及FICED_IO自勱的延伸出來。
Step8:連線的作用就是把PS的時鍾可以接入PL部分,當然這里我們暫時用不到PL部分的資源。在Block文件中,我們迚行連線,將鼠標放在引腳處,鼠標變成鉛筆后迚行拖拽,連線如下圖所示:
Step9:雙擊 ZYNQ,打開Re-customize IP對話框,使能IRQ_F2P
Step10:使能UART1點擊Run Connection Automation,按照如圖所示配置后單擊OK
Step11:添加一個GPIO IP,添加5個輸入,按照如圖所示配置,使能中斷
Step12:再添加一個GPIO IP,添加8個輸出按照如圖所示配置,點擊OK
Step13:單擊Run Connection Automation,將2個GPIO進行自動連線
Step14:把axi_gpio_0的ip2intc_irpt和ZYNQ PS的 IRQ_F2P[0:0]連在一起,並且修改GPIO的名字如圖所示:搭建好的硬件系統連接,如圖所示
Step15: 右擊 system.bd, 單擊Generate Output Products
Step16:支部操作會產生執行、仿真、綜合的文件
Step17:右擊system.bd 選擇 Create HDL Wrapper 這步的作用是產生頂層的HDL文件
Step18:選擇Leave Let Vivado manager wrapper and auto-update 然后單擊OK
Step19:添加xdc約束文件
| set_property IOSTANDARD LVCMOS33 [get_ports {btns_5bits_tri_i[4]}] set_property IOSTANDARD LVCMOS33 [get_ports {btns_5bits_tri_i[3]}] set_property IOSTANDARD LVCMOS33 [get_ports {btns_5bits_tri_i[2]}] set_property IOSTANDARD LVCMOS33 [get_ports {btns_5bits_tri_i[1]}] set_property IOSTANDARD LVCMOS33 [get_ports {btns_5bits_tri_i[0]}] set_property IOSTANDARD LVCMOS33 [get_ports {leds_8bits_tri_o[0]}] set_property IOSTANDARD LVCMOS33 [get_ports {leds_8bits_tri_o[1]}] set_property IOSTANDARD LVCMOS33 [get_ports {leds_8bits_tri_o[2]}] set_property IOSTANDARD LVCMOS33 [get_ports {leds_8bits_tri_o[3]}] set_property IOSTANDARD LVCMOS33 [get_ports {leds_8bits_tri_o[4]}] set_property IOSTANDARD LVCMOS33 [get_ports {leds_8bits_tri_o[5]}] set_property IOSTANDARD LVCMOS33 [get_ports {leds_8bits_tri_o[6]}] set_property IOSTANDARD LVCMOS33 [get_ports {leds_8bits_tri_o[7]}] set_property PACKAGE_PIN T18 [get_ports {btns_5bits_tri_i[0]}] set_property PACKAGE_PIN R18 [get_ports {btns_5bits_tri_i[1]}] set_property PACKAGE_PIN R16 [get_ports {btns_5bits_tri_i[2]}] set_property PACKAGE_PIN P16 [get_ports {btns_5bits_tri_i[3]}] set_property PACKAGE_PIN N15 [get_ports {btns_5bits_tri_i[4]}] set_property PACKAGE_PIN T22 [get_ports {leds_8bits_tri_o[0]}] set_property PACKAGE_PIN T21 [get_ports {leds_8bits_tri_o[1]}] set_property PACKAGE_PIN U22 [get_ports {leds_8bits_tri_o[2]}] set_property PACKAGE_PIN U21 [get_ports {leds_8bits_tri_o[3]}] set_property PACKAGE_PIN V22 [get_ports {leds_8bits_tri_o[4]}] set_property PACKAGE_PIN W22 [get_ports {leds_8bits_tri_o[5]}] set_property PACKAGE_PIN U19 [get_ports {leds_8bits_tri_o[6]}] set_property PACKAGE_PIN U14 [get_ports {leds_8bits_tri_o[7]}] |
13.4導出SOC硬件到SDK
Step1:File->Export->Export Hardware
Step2:勾選Include bitstream 直接單擊OK
Step3:File->Launch SDK加載到SDK
Step4:單擊OK
13.5軟件工程
新建一個PL_PS_INTC空的工程,並且添加main.c把以下代碼添加進去
| #include "xparameters.h" #include "xscugic.h" #include "xil_exception.h" #include "xgpio.h" // Parameter definitions #define INTC_DEVICE_ID XPAR_PS7_SCUGIC_0_DEVICE_ID #define LED_DEVICE_ID XPAR_AXI_GPIO_1_DEVICE_ID #define BTNS_DEVICE_ID XPAR_AXI_GPIO_0_DEVICE_ID #define INTC_GPIO_INTERRUPT_ID XPAR_FABRIC_AXI_GPIO_0_IP2INTC_IRPT_INTR #define BTN_INT XGPIO_IR_CH1_MASK // This is the interrupt mask for channel one #define DELAY 100000000 XGpio LED; XGpio BTNInst; XScuGic INTCInst; static u8 btn_value; //---------------------------------------------------- // PROTOTYPE FUNCTIONS //---------------------------------------------------- static void BTN_Intr_Handler(void *baseaddr_p); static int InterruptSystemSetup(XScuGic *XScuGicInstancePtr); static int IntcInitFunction(u16 DeviceId, XGpio *GpioInstancePtr); //---------------------------------------------------- // INTERRUPT SERVICE ROUTINE(ISR) //also know as : INTERRUPT HANDLER FUNCTION // - called by the buttons interrupt, performs push buttons read //---------------------------------------------------- void BTN_Intr_Handler(void *InstancePtr) { unsigned char led_val = 0; // Ignore additional button presses if ((XGpio_InterruptGetStatus(&BTNInst) & BTN_INT) != BTN_INT) { return; // Disable GPIO interrupts XGpio_InterruptDisable(&BTNInst, BTN_INT); } btn_value = ~XGpio_DiscreteRead(&BTNInst, 1)&0x1f; switch (btn_value){ case 0x01: led_val = 0x01; break; case 0x02: led_val = 0x02; break; case 0x04: led_val = 0x04; break; case 0x08: led_val = 0x08; break; case 0x10: led_val = 0x10; break; default:break; } XGpio_DiscreteWrite(&LED,1,led_val); // Acknowledge GPIO interrupts (void)XGpio_InterruptClear(&BTNInst, BTN_INT); // Enable GPIO interrupts XGpio_InterruptEnable(&BTNInst, BTN_INT); } //---------------------------------------------------- // MAIN FUNCTION //---------------------------------------------------- int main (void) { int status; // 初始化按鍵 status = XGpio_Initialize(&BTNInst, BTNS_DEVICE_ID); if(status != XST_SUCCESS) return XST_FAILURE; //初始化LED status = XGpio_Initialize(&LED, LED_DEVICE_ID); if(status != XST_SUCCESS) return XST_FAILURE; // 設置按鍵IO的方向為輸入 XGpio_SetDataDirection(&BTNInst, 1, 0xFF); //設置LED IO的方向為輸出 XGpio_SetDataDirection(&LED, 1, 0x00); // 初始化中斷控制器 status = IntcInitFunction(INTC_DEVICE_ID, &BTNInst); if(status != XST_SUCCESS) return XST_FAILURE; while(1){ } return (0); } //---------------------------------------------------- // INTERRUPT SETUP FUNCTIONS //---------------------------------------------------- int IntcInitFunction(u16 DeviceId, XGpio *GpioInstancePtr) { XScuGic_Config *IntcConfig; int status; // Interrupt controller initialization IntcConfig = XScuGic_LookupConfig(DeviceId); status = XScuGic_CfgInitialize(&INTCInst, IntcConfig, IntcConfig->CpuBaseAddress); if(status != XST_SUCCESS) return XST_FAILURE; // Call interrupt setup function status = InterruptSystemSetup(&INTCInst); if(status != XST_SUCCESS) return XST_FAILURE; // Register GPIO interrupt handler status = XScuGic_Connect(&INTCInst, INTC_GPIO_INTERRUPT_ID, (Xil_ExceptionHandler)BTN_Intr_Handler, (void *)GpioInstancePtr); if(status != XST_SUCCESS) return XST_FAILURE; // Enable GPIO interrupts XGpio_InterruptEnable(GpioInstancePtr, 1); XGpio_InterruptGlobalEnable(GpioInstancePtr); // Enable GPIO interrupts in the controller XScuGic_Enable(&INTCInst, INTC_GPIO_INTERRUPT_ID); return XST_SUCCESS; } int InterruptSystemSetup(XScuGic *XScuGicInstancePtr) { // Register GIC interrupt handler Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, (Xil_ExceptionHandler)XScuGic_InterruptHandler, XScuGicInstancePtr); Xil_ExceptionEnable(); return XST_SUCCESS; } |
13.6結果
下載好之后,按鍵按下可以看到相應的LED被點亮
13.7 本章小結
本章學習了外部中斷,通過PL傳遞開發板按鍵的中斷,然后在PS接受處理中斷。
官網論壇:www.osrc.cn
視頻鏈接:http://www.osrc.cn/forum.php?mod=viewthread&tid=1103
源碼鏈接:http://pan.baidu.com/s/1jHCdRds 密碼:zvtu


































