UartPS串口收发函数详解

单字节收发

uartps是xilinx为PS端提供的串口收发库,其最简单的收发函数为

void XUartPs_SendByte(u32 BaseAddress, u8 Data)
u8 XUartPs_RecvByte(u32 BaseAddress)	

【XUartPs_SendByte】用于数据发送,其中Data即为发送的字节,【XUartPs_RecvByte】的返回值为接收到的字节。参数BaseAddress为串口地址,可在xparameters.h中找到。

一个简单的示例如下

#define UART 				XPAR_XUARTPS_0_BASEADDR
void uartByteTest(){
    int i = 0;
    char ch;
    char buf[32];
    while (1) {
        ch = XUartPs_RecvByte(UART);
        if (ch == '.' || i == 32){
        	i = 0;
        	continue;
        }
        buf[i++] = ch;
        XUartPs_SendByte(UART, ch); // Echo back
    }
}

其功能很简单,就是把接收到的数据重新发回去,如果该数据以点号结尾,则不发送这个点号。通过串口调试助手测试如下

[2025-08-18 09:14:43.122]# SEND ASCII/6 >>>
hello.

[2025-08-18 09:14:43.175]# RECV ASCII/5 <<<
hello

数组收发

uartps中提供了两个相对复杂的数组收发函数,原型如下

u32 XUartPs_Send(XUartPs * InstancePtr, u8 * BufferPtr, u32 NumBytes)
u32 XUartPs_Recv(XUartPs * InstancePtr, u8 * BufferPtr, u32 NumBytes)	

这两个函数的输入参数相同,均为串口指针、数据指针和数据长度。需要注意的是,其第一个参数为XuartPS的指针,而非单字节收发函数的串口地址。对于这两组收发函数,一个简单的示例如下

void uartTest(){
	char cBuf[10];
    XUartPs Uart_PS;
    int nRecv;

    // 初始化UART
    XUartPs_Config *Uart_Config = XUartPs_LookupConfig(XPAR_XUARTPS_0_DEVICE_ID);
    XUartPs_CfgInitialize(&Uart_PS, Uart_Config, Uart_Config->BaseAddress);

	while(1){
		usleep(10000);
		nRecv = XUartPs_Recv(&Uart_PS, (u8 *)cBuf, 10);
		if(nRecv > 0)
			XUartPs_Send(&Uart_PS, (u8 *)cBuf, 10);
	}
}

其中,【XUartPs_Config】是串口的配置参数,【XUartPs_CfgInitialize】用于初始化串口。

【XUartPs_Recv】的原理是,直接从Uart_PS所在地址读取数据,不管这些数据是否为上位机传来的数据,都会立即返回。如果上位机没有传来数据,那么其返回值就是0个数据。正因如此,需要对其返回值进行判断,只有大于0时,才视作有效的数据。另一方面,为了让上位机传来的数据充分占据UART所在地址,在每次接收之前,需要等待10ms。

接收结构体

在工程应用中,串口通信需要在严格的协议下进行,协议中不同的位置代表不同的数据,例如,我们希望计算除法,那么可以定义如下结构体,包括一个帧头和校验位,中间是除数和被除数。

#pragma pack(push, 1)
typedef struct {
	u8 head;
	u32 dividend;
	u32 divisor;
	u8 check;
} DivData;
#pragma pack(pop)

其中pack语句用于取消结构体的字节对齐,从而让其成员之间不存在缝隙,能够与数组之间无缝转换。其验证程序如下

void uartTest(){
  DivData * dv;
  XUartPs Uart_PS;
  int nRecv, a, b;
  float res;

  XUartPs_Config *Uart_Config = XUartPs_LookupConfig(XPAR_XUARTPS_0_DEVICE_ID);
  XUartPs_CfgInitialize(&Uart_PS, Uart_Config, Uart_Config->BaseAddress);

	while(1){
		usleep(10000);
		nRecv = XUartPs_Recv(&Uart_PS, (u8 *)dv, 10);
		if(nRecv > 0){
			res = 1.0*dv->dividend/dv->divisor;
			a = (int)res;
			b = (int)((res-a)*1000);
			xil_printf("%d/%d=%d.%d", dv->dividend, dv->divisor, a, b);
		}
	}
}

测试如下

# SEND HEX/10 >>>
AA FF 00 00 00 02 00 00 00 00 

# RECV ASCII/13 <<<
255/2=127.500
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

微小冷

请我喝杯咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值