第十二章 ZYNQ-MIZ701 PL中斷請求


 

本篇文章主要介紹外設(PL)產生的中斷請求,在PS端進行處理。
在PL端通過按鍵產生中斷,PS接受到之后點亮相應的LED.

本文所使用的開發板是Miz701 PC 開發環境版本:Vivado 2015.4 Xilinx SDK 2015.4

12.0本章難度系數★★☆☆☆☆☆

12.1 ZYNQ 中斷介紹

12.1.1 ZYNQ中斷框圖

wpsC547.tmp

wpsC548.tmp

可以看到本例子中PL到PS部分的中斷經過ICD控制器分發后后同時進入CPU1 和CPU0。從下面的表格中可以看到中斷向量的具體值。PL到PS部分一共有20個中斷可以使用。其中4個是快速中斷。剩余的16個是本章中涉及了,可以任意定義。如下表所示。

wpsC549.tmp

12.1.2 ZYNQ CPU軟件中斷 (SGI)

ZYNQ 2個CPU 都具備各自16個軟件中斷。

wpsC54A.tmp

12.1.3 ZYNQ CPU 私有端口中斷

這些中斷都是固定死的,不能修改。這里有2個PL到CPU的快速中斷nFIQ

wpsC55A.tmp
11.1.4 ZYNQ PS和PL共享中斷

wpsC55B.tmpwpsC55C.tmp


12.2 搭建硬件工程

Step1:新建一個名為為Miz701_sys的工程

wpsC55D.tmp

Step2:選擇RTL Project 勾選Do not specify source at this time

wpsC55E.tmp

Step3:選擇xc7z010clg400-1作為開發器件。

wpsC56F.tmp

Step4:單擊Finish

wpsC570.tmp

12.3使用IP Integrator創建硬件系統

Step1:單擊Create Block Design

Step2:輸入system

wpsC571.tmp

Step3:單擊下圖中wpsC572.tmp添加IP按鈕

wpsC573.tmp

Step4:搜素單詞z選擇ZYNQ7 Processing System,然后雙擊

wpsC584.tmp

Step5:添加進來了ZYNQ CPU IP,然后雙擊對其進行配置。

wpsC585.tmp

Step6:修改輸入時鍾頻率為50MHZ,PL端頻率FCLK_CLK0頻率為100MHZ。

wpsC586.tmp

Step7:修改內存類型為MT41K256M16 RE-125。

wpsC587.tmp

Step8:在MIO configuration選項中,勾選添加UART1接口。

wpsC588.tmp

Step9:在Interrupt選項中,使能IRQ_F2P,單擊OK完成修改。

wpsC598.tmp

Step10:單擊Run  Block Automation進行智能布線。

wpsC599.tmp

Step11:直接單擊OK

wpsC59A.tmp

Step12:在你點擊了OK后,你會發現DDR以及FICED_IO自動的延伸出來。

wpsC59B.tmp

Step13:連線的作用就是把PS的時鍾可以接入PL部分,當然這里我們暫時用不到PL部分的資源。在Block文件中,我們迚行連線,將鼠標放在引腳處,鼠標變成鉛筆后迚行拖拽,連線如下圖所示:

wpsC59C.tmp

Step14:添加一個GPIO IP,添加1個輸入,按照如圖所示配置,使能中斷

wpsC59D.tmp

Step15:再添加一個GPIO IP,添加4個輸出,按照如圖所示配置。

wpsC5B1.tmp

Step16:單擊Run Connection Automation,將GPIO進行自動連線

wpsC5B2.tmp

Step17:把axi_gpio_0的ip2intc_irpt和ZYNQ PS的 IRQ_F2P[0:0]連在一起,並且修改GPIO的名字如圖所示:搭建好的硬件系統連接,如圖所示

wpsC5B3.tmp

Step18: 右擊 system.bd, 單擊Generate Output Products

wpsC5B4.tmp

Step19:支部操作會產生執行、仿真、綜合的文件

wpsC5B5.tmp

Step20:右擊system.bd 選擇 Create HDL Wrapper 這步的作用是產生頂層的HDL文件

wpsC5C6.tmp

Step21:選擇Leave Let Vivado manager wrapper and auto-update 然后單擊OK

wpsC5C7.tmp

Step22:添加xdc約束文件

set_property IOSTANDARD LVCMOS33 [get_ports {leds_4bits_tri_o[3]}]

set_property IOSTANDARD LVCMOS33 [get_ports {leds_4bits_tri_o[2]}]

set_property IOSTANDARD LVCMOS33 [get_ports {leds_4bits_tri_o[1]}]

set_property IOSTANDARD LVCMOS33 [get_ports {leds_4bits_tri_o[0]}]

set_property IOSTANDARD LVCMOS33 [get_ports {button_tri_i[0]}]

set_property PACKAGE_PIN T17 [get_ports {button_tri_i[0]}]

set_property PACKAGE_PIN F17 [get_ports {leds_4bits_tri_o[0]}]

set_property PACKAGE_PIN J15 [get_ports {leds_4bits_tri_o[1]}]

set_property PACKAGE_PIN G14 [get_ports {leds_4bits_tri_o[2]}]

set_property PACKAGE_PIN D18 [get_ports {leds_4bits_tri_o[3]}]

Step23:執行->產生bit文件wpsC5C8.tmp

12.4導出SOC硬件到SDK

Step1:File->Export->Export Hardware

wpsC5C9.tmp

Step2:勾選Include bitstream 直接單擊OK

wpsC5DA.tmp

Step3:File->Launch SDK加載到SDK

wpsC5DB.tmp

Step4:單擊OK

wpsC5DC.tmp

12.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;

}

12.6結果

下載好之后,按鍵按下可以看到相應的LED移位一次。

12.7 本章小結

本章學習了外部中斷,通過PL傳遞開發板按鍵的中斷,然后在PS接受處理中斷。

淘寶店鋪:https://osrc.taobao.com

官網論壇:www.osrc.cn

源碼鏈接:http://pan.baidu.com/s/1kV0MLbp 密碼:k9jl


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM