ZYNQ笔记(八):UART 串口中断

news2025/5/18 14:28:26

 版本:Vivado2020.2(Vitis)

任务:UART串口中断实验,实现串口中断数据回环(接收数据并发送出去)

目录

一、介绍

二、硬件设计

三、软件设计

四、效果


一、介绍

      ZYNQ 的 UART(Universal Asynchronous Receiver/Transmitter,通用异步收发器) 是一种串行通信接口,用于在 ZYNQ 的 PS 端和外部设备之间进行异步数据传输。

UART 的主要特性

  • 支持标准 UART 协议(8-N-1、7-bit 数据位、奇偶校验等)。

  • 可编程波特率(最高可达 1 Mbps,取决于时钟配置)。

  • 双缓冲(FIFO)支持(减少 CPU 中断负载)。

  • 中断或轮询模式(可配置 DMA 传输)。

  • 硬件流控(可选)(RTS/CTS 信号)。

  • 集成在 PS(ARM)端,通常通过 MIO 或 EMIO 连接至外部引脚。

        注意:使用UART串口有中断和轮询两种方式,之前的例程只是串口打印发送,真正使用UART 进行接收和发送时需要进行初始化,并且通过中断和轮询的方式使用串口(一般选择中断)。

二、硬件设计

        (1)硬件设计同 ZYNQ笔记(一):hello world 一致,直接沿用。

        (2)最后整体 bd 设计部分如图所示:设计检查、Generate Output Products、 Create HDL Wrapper、管脚约束(无PL部分,跳过)、Gnerate Bitstream(无PL部分,跳过)、Export Hardware(无PL部分,不包含比特流文件)、启动Vitis

三、软件设计

        (1)这里提一下 UART 有四种工作模式:

工作模式数据流向主要用途特点

Normal Mode

正常模式

TxD → 外部设备
RxD ← 外部设备

正常通信模式,

与外部设备双向传输数据

标准 UART 操作,依赖 FIFO 缓冲和流控

Automatic Echo Mode

自动回环模式

RxD 接收数据,同时自动回环到 TxD 发送

测试 UART 自身收发功能

(无需外部设备)

接收端数据直接回传,用于验证硬件是否正常

Local Loopback Mode

本地回环模式

TxD 数据内部回环到 RxD(不经过物理引脚)测试芯片内部 UART 控制器和软件逻辑(隔离外部信号干扰)

避免外部线路影响,排查软件或驱动问题

Remote Loopback Mode

远程回环模式

RxD 接收数据直接回环到 TxD 发送

测试完整通信链路

(包括物理线路和外部设备)

验证线路完整性,检测信号衰减或干扰

        (2)设置UART中断触发类型,通过 XUartPs_SetInterruptMask 函数实现,掩码定义在 xuartps_hw.h 头文件,如图所示,本例采用 RX 接收端 FIFO(达到阈值)触发。

/** @name Interrupt Registers
 *
 * Interrupt control logic uses the interrupt enable register (IER) and the
 * interrupt disable register (IDR) to set the value of the bits in the
 * interrupt mask register (IMR). The IMR determines whether to pass an
 * interrupt to the interrupt status register (ISR).
 * Writing a 1 to IER Enbables an interrupt, writing a 1 to IDR disables an
 * interrupt. IMR and ISR are read only, and IER and IDR are write only.
 * Reading either IER or IDR returns 0x00.
 *
 * All four registers have the same bit definitions.
 *
 * @{
 */
#define XUARTPS_IXR_RBRK	0x00002000U /**< Rx FIFO break detect interrupt */
#define XUARTPS_IXR_TOVR	0x00001000U /**< Tx FIFO Overflow interrupt */
#define XUARTPS_IXR_TNFUL	0x00000800U /**< Tx FIFO Nearly Full interrupt */
#define XUARTPS_IXR_TTRIG	0x00000400U /**< Tx Trig interrupt */
#define XUARTPS_IXR_DMS		0x00000200U /**< Modem status change interrupt */
#define XUARTPS_IXR_TOUT	0x00000100U /**< Timeout error interrupt */
#define XUARTPS_IXR_PARITY 	0x00000080U /**< Parity error interrupt */
#define XUARTPS_IXR_FRAMING	0x00000040U /**< Framing error interrupt */
#define XUARTPS_IXR_OVER	0x00000020U /**< Overrun error interrupt */
#define XUARTPS_IXR_TXFULL 	0x00000010U /**< TX FIFO full interrupt. */
#define XUARTPS_IXR_TXEMPTY	0x00000008U /**< TX FIFO empty interrupt. */
#define XUARTPS_IXR_RXFULL 	0x00000004U /**< RX FIFO full interrupt. */
#define XUARTPS_IXR_RXEMPTY	0x00000002U /**< RX FIFO empty interrupt. */
#define XUARTPS_IXR_RXOVR  	0x00000001U /**< RX FIFO trigger interrupt. */
#define XUARTPS_IXR_MASK	0x00003FFFU /**< Valid bit mask */

        (3)UART中断控制原理:可以简单理解为"开关+触发器"的组合,通过掩码(IMR)和中断状态(ISR)两个寄存器协同工作:一种中断触发类型各对应一个掩码位和状态位,当任一触发类型的掩码位和状态位都有效时,UART产生中断请求信号。

        因为UART支持多种中断触发方式,所以中断处理函数部分需要对中断类型进行判断,可以根据不同的触发方式分情况进行处理。

        中断函数具体操作方式:1.读取状态寄存器、掩码寄存器(通过(2)设置),并进行相与(相与之后的结果就是表示当前串口的中断状态)、2. 将相与结果再与上需要判断的中断触发类型掩码,进行 if 判断(相于后只有触发类型一致时,相应位才得1,其余位为0,通过 if 判断)。

        (4)完整设计代码:

#include "xparameters.h"
#include "xil_printf.h"
#include "xuartps.h"
#include "xscugic.h"

//==========================自定义宏==========================//

#define UART_DEVICE_ID		XPAR_XUARTPS_0_DEVICE_ID     //宏定义UART器件ID
#define INTC_DEVICE_ID		XPAR_SCUGIC_SINGLE_DEVICE_ID //宏定义中断控制器(GIC)ID
#define UART_INTR_ID	    XPAR_XUARTPS_1_INTR			 //宏定义UART中断号(中断ID)

//===========================实例化===========================//

XUartPs Uart;	//UART驱动实例
XScuGic Intc;	//中断控制器驱动实例

//========================函数变量声明========================//

static int  Uart_Intr_Init();				//UART中断初始化
static void IntrHandler(void *CallBackRef);	//中断处理函数
static void Setup_Intr_System(XScuGic *intr, XUartPs *uart,u16 uart_intr_id); //建立中断系统

//===========================主函数===========================//

int main()
{
	//串口中断初始化
	Uart_Intr_Init();
	//建立中断系统
	Setup_Intr_System(&Intc, &Uart, UART_INTR_ID);

	//打印Debug信息
	xil_printf("UART Interrupt Test\r\n");

	while(1)
	return 0;
}

//========================中断处理函数========================//
/* @param CallBackRef  用户自定义回调参数(对应UART实例指针)
 */
void IntrHandler(void *CallBackRef)
{
	u8  rec_data;
	u32 IntrStatus;

	//将回调参数转为UART实例指针,用于操作硬件(例规范化设计)
	XUartPs *UartInstPtr = (XUartPs *) CallBackRef;

	//读取中断ID寄存器,获取中断触发类型
	IntrStatus  = XUartPs_ReadReg(UartInstPtr->Config.BaseAddress,
			XUARTPS_IMR_OFFSET);//读取掩码
	IntrStatus &= XUartPs_ReadReg(UartInstPtr->Config.BaseAddress,
			XUARTPS_ISR_OFFSET);//读取状态
	//判断中断类型并执行中断处理(与上对应中断类型掩码)
	//本例只设置了一种中断类型,有多种时通过if判断分情况处理
	if (IntrStatus & (u32)XUARTPS_IXR_RXOVR)
	{
		//接收发送的字节
		rec_data = XUartPs_RecvByte(XPAR_XUARTPS_0_BASEADDR);
		//发送数据
		XUartPs_SendByte(XPAR_XUARTPS_0_BASEADDR,rec_data);
		//清除中断状态
		XUartPs_WriteReg(UartInstPtr->Config.BaseAddress,
				XUARTPS_ISR_OFFSET, XUARTPS_IXR_RXOVR);
	}
}

//======================UART中断初始化=======================//
int Uart_Intr_Init()
{
    //定义UART控制器配置信息(指针)
	XUartPs_Config *UartConfig;
	//根据UART ID,查找配置信息
	UartConfig = XUartPs_LookupConfig(UART_DEVICE_ID);
	//初始化UART控制器驱动
	XUartPs_CfgInitialize(&Uart, UartConfig, UartConfig->BaseAddress);
	//设置工作模式:正常模式
	XUartPs_SetOperMode(&Uart, XUARTPS_OPER_MODE_NORMAL);
	//设置波特率:115200
	XUartPs_SetBaudRate(&Uart,115200);
	//(可选)串口自检:基本设置完成后,调用该函数进行串口自检并返回状态
	int Status = XUartPs_SelfTest(&Uart);
	if (Status != XST_SUCCESS) {
		xil_printf("UART SelfTest Failed\r\n");
		return XST_FAILURE;
	}
	return XST_SUCCESS;
}

//=======================建立中断系统=======================//
/* 建立中断系统,UART接收到数据时产生中断
 * @param intr			是指向 XScuGic驱动实例的指针
 * @param uart 			是指向 XUartPs驱动实例的指针
 * @param uart_intr_id	是 UART控制器ID
 */
void Setup_Intr_System(XScuGic *intr,  XUartPs *uart, u16 uart_intr_id)
{
    //定义中断控制器配置信息(指针)
	XScuGic_Config * IntcConfig;
	//根据中断控制器ID,查找GIC配置信息
	IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
	//初始化中断控制器驱动
	XScuGic_CfgInitialize(intr, IntcConfig, IntcConfig->CpuBaseAddress);
    //设置中断异常处理功能
	Xil_ExceptionInit();
	Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
			(Xil_ExceptionHandler) XScuGic_InterruptHandler,
			(void *) intr);
	//使能处理器中断
	Xil_ExceptionEnable();
	//关联中断处理函数
	XScuGic_Connect(intr, uart_intr_id,
				(Xil_ExceptionHandler) IntrHandler,
				(void *) uart);
	//设置FIFO阈值:1字节,即接收多少字节数据触发中断
	XUartPs_SetFifoThreshold(uart, 1);
	//设置UART中断触发类型:接收端FIFO触发中断(添加触发类型直接或“|”,各触发类型掩码位是独立的)
	XUartPs_SetInterruptMask(uart, XUARTPS_IXR_RXOVR);
	//使能UART中断
	XScuGic_Enable(intr, uart_intr_id);
}

四、效果

        上板后串口打印Debug信息,随后每向板卡发送数据,板卡会将数据接收并发送回来。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2337771.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

生态篇|多总线融合与网关设计

引言 1. 车内多总线概览 2. 主流车载总线技术对比 3. 网关设计原则与架构 4. 协议转换与映射策略 5. 安全与诊断功能集成

基于autoware1.14的实车部署激光雷达循迹,从建图、定位、录制轨迹巡航点、到实车运行。

1.首先安装autoware &#xff0c;大家可以以下一下博客进行安装&#xff0c;如果缺少库什么的直接问ai安装对应的库就行。ubuntu18.04安装Autoware1.14---GPU版 最全环境配置说明_autoware1.14安装教程-CSDN博客 安装成功后运行&#xff1a; source install/setup.bash roslau…

云计算(Cloud Computing)概述——从AWS开始

李升伟 编译 无需正式介绍亚马逊网络服务&#xff08;Amazon Web Services&#xff0c;简称AWS&#xff09;。作为行业领先的云服务提供商&#xff0c;AWS为全球开发者提供了超过170项随时可用的服务。 例如&#xff0c;Adobe能够独立于IT团队开发和更新软件。通过AWS的服务&…

UE学习记录part18

225 animation blueprint templates: generic animation blueprints 在Animation Blueprint中选择template生成动画蓝图模板 在function中选择blurprintthreadsafeupdateanimation&#xff0c;用于做数据的更新 先创建变量&#xff0c;再将变量再blueprintinitializeanimation…

刀片服务器的散热构造方式

刀片服务器的散热构造是其高密度、高性能设计的核心挑战之一。其散热系统需在有限空间内高效处理多个刀片模块产生的集中热量,同时兼顾能耗、噪音和可靠性。以下从模块化架构、核心散热技术、典型方案对比、厂商差异及未来趋势等方面展开分析: 一、模块化散热架构 刀片服务器…

【每日八股】复习计算机网络 Day1:TCP 的头部结构 + TCP 确保可靠传输 + TCP 的三次握手

文章目录 复习计算机网络 Day1TCP 的头部结构TCP 如何保证可靠传输&#xff1f;1. 数据完整性保障2. 顺序与去重控制3. 流量与拥塞控制4. 连接控制5. 其他辅助机制TCP 可靠传输的保障手段总结 TCP 的三次握手&#xff1f;TCP 为什么要三次握手&#xff1f;TCP 三次握手出现报文…

device_fingerprint、device_id、hmac生成

文章目录 1. 写在前面2. 设备信息3. 数美指纹 【&#x1f3e0;作者主页】&#xff1a;吴秋霖 【&#x1f4bc;作者介绍】&#xff1a;擅长爬虫与JS加密逆向分析&#xff01;Python领域优质创作者、CSDN博客专家、阿里云博客专家、华为云享专家。一路走来长期坚守并致力于Python…

python抓取HTML页面数据+可视化数据分析(投资者数量趋势)

本文所展示的代码是一个完整的数据采集、处理与可视化工具&#xff0c;主要用于从指定网站下载Excel文件&#xff0c;解析其中的数据&#xff0c;并生成投资者数量的趋势图表。以下是代码的主要功能模块及其作用&#xff1a; 1.网页数据获取 使用fetch_html_page函数从目标网…

uboot下读取ubifs分区的方法

在uboot 的defconfig中增加以下内容&#xff1a; CONFIG_MTDIDS_DEFAULT"nand0nand0" CONFIG_MTDPARTS_DEFAULT"mtdpartsnand0:1M(boot1),1M(boot2),1M(hwinfo),6M(kernel1),6M(kernel2),56M(rootfs1),56M(rootfs2),-(ubi2)" CONFIG_CMD_UBIy 其中&#x…

HAL详解

一、直通式HAL 这里使用一个案例来介绍直通式HAL&#xff0c;选择MTK的NFC HIDL 1.0为例&#xff0c;因为比较简单&#xff0c;代码量也比较小&#xff0c;其源码路径&#xff1a;vendor/hardware/interfaces/nfc/1.0/ 1、NFC HAL的定义 1&#xff09;NFC HAL数据类型 通常定…

MCP(模型上下文协议)说明

背景 MCP&#xff08;Model Context Protocol&#xff0c;模型上下文协议&#xff09;旨在解决大型语言模型&#xff08;LLM&#xff09;与外部数据源及工具集成的问题。由Anthropic公司于2024年11月提出并开源&#xff0c;目标是实现AI模型与现有系统的无缝集成。 解决的问题…

orcad csi 17.4 DRC规则设置及检查

rCAD绘制完原理图之后总是需要开启DRC检测&#xff0c;但是DRC一般都是英文版的&#xff0c;下面基于Cadence17.4 的orCAD16.6 对DRC的界面做简单的介绍 首先&#xff0c;鼠标点击原理图&#xff0c;然后再点击右上方的小勾图标 desine rules check option选项的界面 电气规…

前端资源加载失败后重试加载(CSS,JS等引用资源)

前端资源加载失败后的重试 .前端引用资源时出现了资源加载失败(这里针对的是路径引用异常或者url解析错误时) 解决这个问题首先要明确一下几个步骤 1.什么情况或者什么时候重试 2.如何重试 3.重试过程中的边界处理 这里引入里三个测试脚本&#xff0c;分别加载里三个不同的脚…

【HDFS入门】联邦机制(Federation)与扩展性:HDFS NameNode水平扩展深度解析

目录 引言 1 NameNode水平扩展原理 1.1 传统HDFS架构的局限性 1.2 联邦机制的基本原理 1.3 联邦架构的关键组件 2 多个Namespace的路由规则配置 2.1 客户端挂载表概念 2.2 挂载表配置示例 2.3 挂载表匹配规则 2.4 配置示例 3 BlockPool与Namespace的映射关系 3.1 B…

AI推荐系统的详细解析 +推荐系统中滤泡效应(Filter Bubble)的详细解析+ 基于Java构建电商推荐系统的分步实现方案,结合机器学习与工程实践

以下是AI推荐系统的详细解析&#xff1a; 一、核心概念 定义 推荐系统是通过分析用户行为、物品特征或用户画像&#xff0c;向用户推荐个性化内容的技术&#xff0c;广泛应用于电商、视频、社交等领域。 目标 提升用户留存与转化率增强用户体验实现精准营销 二、技术原理 1…

CSS 美化页面(五)

一、position属性 属性值‌‌描述‌‌应用场景‌static默认定位方式&#xff0c;元素遵循文档流正常排列&#xff0c;top/right/bottom/left 属性无效‌。普通文档流布局&#xff0c;默认布局&#xff0c;无需特殊定位。relative相对定位&#xff0c;相对于元素原本位置进行偏…

无约束最优化问题的求解算法--梯度下降法(Gradient Descent)

文章目录 梯度下降法梯度下降法原理&#xff08;通俗版&#xff09;梯度下降法公式学习率的设置**如何选择学习率&#xff1f;** 全局最优解梯度下降法流程损失函数的导函数三种梯度下降法**梯度下降法核心步骤回顾****优缺点详解****1. 全量梯度下降 (Batch Gradient Descent,…

Python全功能PDF工具箱GUI:支持转换、加密、旋转、图片提取、日志记录等多功能操作

使用Python打造一款集成 PDF转换、编辑、加密、解密、图片提取、日志追踪 等多个功能于一体的桌面工具应用&#xff08;Tkinter ttkbootstrap PyPDF2 等库&#xff09;。 ✨项目背景与开发动机 在日常办公或学习中&#xff0c;我们经常会遇到各种关于PDF文件的操作需求&#…

计算机视觉---相机标定

相机标定在机器人系统中的作用 1.确定相机的内部参数 相机的内部参数包括焦距、主点坐标、像素尺寸等。这些参数决定了相机成像的几何关系。通过标定&#xff0c;可以精确获取这些参数&#xff0c;从而将图像中的像素坐标与实际的物理坐标建立联系。例如&#xff0c;已知相机…

【AI插件开发】Notepad++ AI插件开发实践:支持配置界面

一、引用 此前的系列文章已基本完成了Notepad的AI插件的功能开发&#xff0c;但是此前使用的配置为JSON配置文件&#xff0c;不支持界面配置。 本章在此基础上集成支持配置界面&#xff0c;这样不需要手工修改配置文件&#xff0c;直接在界面上操作&#xff0c;方便快捷。 注…