OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 24|回复: 0

ZYNQ裸机反复进入中断,会一直运行中断服务函数内程序

[复制链接]

32

主题

82

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
332
金钱
332
注册时间
2016-6-5
在线时间
54 小时
发表于 昨天 20:38 | 显示全部楼层 |阅读模式
1金钱
使用ZYNQ7Z020,代码如下,当程序进入中断后,会反复进入中断,看起来像中断标志位未清除,请看看问题在哪里?


/*
* main.c
*
*  Created on: 2025年11月25日
*      Author: 24747
*/
#include "stdio.h"
#include "xparameters.h"
#include "xuartps.h"
#include "xscugic.h"
#include "xil_printf.h"
#include "sleep.h"
#include "xstatus.h"

#define UART_INT_IRQ_ID                XPAR_XUARTPS_1_INTR                        //串口中断ID
#define INTC_DEVICE_ID                XPAR_SCUGIC_SINGLE_DEVICE_ID//通用中断ID
#define UART_1_DEVICE_ID        XPAR_XUARTPS_0_DEVICE_ID        //串口设备ID


static XScuGic IntcInstPtr;
static XUartPs UartInst_PS;

//建立中断系统
static void UartPs_InterruptHandler(XUartPs *InstancePtr);
static int SetupInterruptSystem(XScuGic *IntcInstancePtr, XUartPs *UartInstancePtr, u16 UartIntrId);



int main(void){

        XUartPs_Config *Config;
        int Status;

//        xil_printf("\n\r Uart Inturrupt test! \n\r ");

        //根据串口设备ID查找配置,初始化串口外设
        Config = XUartPs_LookupConfig(XPAR_XUARTPS_0_DEVICE_ID);
        if (NULL == Config) {
                xil_printf("\n\r Uart XUartPs_LookupConfig Fail! \n\r ");
                return XST_FAILURE;
        }

        Status = XUartPs_CfgInitialize(&UartInst_PS, Config, Config->BaseAddress);
        if (Status != XST_SUCCESS) {
                xil_printf("\n\r Uart CfgInitialize Fail! \n\r");
                return XST_FAILURE;
        }

        //串口设备自检
        Status = XUartPs_SelfTest(&UartInst_PS);
        if (Status != XST_SUCCESS) {
                xil_printf("\n\r Uart SelfTest Fail! \n\r");
                return XST_FAILURE;
        }

        //设置工作模式
        XUartPs_SetOperMode(&UartInst_PS, XUARTPS_OPER_MODE_NORMAL);
        //设置波特率
        XUartPs_SetBaudRate(&UartInst_PS, 115200);
        //设置FIFO中断触发阈值:1字节,即接收多少字节数据触发中断
        XUartPs_SetFifoThreshold(&UartInst_PS, 0x03);


        xil_printf("\n\r Uart XUartPs_Init Done! \n\r");
        //建立中断系统
        Status = SetupInterruptSystem(&IntcInstPtr, &UartInst_PS, UART_INT_IRQ_ID);
        if (Status != XST_SUCCESS) {
                xil_printf("\n\r Uart SetupInterruptSystem Fail! \n\r");
                return XST_FAILURE;
        }

        while(1)
        {

        }
        return 0;
}

/********************************中断处理函数********************************/
static void UartPs_InterruptHandler(XUartPs *InstancePtr){

        u32 IsrStatus;
        u8 Rx_Data[5] = {1};

        //读取中断 ID 寄存器,判断触发的是哪种中断
        IsrStatus = XUartPs_ReadReg(InstancePtr->Config.BaseAddress, XUARTPS_IMR_OFFSET);
        IsrStatus &= XUartPs_ReadReg(InstancePtr->Config.BaseAddress, XUARTPS_ISR_OFFSET);

        //判断中断标志位RX FIFO是否触发
        if(IsrStatus & (u32)XUARTPS_IXR_RXOVR){
                //将数据存储到Rx_Data寄存器
                //Rx_Data = XUartPs_RecvByte(XPAR_PS7_UART_1_BASEADDR);
                XUartPs_Recv(InstancePtr, Rx_Data, 3);
                //清除中断标志位
                XUartPs_WriteReg(InstancePtr->Config.BaseAddress, XUARTPS_ISR_OFFSET, XUARTPS_IXR_RXOVR);
                XUartPs_Send(InstancePtr, Rx_Data, 3);
        }
        //发送接收到的数据
        //XUartPs_SendByte(XPAR_PS7_UART_1_BASEADDR, Rx_Data);

}

/********************************建立中断********************************/
static int SetupInterruptSystem(XScuGic *IntcInstancePtr, XUartPs *UartInstancePtr, u16 UartIntrId){

        XScuGic_Config *IntcConfig;
        int status;

        //初始化中断控制寄存器
        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;
        }
        //打开中断异常处理函数
        Xil_ExceptionInit();
        Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
                                        (Xil_ExceptionHandler)XScuGic_InterruptHandler,
                                        IntcInstancePtr);
        Xil_ExceptionEnable();

        //设置中断处理函数
        XScuGic_Connect(IntcInstancePtr, UartIntrId,
                                          (Xil_ExceptionHandler) UartPs_InterruptHandler,
                                          (void *) UartInstancePtr);
        XUartPs_SetInterruptMask(UartInstancePtr, 1);
        XScuGic_Enable(IntcInstancePtr, UartIntrId);

        return XST_SUCCESS;
}










回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则


关闭

原子哥极力推荐上一条 /1 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-12-13 05:37

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表