在PS端对两个axi_uartlite中断的使用

由于项目需要多个UART,所以在用了两个IP核实现UART的功能。

开发板环境:vivado 2017.4 ,开发板型号xc7z020clg400-1,这个工程主要功能是自定义两个axi_uartlite  IP核,实现他们的中断接收。

在实验中遇到的问题(在网上查找了很多资料,花了不少时间才填完的坑):

1:两个IP核的中断怎么连接到PS端

2:在Xilinx SDK中如何对axi_uartlite IP核的中断如何进行配置

PS端的代码放到github上了:Zynq7020 two uartlite interrupt test, PS side source code.

下面是简要步骤:

1:两个IP核的中断怎么连接到PS端:

 添加zynq7000 Block后,在配置时需要打开PL到PS端的中断

添加两个axi_uartlite后,在system中添加Concat IP核

Concat IP核的功能是:把几个零散的中断信号合并成bus,连到系统中断总线上。

配置完的系统图如下图所示:

配置完成后,添加引脚约束:

其中有两种方法:

(一):在RTL ANALYSIS中的Open Elaborated Design中进行引脚的选择

(二):在Constarins中添加.XDC文件

2:在Xilinx SDK中如何对axi_uartlite IP核的中断如何进行配置

在官方例程xuartlite_intr_tapp_example(大概在Xilinx SDK的example目录下)的基础上进行修改,配置串口分为两个步骤:

(1)初始化串口

int UartLiteIntrExample(INTC *IntcInstancePtr,
			XUartLite *UartLiteInstPtr,
			u16 UartLiteDeviceId,
			u16 UartLiteIntrId)
{
	int Status;
	//u32 Index;

	/*
	 * Initialize the UartLite driver so that it's ready to use.
	 */
	Status = XUartLite_Initialize(UartLiteInstPtr, UartLiteDeviceId);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}

	/*
	 * Perform a self-test to ensure that the hardware was built correctly.
	 */
	Status = XUartLite_SelfTest(UartLiteInstPtr);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}

/*2020.07.01	while ((TotalSentCount != TEST_BUFFER_SIZE)) {
	}

	UartLiteDisableIntrSystem(IntcInstancePtr, UartLiteIntrId);  */

	return XST_SUCCESS;
}

(2)配置中断

int UartLiteSetupIntrSystem(INTC *IntcInstancePtr,
				XUartLite *UartLiteInstPtr,
				u16 UartLiteIntrId)
{
	int Status;

#ifdef XPAR_INTC_0_DEVICE_ID

#ifndef TESTAPP_GEN
	/*
	 * Initialize the interrupt controller driver so that it is ready
	 * to use. 初始化中断控制器
	 */
	Status = XIntc_Initialize(IntcInstancePtr, INTC_DEVICE_ID);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}
#endif

	/*
	 * Connect a device driver handler that will be called when an interrupt
	 * for the device occurs, the device driver handler performs the specific
	 * interrupt processing for the device.
	 */
	Status = XIntc_Connect(IntcInstancePtr, UartLiteIntrId,
			(XInterruptHandler)XUartLite_InterruptHandler,
			(void *)UartLiteInstPtr);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}

#ifndef TESTAPP_GEN
	/*
	 * Start the interrupt controller such that interrupts are enabled for
	 * all devices that cause interrupts, specific real mode so that
	 * the UART can cause interrupts thru the interrupt controller.
	 */
	Status = XIntc_Start(IntcInstancePtr, XIN_REAL_MODE);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}
#endif

	/*
	 * Enable the interrupt for the UartLite.
	 */
	XIntc_Enable(IntcInstancePtr, UartLiteIntrId);
#else

#ifndef TESTAPP_GEN
	XScuGic_Config *IntcConfig;

	/*初始化中断控制器
	 * Initialize the interrupt controller driver so that it is ready to
	 * use.
	 */
	IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
	if (NULL == IntcConfig) {
		return XST_FAILURE;
	}

	Status = XScuGic_CfgInitialize(IntcInstancePtr, IntcConfig,
					IntcConfig->CpuBaseAddress);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}
#endif /* TESTAPP_GEN */
//Sets the interrupt priority and trigger type for the specificd IRQ source.
//2020.7.2	XScuGic_SetPriorityTriggerType(IntcInstancePtr, UartLiteIntrId,
//					0xA0, 0x3);
	case 62U:
		XScuGic_SetPriorityTriggerType(IntcInstancePtr, UartLiteIntrId,
						0xA0, 0x3); break;
	case 61U:
		XScuGic_SetPriorityTriggerType(IntcInstancePtr, UartLiteIntrId,
						0xA1, 0x3);  break;
	default:
		XScuGic_SetPriorityTriggerType(IntcInstancePtr, UartLiteIntrId,
						0xA0, 0x3); break; break;
	}
#endif /* XPAR_INTC_0_DEVICE_ID */


#ifndef TESTAPP_GEN
   //设置并打开中断异常处理功能
	/*
	 * Initialize the exception table. 初始化异常表
	 */
	Xil_ExceptionInit();

	/*注册中断控制器处理程序
	 * Register the interrupt controller handler with the exception table.
	 */
	Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
			(Xil_ExceptionHandler)INTC_HANDLER,
			IntcInstancePtr);

	/*
	 * Enable exceptions.
	 */
	Xil_ExceptionEnable();
/**************************2020.7.1******************/
	/*
	 * Connect the interrupt handler that will be called when an
	 * interrupt occurs for the device.
	 */
	//为中断设置中断处理函数XUartLite_InterruptHandler
	switch(UartLiteIntrId){
	case 62U:
	Status = XScuGic_Connect(IntcInstancePtr, UartLiteIntrId,
				 (Xil_ExceptionHandler)RS232_intr_handler,/*XUartLite_InterruptHandler,*/
				 UartLiteInstPtr);  break;
	case 61U:
		Status = XScuGic_Connect(IntcInstancePtr, UartLiteIntrId,
					 (Xil_ExceptionHandler)RS422_intr_handler,/*XUartLite_InterruptHandler,*/
					 UartLiteInstPtr);  break;
	default:
	Status = XScuGic_Connect(IntcInstancePtr, UartLiteIntrId,
				 (Xil_ExceptionHandler)RS422_intr_handler,/*XUartLite_InterruptHandler,*/
				 UartLiteInstPtr);  break;
	}
	if (Status != XST_SUCCESS) {
		return Status;
	}

	/*
	 * Enable the interrupt for the Timer device.
	 */
	//使能GIC中的串口中断
	XScuGic_Enable(IntcInstancePtr, UartLiteIntrId);

	/*
	 * Enable the interrupt of the UartLite so that the interrupts
	 * will occur.
	 */
	XUartLite_EnableInterrupt(UartLiteInstPtr);

#endif /* TESTAPP_GEN */

	return XST_SUCCESS;
}

中断处理函数代码:

void RS422_intr_handler(void *CallBackRef){

    u8 buff,buff1;
    static u8 i=0;
	xil_printf("test success\r\n");

	//清除中断位
	//读取中断ID寄存器,判断触发的是哪种中断
	buff=XUartLite_RecvByte(XPAR_AXI_UARTLITE_1_BASEADDR);
	buff1=buff+1;
	XUartLite_SendByte(XPAR_AXI_UARTLITE_1_BASEADDR,++i);
	XUartLite_SendByte(XPAR_AXI_UARTLITE_1_BASEADDR,buff1);
}

实际运行结果:

  • 6
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 13
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值