ZYNQ 7020学习笔记之PL侧普通信号中断PS的实验

摘要:
4.在实验过程中,建立了项目,设置并初始化了串口中断。运行程序后,如果串行端口接收到N字节的数据,则生成串行端口中断。Zynq响应中断,从RXFIFO读取数据,并将其写入DDR3预定地址。

1、参考
UG585
网络笔记
2、理论知识
见中断部分

3、实验目的
练习使用PL侧的普通信号来中断PS处理器。

4、实验过程
建立工程,设置并初始化串口中断,在运行程序之后,如果串口接收到N(1-63)个字节数据,则产生串口中断,Zynq响应中断,将数据从RXFIFO读出之后写入到DDR3预定的地址中。

5、实验平台
Microphase ZUS zynq7020 开发板。 串口使用 uart1[48,49]. DDR选择 MT41J256M16 RE-125,32bit. BANK1 = 1.8v.

6、Vivado 建立工程
block design 如下:
在这里插入图片描述

7、SDK的工程程序

/******************************************************************************
*
* Copyright (C) 2009 - 2014 Xilinx, Inc.  All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/

#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "xscugic.h"
#include "xscutimer.h"
#include "xparameters.h"
#include "xil_exception.h"

#include <unistd.h>  //sleep()  usleep()

#define 	INTC_DEVICE_ID		 		XPAR_PS7_SCUGIC_0_DEVICE_ID
#define		INTC_PL_INTERRUPT_ID 	   	XPAR_FABRIC_MY_AXI4LITE_IP_0_PL_TO_ZYNQ_IRQ_INTR
#define		INT_TYPE_MASK				0x01
#define     INT_TYPE_RISING_EDGE        0X03
#define     INT_TYPE_HIGHLEVEL 			0X01
#define 	INT_CFG0_OFFSET 			0x00000C00  //(intID/16 )*4
#define 	INT_ENABLE_OFFSET 			0x00000100  //(intID/32 )*4
#define 	INT_CLEAR_OFFSET 			0x00000280  //(intID/32 )*4
#define 	INT_PRIORITY_OFFSET 		0x00000400  //(intID/4 )*4
#define 	INT_PROCESSORTARGET_OFFSET 	0x00000800  //(intID/4 )*4

#define 	INT_ICCPMR_OFFSET 	0xF8F00104
#define 	INT_ICCICR_OFFSET 	0xF8F00100


#define     BRAM_BASS_ADDRESS    0X40000000

XScuGic		INTCInst;

static	void	PLIRQIntrHandler(void	*	InstancePtr);  //中断处理功能函数
static  void 	CPU_Init(void);
static  void 	IntcTypeSetup(XScuGic *InstancePtr, int intId, int intType) ;
static  void 	IntcTypeEnable(XScuGic *InstancePtr, int intId, int intMask) ;
static  void 	IntcTypeClear(XScuGic *InstancePtr, int intId ) ;
static	int		InterruptSystemSetup(XScuGic	* XScuGicInstancePtr);   //中断系统建立
static  int		IntcInitFunction(u16 DeviceID);  //中断控制器初始化功能

int main()
{
    init_platform();
    CPU_Init();

    int status;

    //中断建立
     status = IntcInitFunction(INTC_DEVICE_ID);
     if(status != XST_SUCCESS)
    	 return		XST_FAILURE ;

    print(">>>>>>>>>>>> TEST Start >>>>>>>>>>>>>>>>

");
    print(" Press the Key for PL begin write data to PS DDR3 : 

");
    while(1)
    {

    	;
    }


    cleanup_platform();
    return 0;
}


// 中断控制器初始化功能
static int IntcInitFunction(u16 DeviceId)
{
	XScuGic_Config	* IntcConfig ;
	int		status;

	printf("Enter the interrupt system >>>>>>
");
	// 第二步, 对中断控制器进行初始化
	IntcConfig = XScuGic_LookupConfig(DeviceId);   //查找 GIC 的ID
	status = XScuGic_CfgInitialize(&INTCInst, IntcConfig, IntcConfig->CpuBaseAddress);
	if(status != XST_SUCCESS)
		return XST_FAILURE;

	//第三步,建立中断系统
	status = InterruptSystemSetup(&INTCInst);
	if(status != XST_SUCCESS)
		return	XST_FAILURE ;

	//第四步,GPIO中断连接到GIC上
	status = XScuGic_Connect(&INTCInst, INTC_PL_INTERRUPT_ID,
			(Xil_ExceptionHandler)PLIRQIntrHandler, (void *)1);

	if(status != XST_SUCCESS)
			return	XST_FAILURE ;

  //******************//
	// 参考
    IntcTypeSetup(&INTCInst,  INTC_PL_INTERRUPT_ID, INT_TYPE_RISING_EDGE);   //重要
    IntcTypeEnable(&INTCInst,  INTC_PL_INTERRUPT_ID, INT_TYPE_MASK);

//*********************************//
	XScuGic_Enable(&INTCInst, INTC_PL_INTERRUPT_ID); //CIG允许中断

	return XST_SUCCESS ;
}


static int InterruptSystemSetup (XScuGic * XScuGicInstancePtr)
{
	//中断异常的处理,指定该中断异常的处理器
	Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
			(Xil_ExceptionHandler)XScuGic_InterruptHandler, XScuGicInstancePtr);

	Xil_ExceptionEnable();   //异常处理使能

	return XST_SUCCESS;


}


void IntcTypeSetup(XScuGic *InstancePtr, int intId, int intType)
{
  //Setup 包括 触发方式配置, 优先级配置,CPU连接。 设置某个中断信息的前提是不影响其他中断设置
    int mask;

   //设置边沿触发方式
    mask = XScuGic_DistReadReg(InstancePtr, INT_CFG0_OFFSET + (intId/16)*4);     //read ICDICFR  *4,因为1个寄存器4个字节
    mask &= ~(0X3 << (intId%16)*2);  		//把读出的值对应2bit,清00,其他保持不变             //*2因为每个中断对应2bit
    mask |= intType << ((intId%16)*2);         	//把清0后的值对应2bit,写01,其他保持不变
    XScuGic_DistWriteReg(InstancePtr, INT_CFG0_OFFSET + (intId/16)*4, mask);     //WRITE ICDICFR

    //设置优先级
    mask = XScuGic_DistReadReg(InstancePtr, INT_PRIORITY_OFFSET + (intId/4)*4);     //read 优先级状态
	mask &= ~(0XFE << (intId%4)*8);        //把读出的值对应8bit,清00,其他保持不变             //*8因为每个中断对应8bit
	mask |= 0XA0 << ((intId%4)*8);         //把清0后的值对应8bit,写A0,其他保持不变
	XScuGic_DistWriteReg(InstancePtr, INT_PRIORITY_OFFSET + (intId/4)*4, mask);     //WRITE ICDICFR

    //设置处理器CPIID
	mask = XScuGic_DistReadReg(InstancePtr, INT_PROCESSORTARGET_OFFSET + (intId/4)*4);     //read 优先级状态
	mask &= ~(0X03 << (intId%4)*8);        //把读出的值对应8bit,清00,其他保持不变             //*8因为每个中断对应8bit
	mask |= 0X01 << ((intId%4)*8);         //把清0后的值对应8bit,写A0,其他保持不变
	XScuGic_DistWriteReg(InstancePtr, INT_PROCESSORTARGET_OFFSET + (intId/4)*4, mask);     //WRITE ICDICFR

}

void IntcTypeEnable(XScuGic *InstancePtr, int intId,int intMask)
{
  // 本函数 只包括 使能中断。使能之前先判断是否需要屏蔽
    int mask;

    mask = XScuGic_DistReadReg(InstancePtr, INT_ENABLE_OFFSET + (intId/32)*4);
    mask &= ~(0x01 << (intId%32)*1);   //把对应的Enable bit 清0
    mask |= intMask << ((intId%32)*1); //把对应的Enable bit 与 mask
    XScuGic_DistWriteReg(InstancePtr, INT_ENABLE_OFFSET + (intId/32)*4, mask);     //WRITE ICDICFR
}

void IntcTypeClear(XScuGic *InstancePtr, int intId )
{
	//本函数仅包括清楚中断,注意只能清除本中断对应的寄存器位
	 int mask;

    mask = XScuGic_DistReadReg(InstancePtr, INT_CLEAR_OFFSET + (intId/32)*4);     //read  ICDICPR
    mask &= ~(0x01 << (intId%32)*1);
    mask |= 0x01 << ((intId%32)*1);
    XScuGic_DistWriteReg(InstancePtr, INT_CLEAR_OFFSET + (intId/32)*4, mask);     //WRITE  ICDICPR
}



void CPU_Init( )
{
    //中断优先级都是A0,优先级高于F0,CPU可接受这些中断
	Xil_Out32(INT_ICCPMR_OFFSET,0xF0);
    //处理器能接收IRQ,使能中断信号连接到处理器
	Xil_Out32(INT_ICCICR_OFFSET,0x07);
}


static void PLIRQIntrHandler(void * InstancePtr)
{
	//default led all turn off
	printf("
************* test STARAT *********************
");
    int i;
    int readdata;
	sleep(1);

	for(i = 0; i < 4; i++)
	{
		readdata = Xil_In32(BRAM_BASS_ADDRESS+i*4);              //读取数据函数。
		sleep(1);
		printf("the read address is 0x%04x, the read data is 0x%04x.
", BRAM_BASS_ADDRESS+i*4, readdata);
	}

	printf("
************* test finish *********************
");
	// ***************************************************** //

	IntcTypeClear(&INTCInst,  INTC_PL_INTERRUPT_ID);
	IntcTypeEnable(&INTCInst,  INTC_PL_INTERRUPT_ID, INT_TYPE_MASK);

}

8 调试结果

在这里插入图片描述

免责声明:文章转载自《ZYNQ 7020学习笔记之PL侧普通信号中断PS的实验》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Idea基本设置(zxing.net)二维码Data Matrix的简介、实现与解码下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

OpenMP并行编程应用—加速OpenCV图像拼接算法

OpenMP是一种应用于多处理器程序设计的并行编程处理方案,它提供了对于并行编程的高层抽象,只需要在程序中添加简单的指令,就可以编写高效的并行程序,而不用关心具体的并行实现细节,降低了并行编程的难度和复杂度。也正因为OpenMP的简单易用性,它并不适合于需要复杂的线程间同步和互斥的场合。 OpenCV中使用Sift或者Surf特征进行图像拼接的算法,需要...

【视频开发】【Live555】摄像头采集,264编码,live555直播(0)

参看 有关live555  1.首先需要修改live555,定义从 内存中直接获取source而不是从文件读取source的类。 自己实现的类命名为 H264FramedLiveSource    /* * Filename: H264FramedLiveSource.hh * Auther: chenbin * Create da...

STM32 串口功能 库函数 详解和DMA 串口高级运用(转载)

数据传输时要从支持那些相关的标准?传输的速度?什么时候开始?什么时候结束?传输的内容?怎样防止通信出错?数据量大的时候怎么弄?硬件怎么连接出发,当然对于stm32还要熟悉库函数的功能 具起来rs232和485电平的区别硬件外围芯片,波特率(反映传一位的时间),起始位和停止位,数据宽度,校验,硬件流控制,相应连接电脑时的接口怎么样的。配置,使用函数,中断,查...

【t065】最敏捷的机器人

Time Limit: 1 second Memory Limit: 128 MB 【问题描述】 【背景】 Wind设计了很多机器人。但是它们都认为自己是最强的,于是,一场比赛开始了~ 【问题描述】 机器人们都想知道谁是最敏捷的,于是它们进行了如下一个比赛。 首先,他们面前会有一排共n个数,它们比赛看谁能最先把每连续k个数中最大和最小值写下来,...

MASM32快速起步

MASM32是一个免费的软件程序,让您编辑Microsoft宏汇编程序(MASM)代码从一个基本的文本界面。它强调MASM代码各部分以不同的颜色,使其更容易扫描和检测错误。它提供了一个简单的布局程序员手动编辑代码,没有任何花哨的功能或选项的常规Microsoft宏汇编。注意MASM32编辑器实际上并没有让你运行或编译的代码。对于这一点,你仍然需要Micros...

深入剖析 RocketMQ 源码 消息存储模块

一、简介 RocketMQ 是阿里巴巴开源的分布式消息中间件,它借鉴了 Kafka 实现,支持消息订阅与发布、顺序消息、事务消息、定时消息、消息回溯、死信队列等功能。RocketMQ 架构上主要分为四部分,如下图所示: Producer:消息生产者,支持分布式集群方式部署。 Consumer:消息消费者,支持分布式集群方式部署。 NameServer:...