当前位置: 首页 > news >正文

6.1 - UART串口数据收发环回实验

文章目录

  • 1 实验任务
  • 2 系统框图
  • 3 软件设计

1 实验任务

本实验任务是使用PS端UART控制器,完成串口中断数据环回的功能。

2 系统框图

在这里插入图片描述

3 软件设计

注意事项:

  1. 同时使能XUARTPS_IXR_RXOVR 和XUARTPS_IXR_TOUT,以支持不定长数据接收;
  2. 对于XUartPs_Recv函数
    • (1) 禁用所有中断
    • (2) 使用XUartPs_ReceiveBuffer函数从RX FIFO中读取数据
    • (3) 恢复中断使能
    • (4) 返回实际读取的个数;
  3. 接收超时是个好东西,哈哈哈。
/************************** Include Files ***********************************/
#include "xparameters.h"
#include "xuartps.h"
#include "xscugic.h"
#include "xil_exception.h"
#include "stdio.h"

/************************** Constant Definitions ****************************/
#define UART_DEVICE_ID		XPAR_XUARTPS_0_DEVICE_ID
#define INTC_DEVICE_ID		XPAR_SCUGIC_SINGLE_DEVICE_ID
#define UART_INTR_ID		XPAR_XUARTPS_1_INTR

#define BUFFER_SIZE 		64   // 接收缓冲区大小
#define FIFO_TRIGGER_LEVEL  32   // FIFO触发阈值
#define RECV_TIMEOUT        4    // 接收超时时间(单位:波特率时钟周期)

/************************** Function Prototypes *****************************/
s32  UartPsInit(XUartPs *UartPsInstPtr, XUartPsFormat* UartFormatPtr);
s32  SetupInterruptSystem(XScuGic *IntcInstPtr, XUartPs *UartPsInstPtr);
void UartIntrHandler(void *CallBackRef);

/************************** Variable Definitions ****************************/
XUartPs UartInst;
XScuGic IntcInst;

u8 RxBuffer[BUFFER_SIZE] = { 0 };  // 接收缓冲区

int RxDataLength = 0;  // 接收到的数据长度

XUartPsFormat UartFormat = {
		XUARTPS_DFT_BAUDRATE,     // 115200
		XUARTPS_FORMAT_8_BITS,
		XUARTPS_FORMAT_NO_PARITY,
		XUARTPS_FORMAT_1_STOP_BIT
};
/************************** Function Implementation *************************/

int main()
{
	//
	s32 Status;
	// 初始化UART
	Status = UartPsInit(&UartInst, &UartFormat);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}
	// 设置中断系统
	Status = SetupInterruptSystem(&IntcInst, &UartInst);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}
	// 主循环
	while(1)
	{
		;
	}
	//
	return 0;
}

s32 UartPsInit(XUartPs *UartInstPtr, XUartPsFormat* UartFormatPtr)
{
	//
	s32 Status;
	XUartPs_Config *UartConfigPtr;
	// 查找UART配置
	UartConfigPtr = XUartPs_LookupConfig(UART_DEVICE_ID);
	if(NULL == UartConfigPtr)
	{
		return XST_FAILURE;
	}
	// 初始化UART
	Status = XUartPs_CfgInitialize(UartInstPtr, UartConfigPtr, UartConfigPtr->BaseAddress);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}
	// 设置UART数据格式
	XUartPs_SetDataFormat(UartInstPtr, UartFormatPtr);
	// 设置UART操作模式
	XUartPs_SetOperMode(UartInstPtr, XUARTPS_OPER_MODE_NORMAL);
	// 设置接收FIFO触发阈值
	XUartPs_SetFifoThreshold(UartInstPtr, FIFO_TRIGGER_LEVEL);
	// 设置接收超时
	XUartPs_SetRecvTimeout(UartInstPtr, RECV_TIMEOUT);
	// 设置中断掩码,使能FIFO触发中断和接收超时中断
	XUartPs_SetInterruptMask(UartInstPtr, XUARTPS_IXR_RXOVR | XUARTPS_IXR_TOUT);
	//
	return XST_SUCCESS;
}

s32 SetupInterruptSystem(XScuGic *IntcInstPtr, XUartPs *UartInstPtr)
{
	//
	s32 Status;
	XScuGic_Config *IntcConfigPtr;
	// 初始化中断控制器GIC
	IntcConfigPtr = XScuGic_LookupConfig(INTC_DEVICE_ID);
	if (NULL == IntcConfigPtr)
	{
		return XST_FAILURE;
	}

	Status = XScuGic_CfgInitialize(IntcInstPtr, IntcConfigPtr, IntcConfigPtr->CpuBaseAddress);
	if (Status != XST_SUCCESS)
	{
		return XST_FAILURE;
	}
	// 注册异常处理程序
	Xil_ExceptionInit();
	Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, (Xil_ExceptionHandler)XScuGic_InterruptHandler, IntcInstPtr);
	Xil_ExceptionEnable();
	// 连接UART中断处理程序
	XScuGic_Connect(IntcInstPtr, UART_INTR_ID, (Xil_InterruptHandler)UartIntrHandler, (void *)UartInstPtr);
	// 使能UART中断
	XScuGic_Enable(IntcInstPtr, UART_INTR_ID);
	//
	return XST_SUCCESS;
}

void UartIntrHandler(void *CallBackRef)
{
	//
	XUartPs* UartInstPtr = (XUartPs*)CallBackRef;
	u32 IsrStatus;
	// 读取中断状态
	IsrStatus = XUartPs_ReadReg(UartInstPtr->Config.BaseAddress, XUARTPS_IMR_OFFSET);
	IsrStatus &= XUartPs_ReadReg(UartInstPtr->Config.BaseAddress, XUARTPS_ISR_OFFSET);
	// 处理FIFO触发中断
	if ((IsrStatus & (u32)XUARTPS_IXR_RXOVR) != (u32)0) {
		// 读取FIFO中的数据
		RxDataLength = XUartPs_Recv(UartInstPtr, RxBuffer, BUFFER_SIZE);
		// 清除中断状态
		XUartPs_WriteReg(UartInstPtr->Config.BaseAddress, XUARTPS_ISR_OFFSET, XUARTPS_IXR_RXOVR);
		//
		printf("Rx Trigger, Receive %u Bytes.\n", RxDataLength);
	}
	// 处理接收超时中断
	if ((IsrStatus & (u32)XUARTPS_IXR_TOUT) != (u32)0) {
		// 读取FIFO中剩余的数据
		RxDataLength = XUartPs_Recv(UartInstPtr, RxBuffer, BUFFER_SIZE);
		// 清除中断状态
		XUartPs_WriteReg(UartInstPtr->Config.BaseAddress, XUARTPS_ISR_OFFSET, XUARTPS_IXR_TOUT);
		//
		printf("Rx Timeout, Receive %u Bytes.\n", RxDataLength);
	}
	// 如果有数据接收到
	if (RxDataLength > 0) {
		// 处理接收到的数据
		XUartPs_Send(UartInstPtr, RxBuffer, RxDataLength);
		//
		RxDataLength = 0;
	}
	//
	return;
}

相关文章:

  • 代码随想录第三十八天| 322. 零钱兑换 279.完全平方数 139.单词拆分 动态规划:关于多重背包,你该了解这些!
  • 布隆过滤器:一种简单而高效的集合查询方法
  • git中,如何查看具体单个文件的log
  • 3dtiles平移旋转工具制作
  • 今日运维之-Mac笔记本python环境问题
  • FFmpeg视频处理入门级教程
  • 汇编语言 第九章-转移指令的原理
  • Python GUI
  • OpenCV给图像添加噪声
  • 每日一题之铠甲合体
  • 代码随想录day21
  • 哈希表的复习
  • 25全国各省自考报名时间汇总⏰照片要求✅
  • 【附源码】基于opencv+pyqt5搭建的人脸识别系统
  • Golang 构建学习
  • 涉密载体管控系统革新:RFID技术引领,信息安全新境界
  • 《全星质量管理 QMS 软件系统》:赋能企业高效质量管理
  • javascript如何通过原型链实现对象的继承,并指出这种继承方式的优缺点
  • ViT 模型介绍(三)——简单实战项目
  • ctfshow做题笔记—栈溢出—pwn57~pwn60
  • 华住集团:第一季度盈利8.94亿元,同比增长超三成
  • 美国前驻华大使携美大学生拜访中联部、外交部
  • 上海电视节评委会名单公布,陈宝国担任电视剧评委会主席
  • 新质观察|低空货运是城市发展低空经济的第一引擎
  • 15年全免费,内蒙古准格尔旗实现幼儿园到高中0学费
  • 竞彩湃|足总杯决赛或有冷门,德甲欧冠资格之争谁笑到最后