不需要了解时序。
UART是全双工异步收发的,没有时钟。
UART的操作通过配置和模式寄存器控制。
UART由独立的接受和发送路径构成。每个路径包含深度为64字节的FIFO。FIFO中断状态为支持轮询或中断方式。
轮询方式:不停地读取寄存器看有没有数据。
中断方式:只有当接收到串口数据后才打断主进程来接收数据。
数据位宽:6/7/8bit
停止位:1/1.5/2bit
CPU通过APB接口将数据写入发送FIFO,直到发送模块(Transmitter,执行并转串)将数据从FIFO中读出并送到移位寄存器。CPU通过操纵TxFIFO寄存器来写数据。
写入数据后,TxFIFO的空标志被清零,发送模块检测到非空后,开始从TxFIFO中读出数据,并转为串行。
接收FIFO存储来源于接收模块(Receiver,执行串转并)的数据,写入RxFIFO。CPU通过APB接口读取RxFIFO寄存器。
阈值触发:当RxFIFO接收到设定的阈值位数的数据后,阈值触发标志位变为1。可用于产生中断。
有两个状态寄存器:
读写数据操纵的都是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);}