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);}

相关内容

热门资讯

前端-session、jwt 目录:   (1)session (2&#x...
linux入门---制作进度条 了解缓冲区 我们首先来看看下面的操作: 我们首先创建了一个文件并在这个文件里面添加了...
关于测试,我发现了哪些新大陆 关于测试 平常也只是听说过一些关于测试的术语,但并没有使用过测试工具。偶然看到编程老师...
前缀和与对数器与二分法 1. 前缀和 假设有一个数组,我们想大量频繁的去访问L到R这个区间的和,...
nodejs:本地安装nvm实... 一、背景-使用不同版本node的原因 vue3+ts、nuxt3版本,node...
JAVA集合知识整理 Java集合知识整理 HashMap相关 HashMap的底层数据结构:jdk1.8之...
无刷直流电机介绍及单片机控制实... 无刷直流电机介绍及单片机控制实例前言基本概念优势与劣势使用寿命基本结构使用单片机控制实例电子调速器&...
fwdiary(2) dp2 1.传纸条  AcWing 275. 传纸条 - AcWing 走两条路,走一条最大的...
常用的DOS命令 常用的DOS命令 DOS(Disk Operating System,磁...
<C++> 类和对象(下) 1.const成员函数将const修饰的“成员函数”称之为const成员函数,cons...