ZYNQ中断

中断定义:中断是指计算机运行过程中,出现某些意外情况需主机干预时,机器能自动停止正在运行的程序并转入处理新情况的程序,处理完毕后又返回原被暂停的程序继续运行。
zynq中断:由状态寄存器读取当前状态,判断当前的状态是否满足中断触发的条件,满足后开始中断的触发,进入到中断处理函数,中断处理完成后跳出函数继续执行其余操作。
1.uart的中断:zynq的共有两路uart,单个uart的fifo深度为64,如果想要发送或者接收大于64字节的数据,则需要使用uart的中断完成操作,具体的流程为:uart初始化完成后,开始中断的初始化,设置中断触发的条件,满足条件后进入到中断处理函数。

#include"stdio.h"
#include"xuartps.h"
#include "xparameters.h"
#include "xscugic.h"
#include "xplatform_info.h"
#include "xil_exception.h"
#include "sleep.h"



#define INTC		  		XScuGic
#define DeviceId			XPAR_XUARTPS_0_DEVICE_ID
#define UART_INT_IRQ_ID		XPAR_XUARTPS_0_INTR
#define INTC_DEVICE_ID		XPAR_SCUGIC_SINGLE_DEVICE_ID
#define BAUDRATE			115200

XUartPs UartPs;
INTC InterruptController;	/* Instance of the Interrupt Controller */

//function  list
int SetupInterruptSystem(INTC *IntcInstancePtr,XUartPs *UartInstancePtr,u16 UartIntrId);
//void Handler(void *call_back);
void Handler(void *call_back_ref);
void UART_Init();
void XScuGic_ClearIntC(XUartPs * Uart_Ps,u32 IntrMASK);
u32 XScuGic_Getregstate(XUartPs * Uart_Ps);


int main()
{

 	//UART 初始化
 	UART_Init(&UartPs,BAUDRATE);

 	//设置中断系统
 	SetupInterruptSystem(&InterruptController, &UartPs, UART_INT_IRQ_ID);

 	printf("uart loop test action!\t\n");

 		while(1)
 		{
			

 		}
    return 0;
}

void UART_Init(XUartPs *UartPs,u32 BaudRate)
{
 	/*
 	 * 初始化UART 驱动
	 * Initialize the UART driver so that it's ready to use
	 * Look up the configuration in the config table, then initialize it.
	 */
 	XUartPs_Config *Config;
 	Config = XUartPs_LookupConfig(DeviceId);
 	XUartPs_CfgInitialize(UartPs, Config, Config->BaseAddress);

 	//设置UART波特率
    XUartPs_SetBaudRate(UartPs,BaudRate);
    //设置UART的模式
    XUartPs_SetOperMode(UartPs, XUARTPS_OPER_MODE_NORMAL);

    //设置FIFO阈值  0位disable  1为接收一位就触发中断
    XUartPs_SetFifoThreshold(UartPs, 1U);
    printf("UART Initial finished!\n\t");
}


int SetupInterruptSystem(INTC *IntcInstancePtr,XUartPs *UartInstancePtr,u16 UartIntrId)
{
		u32 IntrMask;
       /* Config for interrupt controller */
	    XScuGic_Config *IntcConfig;


		/* Initialize the interrupt controller driver */
		IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
        XScuGic_CfgInitialize(IntcInstancePtr, IntcConfig,IntcConfig->CpuBaseAddress);

       // 中断必须要配置的函数
        Xil_ExceptionInit();
        Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
        				(Xil_ExceptionHandler) XScuGic_InterruptHandler,
        				IntcInstancePtr);
        Xil_ExceptionEnable();

        //连接中断处理函数
        XScuGic_Connect(IntcInstancePtr, UartIntrId,
        				  (Xil_ExceptionHandler) Handler,
        				  (void *) UartInstancePtr);

    	IntrMask =
    		XUARTPS_IXR_TOUT | XUARTPS_IXR_PARITY | XUARTPS_IXR_FRAMING |
    		XUARTPS_IXR_OVER | XUARTPS_IXR_TXEMPTY | XUARTPS_IXR_RXFULL |
    		XUARTPS_IXR_RXOVR;
    	//设置中断触发方式
        //IntrMask =XUARTPS_IXR_RXOVR;
    	XUartPs_SetInterruptMask(UartInstancePtr, XUARTPS_IXR_RXOVR);
    	
    	/* Enable the interrupt for the device */
    	XScuGic_Enable(IntcInstancePtr, UartIntrId);

    		return 0;
}


/*
#define XUARTPS_IMR_OFFSET		0x0010U  //< Interrupt Mask [12:0]
#define XUARTPS_ISR_OFFSET		0x0014U  //< Interrupt Status [12:0]
*/
void XScuGic_ClearIntC(XUartPs * Uart_Ps,u32 IntrMASK)
{
	XUartPs_WriteReg(Uart_Ps->Config.BaseAddress,XUARTPS_ISR_OFFSET, IntrMASK) ;
}

u32 XScuGic_Getregstate(XUartPs * Uart_Ps)
{

	u32 int_state;
	//第二个参数 表示基地址的偏移量
	int_state  = XUartPs_ReadReg(Uart_Ps->Config.BaseAddress,XUARTPS_IMR_OFFSET) ;
	int_state &= XUartPs_ReadReg(Uart_Ps->Config.BaseAddress,XUARTPS_ISR_OFFSET) ;
	return int_state;
}

void Handler(void *call_back_ref)
 {
	 XUartPs *uart_instance_ptr = (XUartPs *) call_back_ref;
	 u32 rec_data = 0 ;
	 u32 isr_status ; //中断状态标志

	 printf("interrupt assert \n\t");
	//读取中断 ID 寄存器,判断触发的是哪种中断
	isr_status = XUartPs_ReadReg(uart_instance_ptr->Config.BaseAddress,
	XUARTPS_IMR_OFFSET);
	 isr_status &= XUartPs_ReadReg(uart_instance_ptr->Config.BaseAddress,
	XUARTPS_ISR_OFFSET);

	 //判断中断标志位 RxFIFO 是否触发
	 if (isr_status & (u32)XUARTPS_IXR_RXOVR){
	rec_data = XUartPs_RecvByte(XPAR_PS7_UART_0_BASEADDR);
	 //清除中断标志
	 XUartPs_WriteReg(uart_instance_ptr->Config.BaseAddress,
	XUARTPS_ISR_OFFSET, XUARTPS_IXR_RXOVR) ;
	 }
	 XUartPs_SendByte(XPAR_PS7_UART_0_BASEADDR,rec_data);

	 printf("interrupt end\t\n");
 }

//简易版本
/*void Handler(void *call_back_ref)
{
	u32 rec_data = 0 ;
	XUartPs * Uart_PS = (XUartPs*)call_back_ref;
	printf("interrupt assert \n\t");
	rec_data = XUartPs_RecvByte(XPAR_PS7_UART_0_BASEADDR);
	XUartPs_SendByte(XPAR_PS7_UART_0_BASEADDR,rec_data);
     XScuGic_ClearIntC(Uart_PS,XUARTPS_IXR_RXOVR);
	printf("interrupt end\t\n");

}*/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Zynq中,中断是一种处理器暂停正在执行的当前任务,转而执行与中断相关的任务的机制。Zynq中断具有优先级的概念,优先级决定了中断被响应的顺序。 每个中断都有一个特定的优先级,优先级值越小表示优先级越高。当多个中断同时生时,Zynq会根据中断的优先级来决定哪个中断优先被处理。 Zynq中,有两种类型的中断优先级:硬件优先级和软件优先级。硬件优先级由Zynq硬件定义,软件优先级由软件编写者进行定义。 硬件优先级在中断控制器内部实现,是通过对中断请求信号进行优先级编码来实现的。每个中断请求都有一个对应的优先级。当多个中断请求同时到达中断控制器时,硬件会根据这些优先级进行比较,并选择优先级最高的中断请求来处理。硬件优先级在编程过程中无法修改,由硬件设计决定。 软件优先级由编程者在中断处理程序中定义。在Zynq中,可以通过配置寄存器来设置每个中断的软件优先级。软件优先级与硬件优先级相互独立,但软件优先级必须小于硬件优先级。软件优先级的设置允许开发者自定义中断的响应顺序,以满足特定需求。 总的来说,Zynq中断的优先级是通过硬件优先级和软件优先级来确定的。硬件优先级由硬件设计决定,而软件优先级由编程者在中断处理程序中进行设置。根据这些优先级,Zynq选择性地处理中断请求,以确保高优先级的中断可以及时响应和处理。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一个会飞的小苏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值