本帖最后由 blackroot 于 2015-6-12 12:32 编辑
参照以前的工程建立方法,建立工程,添加如下IP:
1、ZYNQ7 processing_system2、xlconcat(该IP 核可以将多个输入汇成一个输出,双击Concat IP 核,将Number of Parts 设置成3,因为我们使用三个PL 中断)
3、u
til_vector_logic(因为设计的是三个独立的PL中断,所以应该将util_vector_logic IP配置成反相器,宽度设计成1)
3、AXI_GPIO(当然也可以采用EMIO的方式)
配置PS,修改端口名字,配置好的工程如下:
综合分配管脚
生成bitstream,导出硬件配置文件,生成FSBL 工程,生成APP 工程,利用已有的bsp文件新建helloworld工程,在helloworld工程上开发我们需要的功能。(f***l工程在这里主要用于初始化相关硬件资源,如果对f***l不是很清楚的话,可以参考相关的文档了解)
修改连接脚本文件,使主程序运行在DDR3上。设置方法:右击工程—>generate linker script,进入相关界面配置,配置完成如下:
由于本工程中使用拔码开关U20 作为外部的中断源,当开关1,2,3 从H 拔到L 时,会触发中断。同时中断处理函数会从串口打印出中断信息,并且相应的RGB等被点亮。串口信息如下:
PL中断源测试
sw1 中断正常
sw2 中断正常
sw3 中断正常
在线调试工程的效果如下图所示:
主要代码如下:
#include
#include "platform.h"
#include "xgpiops.h"
#include "xscugic.h"
#include "xil_exception.h"
#include "xparameters.h"
#include "xgpio.h"
#define INT_CFG0_OFFSET 0x00000C00
#define GPIO_EXAMPLE_DEVICE_ID XPAR_AXI_GPIO_0_DEVICE_ID// XPAR_LEDS_POSITIONS_DEVICE_ID
// Parameter definitions
#define SW1_INT_ID XPAR_FABRIC_UTIL_VECTOR_LOGIC_0_RES_INTR
#define SW2_INT_ID XPAR_FABRIC_UTIL_VECTOR_LOGIC_1_RES_INTR
#define SW3_INT_ID XPAR_FABRIC_UTIL_VECTOR_LOGIC_2_RES_INTR
#define INTC_DEVICE_ID XPAR_PS7_SCUGIC_0_DEVICE_ID
#define INT_TYPE_RISING_EDGE 0x03
#define INT_TYPE_HIGHLEVEL 0x01
#define INT_TYPE_MASK 0x03
#define LED_CHANNEL 1
static XScuGic INTCInst;
XGpio Gpio;
int dat=6;
//----------------------------------------------------
// PROTOTYPE FUNCTIONS
//----------------------------------------------------
static void SW_intr_Handler1(void *param);
static void SW_intr_Handler2(void *param);
static void SW_intr_Handler3(void *param);
static int InterruptSystemSetup(XScuGic *XScuGicInstancePtr);
static int IntcInitFunction(u16 DeviceId);
//处理函数
static void SW_intr_Handler1(void *param)
{
int sw_id = (int)param;
//int dat1;
printf("SW%d 中断正常nr", sw_id);
XGpio_DiscreteWrite(&Gpio, LED_CHANNEL, dat);
//dat1=dat<<1;
}
static void SW_intr_Handler2(void *param)
{
int sw_id = (int)param;
int dat1;
printf("SW%d 中断正常nr", sw_id);
dat1=dat<<1;
XGpio_DiscreteWrite(&Gpio, LED_CHANNEL, dat1);
}
static void SW_intr_Handler3(void *param)
{
int sw_id = (int)param;
int dat2;
printf("SW%d 中断正常nr", sw_id);
dat2=(dat<<1)<<1;
XGpio_DiscreteWrite(&Gpio, LED_CHANNEL, dat2);
}
//----------------------------------------------------
// INITIAL SETUP FUNCTIONS
//----------------------------------------------------
void IntcTypeSetup(XScuGic *InstancePtr, int intId, int intType)
{
int mask;
intType &= INT_TYPE_MASK;
mask = XScuGic_DistReadReg(InstancePtr, INT_CFG0_OFFSET + (intId/16)*4);
mask &= ~(INT_TYPE_MASK << (intId%16)*2);
mask |= intType << ((intId%16)*2);
XScuGic_DistWriteReg(InstancePtr, INT_CFG0_OFFSET + (intId/16)*4, mask);
}
int InterruptSystemSetup(XScuGic *XScuGicInstancePtr)
{
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
(Xil_ExceptionHandler)XScuGic_InterruptHandler,
XScuGicInstancePtr);
Xil_ExceptionEnable();
return XST_SUCCESS;
}
int IntcInitFunction(u16 DeviceId)
{
XScuGic_Config *IntcConfig;
int status;
// Interrupt controller initialisation
IntcConfig = XScuGic_LookupConfig(DeviceId);
status = XScuGic_CfgInitialize(&INTCInst, IntcConfig, IntcConfig->CpuBaseAddress);
if(status != XST_SUCCESS) return XST_FAILURE;
// Call to interrupt setup
status = InterruptSystemSetup(&INTCInst);
if(status != XST_SUCCESS) return XST_FAILURE;
// Connect SW1~SW3 interrupt to handler
status = XScuGic_Connect(&INTCInst,
SW1_INT_ID,
(Xil_ExceptionHandler)SW_intr_Handler1,
(void *)1);
if(status != XST_SUCCESS) return XST_FAILURE;
status = XScuGic_Connect(&INTCInst,
SW2_INT_ID,
(Xil_ExceptionHandler)SW_intr_Handler2,
(void *)2);
if(status != XST_SUCCESS) return XST_FAILURE;
status = XScuGic_Connect(&INTCInst,
SW3_INT_ID,
(Xil_ExceptionHandler)SW_intr_Handler3,
(void *)3);
if(status != XST_SUCCESS) return XST_FAILURE;
// Set interrupt type of SW1~SW3 to rising edge
IntcTypeSetup(&INTCInst, SW1_INT_ID, INT_TYPE_RISING_EDGE);
IntcTypeSetup(&INTCInst, SW2_INT_ID, INT_TYPE_RISING_EDGE);
IntcTypeSetup(&INTCInst, SW3_INT_ID, INT_TYPE_RISING_EDGE);
// Enable SW1~SW3 interrupts in the controller
XScuGic_Enable(&INTCInst, SW1_INT_ID);
XScuGic_Enable(&INTCInst, SW2_INT_ID);
XScuGic_Enable(&INTCInst, SW3_INT_ID);
return XST_SUCCESS;
}
int main(void)
{
int Status,i;
init_platform();
print("PL中断源测试nr");
Status = XGpio_Initialize(&Gpio, GPIO_EXAMPLE_DEVICE_ID);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
XGpio_SetDataDirection(&Gpio, LED_CHANNEL,dat);
// interrupt init
IntcInitFunction(INTC_DEVICE_ID);
while (1) {
}
cleanup_platform();
return 0;
}