OpenEdv-开源电子网

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

[XILINX] zynq PS端UART1通过EMIO从PL引出后不响应中断。。。

[复制链接]

3

主题

10

帖子

0

精华

新手上路

积分
31
金钱
31
注册时间
2026-3-17
在线时间
7 小时
发表于 6 天前 | 显示全部楼层 |阅读模式
1金钱
本帖最后由 MrsTao 于 2026-5-18 15:15 编辑

各位大佬
我用的是正点原子Z100 ZYNQ开发板(XC7Z035处理器),我按照教程《Z100 ZYNQ之嵌入式 V itis 开发指南》第九章 UART串口中断实验顺利通过了下载测试,于是我在此基础上将PS端的UART1通过EMIO将其引脚从PL端的AA27/AA28引出,并重新导出了硬件,修改了vitis程序,结果发现UART1串口可以输出数据 ,但不能接收数据,串口接收中断不响应,程序卡在 XScuGic_Enable(intc, UART1_INT_IRQ_ID);请问大佬这是怎么回事?
#include "xparameters.h"                //器件参数信息
#include "xuartps.h"                        //包含PS UART的函数声明
#include "xil_printf.h"                        //包含print()函数
#include "xscugic.h"                        //包含中断的函数声明
#include "stdio.h"                                //包含printf函数的声明
#include "sleep.h"

#define UART1_DEVICE_ID     XPAR_PS7_UART_1_DEVICE_ID    //串口设备ID
#define INTC_DEVICE_ID      XPAR_SCUGIC_SINGLE_DEVICE_ID //中断ID
#define UART1_INT_IRQ_ID    XPAR_XUARTPS_1_INTR          //串口中断ID

XScuGic Intc;              //中断控制器驱动程序实例
XUartPs Uart_Ps;           //串口驱动程序实例

//UART初始化函数
int uart_init(XUartPs* uart_ps)
{
        int status;
    XUartPs_Config *uart_cfg;

    uart_cfg = XUartPs_LookupConfig(UART1_DEVICE_ID);
    if (NULL == uart_cfg)
       return XST_FAILURE;
    status = XUartPs_CfgInitialize(uart_ps, uart_cfg, uart_cfg->BaseAddress);
    if (status != XST_SUCCESS)
       return XST_FAILURE;

    //UART设备自检
    status = XUartPs_SelfTest(uart_ps);
    if (status != XST_SUCCESS)
       return XST_FAILURE;

    //设置工作模式:正常模式
    XUartPs_SetOperMode(uart_ps, XUARTPS_OPER_MODE_NORMAL);
    //设置波特率:115200
    XUartPs_SetBaudRate(uart_ps,115200);
    //设置RxFIFO的中断触发等级
    XUartPs_SetFifoThreshold(uart_ps, 1);

    return XST_SUCCESS;
}

//UART中断处理函数
void uart_intr_handler(void *call_back_ref)
{
        XUartPs *uart_instance_ptr = (XUartPs *) call_back_ref;
    u32 rec_data = 0 ;
    u32 isr_status ;                           //中断状态标志

    //读取中断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);
}

//串口中断初始化
int uart_intr_init(XScuGic *intc, XUartPs *uart_ps)
{
        int status;
    //初始化中断控制器
    XScuGic_Config *intc_cfg;
    intc_cfg = XScuGic_LookupConfig(INTC_DEVICE_ID);
    if (NULL == intc_cfg)
        return XST_FAILURE;
    status = XScuGic_CfgInitialize(intc, intc_cfg,intc_cfg->CpuBaseAddress);
    if (status != XST_SUCCESS)
        return XST_FAILURE;

    //设置并打开中断异常处理功能
    Xil_ExceptionInit();
    Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
            (Xil_ExceptionHandler)XScuGic_InterruptHandler,
            (void *)intc);
    Xil_ExceptionEnable();

    //为中断设置中断处理函数
    XScuGic_Connect(intc, UART1_INT_IRQ_ID,
            (Xil_ExceptionHandler) uart_intr_handler,(void *) uart_ps);
    //设置UART的中断触发方式
    XUartPs_SetInterruptMask(uart_ps, XUARTPS_IXR_RXOVR);
    //使能GIC中的串口中断
    XScuGic_InterruptMaptoCpu(intc, 0, UART1_INT_IRQ_ID);
    XScuGic_Enable(intc, UART1_INT_IRQ_ID);
    return XST_SUCCESS;
}

//main函数
int main(void)
{
   int status;
   xil_printf("Uart1 test...\r\n");
   status = uart_init(&Uart_Ps);    //串口初始化
   if (status == XST_FAILURE) {
       xil_printf("Uart Initial Failed\r\n");
       return XST_FAILURE;
   }

   u32 rec0_data = 0 ;
   sleep(2);
//   uart_intr_init(&Intc, &Uart_Ps); //串口中断初始化
   while (1)
   {
           XUartPs_SendByte(XPAR_PS7_UART_1_BASEADDR,rec0_data);
           rec0_data++;
           sleep(1);
   }
   return status;
}



注释掉main()函数中的   “//   uart_intr_init(&Intc, &Uart_Ps); //串口中断初始化”   串口中断初始化,UART1能输出数据,去掉注释,程序就卡在串口中断初始化  "int uart_intr_init(XScuGic *intc, XUartPs *uart_ps)"   倒数第二行,即    XScuGic_Enable(intc, UART1_INT_IRQ_ID);这一行上。
请高手指点

回复

使用道具 举报

1

主题

75

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1430
金钱
1430
注册时间
2021-3-25
在线时间
234 小时
发表于 3 天前 | 显示全部楼层
uart控制器的基地址选错了,如果是要用uart1来进行串口环回,那么函数XUartPs_RecvByte跟XUartPs_SendByte的参数应该选 XPAR_PS7_UART_1_BASEADDR
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

如发现本坛存在违规或侵权内容, 请点击这里发送邮件举报 (或致电020-38271790)。请提供侵权说明和联系方式。我们将及时审核依法处理,感谢配合。

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

GMT+8, 2026-5-24 14:13

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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