ZYNQ嵌入式学习(5)
创始人
2024-05-30 15:10:13
0

UART

  • UART简介
    • 发送FIFO
    • 接收FIFO
    • 模式切换
    • 寄存器操作
      • 中断和状态寄存器
  • 发送数据
    • 轮询
    • 中断
  • 接收数据
    • 轮询
    • 中断
  • 实验:串口中断数据环回

UART简介

不需要了解时序。
UART是全双工异步收发的,没有时钟。
UART的操作通过配置和模式寄存器控制。
UART由独立的接受和发送路径构成。每个路径包含深度为64字节的FIFO。FIFO中断状态为支持轮询或中断方式。
轮询方式:不停地读取寄存器看有没有数据。
中断方式:只有当接收到串口数据后才打断主进程来接收数据。
数据位宽:6/7/8bit
停止位:1/1.5/2bit


发送FIFO

CPU通过APB接口将数据写入发送FIFO,直到发送模块(Transmitter,执行并转串)将数据从FIFO中读出并送到移位寄存器。CPU通过操纵TxFIFO寄存器来写数据。
写入数据后,TxFIFO的空标志被清零,发送模块检测到非空后,开始从TxFIFO中读出数据,并转为串行。

接收FIFO

接收FIFO存储来源于接收模块(Receiver,执行串转并)的数据,写入RxFIFO。CPU通过APB接口读取RxFIFO寄存器。
阈值触发:当RxFIFO接收到设定的阈值位数的数据后,阈值触发标志位变为1。可用于产生中断。

模式切换

寄存器操作

中断和状态寄存器

有两个状态寄存器:

  • 中断状态寄存器可以被读取状态和产生中断。(sticky)
  • 状态寄存器仅能读取状态。(dynamic)
    中断状态寄存器和掩码寄存器(只读)按位与。仅有都为1的位才能产生中断,送入中断控制器。

    通过中断使能寄存器和中断除能寄存器来控制中断掩码寄存器。

    收发FIFO寄存器的几种中断:空、满、触发阈值、接近满、溢出。

发送数据

轮询

  1. 检查TxFIFO是否为空
  2. 向TxFIFO中写数(64B)
  3. 等待TxFIFO空后再次写入

中断

  1. 除能TxFIFO空中断
  2. 向TxFIFO中写数(64B)
  3. 检查TxFIFO中还有没有空间可以写数
  4. 重复2、3
  5. 使能中断
  6. 等待TxFIFO为空后返回1

接收数据

轮询

  1. 等待RxFIFO中数据达到阈值或接收超时
  2. 从RxFIFO中读数据
  3. 重复2直到RxFIFO空
  4. 若接收超时,清除超时位

中断

  1. 使能中断
  2. 等待RxFIFO中数据达到阈值或接收超时
  3. 从RxFIFO中读数据
  4. 重复2、3
  5. 清除中断

读写数据操纵的都是TX_RX_FIFO0寄存器,其中包含收发两个FIFO。

实验:串口中断数据环回

/******************************************************************************
*
* 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.
*
******************************************************************************//** helloworld.c: simple test application** This application configures UART 16550 to baud rate 9600.* PS7 UART (Zynq) is not initialized by this application, since* bootrom/bsp configures it to baud rate 115200** ------------------------------------------------* | UART TYPE   BAUD RATE                        |* ------------------------------------------------*   uartns550   9600*   uartlite    Configurable only in HW design*   ps7_uart    115200 (configured by bootrom/bsp)*/
/** 20230307运行成功!*/
#include 
//#include "platform.h"
#include "xil_printf.h"
#include "xuartps.h"
#include "xparameters.h"
#include "xscugic.h"
#include "xuartps_hw.h"#define UART_DEVICE_ID		XPAR_XUARTPS_0_DEVICE_ID
#define UART_INT_IRQ_ID		XPAR_XUARTPS_0_INTR
#define INTC				XScuGic
#define INTC_DEVICE_ID		XPAR_SCUGIC_0_DEVICE_ID
//#define TEST_BUFFER_SIZE	100XUartPs UartPs	;
XUartPs_Config *Config;
INTC InterruptController;	// 中断控制器驱动实例
//u8 RecvBuffer[TEST_BUFFER_SIZE];void Handler();
void uart_init();
void uart_intr_handler();
void uart_intr_init(INTC *IntcInstancePtr,XUartPs *UartInstancePtr,u16 UartIntrId);
int SetupInterruptSystem(INTC *IntcInstancePtr,XUartPs *UartInstancePtr,u16 UartIntrId);
int main()
{// 串口初始化uart_init();xil_printf("Uart initializes successfully!");// 串口中断初始化(包含:1.对Uart的中断进行配置;2.对PS的中断控制器(Gic)进行配置)uart_intr_init(&InterruptController, &UartPs, UART_INT_IRQ_ID);while(1); // 让程序停在这个位置,用来检测中断,只有cpu收到中断指令,才会跳出while(1),进入中断服务子程序return 0;
}// 串口初始化函数
void uart_init(){Config = XUartPs_LookupConfig(UART_DEVICE_ID);XUartPs_CfgInitialize(&UartPs, Config, Config->BaseAddress);// 设置串口工作模式XUartPs_SetOperMode(&UartPs, XUARTPS_OPER_MODE_NORMAL);// 设置串口波特率(默认就是115200)XUartPs_SetBaudRate(&UartPs, 115200);// 设置接收FIFO中断事件触发阈值,这里设置为1Byte,即每接收到1字节的数据就要产生一次中断,在中断函数中处理此中断XUartPs_SetFifoThreshold(&UartPs, 1);
}// 串口中断初始化函数
void uart_intr_init(INTC *IntcInstancePtr,XUartPs *UartInstancePtr,u16 UartIntrId){/** 以下为中断控制器Gic配置*/XScuGic_Config *IntcConfig;IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);XScuGic_CfgInitialize(IntcInstancePtr, IntcConfig, IntcConfig->CpuBaseAddress);// 关联中断ID和中断处理函数XScuGic_Connect(IntcInstancePtr, UartIntrId, (Xil_ExceptionHandler) uart_intr_handler, (void *) UartInstancePtr);// 设置并打开中断异常处理功能Xil_ExceptionInit();Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, (Xil_ExceptionHandler) XScuGic_InterruptHandler,IntcInstancePtr);Xil_ExceptionEnable();/** 以下为Uart中断配置*/// 设置UART中断触发方式,即哪些状态位能够产生中断u32 IntrMask;IntrMask = XUARTPS_IXR_RXOVR; 	// 接收fifo触发阈值中断位XUartPs_SetInterruptMask(UartInstancePtr, IntrMask);/** 使能UART中断*/XScuGic_Enable(IntcInstancePtr, UartIntrId);
}// 中断处理函数
void uart_intr_handler(XUartPs *UartInstancePtr){// 读取中断状态寄存器u32 rec_data = 0;u32 IsrStatus;IsrStatus = XUartPs_ReadReg(UartInstancePtr->Config.BaseAddress,XUARTPS_IMR_OFFSET);		// 获取中断掩码寄存器值,此处应该只有最低位为1,对应接收触发阈值中断IsrStatus &= XUartPs_ReadReg(UartInstancePtr->Config.BaseAddress,XUARTPS_ISR_OFFSET);		// 获取对应的中断状态寄存器的值// 若满足中断掩码寄存器和中断状态寄存器的与为1,再和接收fifo触发阈值位相与,为高电平,则确实为所需类型中断/** 接收处理*/if(IsrStatus & XUARTPS_IXR_RXOVR) {// 读取出Rxfifo中接收到的数据(仅一个字节)//	rec_data = XUartPs_Recv(UartInstancePtr, RecvBuffer, TEST_BUFFER_SIZE);rec_data = XUartPs_RecvByte(UartInstancePtr->Config.BaseAddress);// 清除中断状态寄存器的接收fifo触发阈值位XUartPs_WriteReg(UartInstancePtr->Config.BaseAddress, XUARTPS_ISR_OFFSET,XUARTPS_IXR_RXOVR);}/** 发送处理*/XUartPs_SendByte(UartInstancePtr->Config.BaseAddress, rec_data);}

相关内容

热门资讯

【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
AsusVivobook无法开... 首先,我们可以尝试重置BIOS(Basic Input/Output System)来解决这个问题。...
ASM贪吃蛇游戏-解决错误的问... 要解决ASM贪吃蛇游戏中的错误问题,你可以按照以下步骤进行:首先,确定错误的具体表现和问题所在。在贪...
月入8000+的steam搬砖... 大家好,我是阿阳 今天要给大家介绍的是 steam 游戏搬砖项目,目前...