FPGA—ZYNQ学习UART环回(五)
实验目的UART环回
完成HELLOward的时候,先添加UART.h 以及uart.c文件
1打开官方库文件
通过.mss进行打开 uart的官方库文件
选择普通的例子
1.1初始化例子

1.2uart设置模式
1.3xuartps.h
这里面是uartps端的参数,其中有uart控制器结构体以及 UART配置寄存器结构体以及buffer。
这是控制器的结构体,就是用uart这个功能看用哪个控制器进行操作,是uart控制器就需要先输入uart这个控制器地址,就需要uart这个控制器,然后需要进行配置uart以及其他配置
2.配置头文件
在uart.h中配置同文件,在uart.c中调用 uart.h

3.设置波特率

结构体的形参以及需要设置的波特率
4.操作模式函数
1的话开回环0不开回环

这个意思就是给一个uart控制器,然后设置他的模式,通过上面的模式参数填进去就行

回环模式
![]()
正常模式

5.设置uart发送以及接收函数。
在库文件中调用uart的发送和接收函数
u8 是无符号字符串儿型的。

其中第一个是控制器结构体 第二个是buffer缓冲区 第三个是字节数
总结来说这个,在发送的时候arm把发送的数据送到缓冲区,uatrt控制器把缓冲区的数据从给fifo输出接收端的时候uart控制器把接收的数据通过fifo送给buffer,arm在从不敢buffer中读取
5.1在 XUartPs_Send函数中(发送数据)
- •
Buffer 是“发货仓库”:它是一个在内存中开辟的空间,里面存放着您希望串口发送出去的原始数据字节。
- •
工作流程:ARM处理器(CPU)将需要发送的数据(比如一个字符串 "Hello")先写入到这个
Buffer中。然后,当调用XUartPs_Send函数时,UART驱动程序会从Buffer这个“仓库”里取出数据,搬运到UART控制器的发送FIFO(先入先出存储器)中,最后由UART硬件自动将数据转换成串行信号,通过TX引脚一位一位地发送出去 5.2在
XUartPs_Recv函数中(接收数据)- •
Buffer 是“收货仓库”:同样是一个内存空间,但它是空的,准备用来存放从串口接收到的数据。
- •
工作流程:UART硬件通过RX引脚监测线路,当收到数据时,会先将数据位组装成字节,存入接收FIFO。当您调用
XUartPs_Recv函数时,UART驱动程序会从UART硬件的接收FIFO中取出数据,搬运到您提供的Buffer这个“仓库”中。之后,您的ARM处理器程序就可以从Buffer里读取并处理这些数据了。 5.2.1 什么是静态变量以及动态变量
下面的定义的是一个动态变量,如果跳出这个函数那么count内存会释放,再次进入这个函数分配一个count地址它的值还是从0开始

下面定义的是静态变量static 跳出这个函数的内存地址不释放,再次进入这个地址紧接着上次的继续计数
5.2.2 添加控制接收的字节数 和地址
当计数器小于它的发送的长度,就会一直发送,发送的计数就是根据uartps的返回值,返回1成功,返回0不成功,
地址:如果是给内存地址不控制添加,那么接收的数据就会一直在这个地址进行赋值并没有地址的添加操作,所以不许要 buffer+count 每一次接收的都是下一个地址
![]()
5.3怎么去理解bufferptr地址

u8 *BufferPtr是一个指针,它的值就是一个内存地址。对于 Send函数,这个地址指向了您希望发送的第一字节数据所在的位置。驱动程序会从这个地址开始,连续读取 NumBytes个字节,然后交给UART硬件发送出去。
u8是一个无符号8位整数类型,其取值范围确实是0~255(共256个值)
每个
u8类型的变量只能存储一个字节的数据。- •
当我们需要发送一个字符串(如 "AB")时,字符 'A' 的ASCII码(65)存在第一个
u8位置,字符 'B' 的ASCII码(66)存在紧接着的下一个u8位置。 - •
所以,
BufferPtr指向的是一个 u8类型的数组,而不是一个单一的u8变量。这个数组在内存中是连续存放的。
6.判断是否发送完成
如果控制器返回的值是1,那么就是正在发送,返回0就是发送结束
7主函数的编写
设置id需要再参数.h里面寻找

这个就是通过接收的数据需要接收100个数据但是实际只接收了10个数据,在主函数中UartSendLen =strlen(UartRecBuf);就能够知道是只就收了10个数据对吧,然后吧这个长度送给发射端进行发射10个数据通过
strlen函数来动态获取实际接收到的数据长度,然后只发送有效数据,而不是机械地发送预设的100个字节。

这个就是通过接收的数据需要接收100个数据但是实际只接收了10个数据,在主函数中UartSendLen =strlen(UartRecBuf);就能够知道是只就收了10个数据对吧,然后吧这个长度送给发射端进行发射10个数据通过
strlen函数来动态获取实际接收到的数据长度,然后只发送有效数据,而不是机械地发送预设的100个字节。
7.1主函数main.c
/** main.c*/#include "string.h"
#include "main.h"
#include "gpio.h"
#include "uart.h"XUartPs PsUartCtrl;
u8 UartRecBuf[100];
u32 UartSendLen=0;int main()
{UartInit(&PsUartCtrl,XPAR_PS7_UART_1_DEVICE_ID,9600,0);while(1) //程序运行的死循环{UartRecData(&PsUartCtrl,UartRecBuf,100,10);UartSendLen = strlen(UartRecBuf);UartSendData(&PsUartCtrl,UartRecBuf,UartSendLen);}return 0;
}
7.2uart.h
/** uart.h*/#ifndef SRC_UART_H_
#define SRC_UART_H_#include "xil_types.h"
#include "xil_assert.h"
#include "xstatus.h"
#include "xuartps_hw.h"
#include "xplatform_info.h"
#include "xparameters.h"
#include "xuartps.h"/* 添加以下函数声明 */
u32 UartInit(XUartPs *UartPtr, u16 DeviceId, u32 BaudRate, u32 LoopTure);
u32 UartSendData(XUartPs *UartPtr, u8 *StrPtr, u32 StrLen);
u32 UartRecData(XUartPs *UartPtr, u8 *BufPtr, u32 BufLen, u32 StrLen);#endif /* SRC_UART_H_ */
7.3uart.c
/** uart.c*/#include "uart.h"u32 UartInit(XUartPs *UartPtr,u16 DeviceId,u32 BaudRate,u32 LoopTure)
{int Status;XUartPs_Config *Config;Config = XUartPs_LookupConfig(DeviceId);if (NULL == Config) {return XST_FAILURE;}Status = XUartPs_CfgInitialize(UartPtr, Config, Config->BaseAddress);if (Status != XST_SUCCESS) {return XST_FAILURE;}XUartPs_SetBaudRate(UartPtr,BaudRate);if(LoopTure){XUartPs_SetOperMode(UartPtr,XUARTPS_OPER_MODE_LOCAL_LOOP);}else{XUartPs_SetOperMode(UartPtr,XUARTPS_OPER_MODE_NORMAL);}return XST_SUCCESS;
}u32 UartSendData(XUartPs *UartPtr,u8 *StrPtr,u32 StrLen)
{while(XUartPs_IsSending(UartPtr));XUartPs_Send(UartPtr,StrPtr,StrLen);return XST_SUCCESS;
}u32 UartRecData(XUartPs *UartPtr,u8 *BufPtr,u32 BufLen,u32 StrLen)
{u32 RecCount = 0;while(RecCount < StrLen){RecCount += XUartPs_Recv(UartPtr,BufPtr + RecCount,BufLen);}return XST_SUCCESS;
}






