sdk例程:PS串口接收不定长数据,以及接收文件 - minichao9901/TangNano-20k-Zynq-7020 GitHub Wiki

c程序

注意这个程序中,接收不定长数据的超时终止逻辑是如何写的


#include "ACZ702_Lib/COMMON.h"
#include "xil_cache.h"

#define MAX_LENGTH (65535*10)
uint8_t RecvBuffer[MAX_LENGTH];
u32 ReceivedCount = 0;

int main(void)
{
	PS_UART_Init(&UartPs1,XPAR_PS7_UART_0_DEVICE_ID, XUARTPS_OPER_MODE_NORMAL, 115200);
//	xil_printf("Pleas input file bytes:\n");

#if(0) /*接收定长数据,这里不用*/
	u32 length=55845;
	u32 ReceivedCount = 0;
	while (ReceivedCount < length) {
		ReceivedCount +=
			XUartPs_Recv(&UartPs1, &RecvBuffer[ReceivedCount],
					  (length - ReceivedCount));
#endif

#if(1)/*接收不定长数据*/
	u32 loop_cnt=0;
	while (ReceivedCount<=MAX_LENGTH) {
		u32 OneTimeCount=XUartPs_Recv(&UartPs1, &RecvBuffer[ReceivedCount],
					  (MAX_LENGTH - ReceivedCount));
		ReceivedCount+=OneTimeCount;

		if(ReceivedCount>0){ /*只有当接收到数据后,才开始计数。最初没有接收到数据,不计数。*/
			if(OneTimeCount==0){/*当接收停顿后,开始计时*/
				usleep(10);
				loop_cnt++;
				if(loop_cnt>10000) /*这个计数长度要大于sscom每发送256bytes后的停顿时间*/
					break;
			}
			else{
				loop_cnt=0; /*一旦接收到数量不为零,那么计数值就清零*/
			}
		}
	}
#endif

	u32 TransmitCount = 0;
	u32 remainBytes=ReceivedCount;
	while (remainBytes >= 32) {
		TransmitCount+=XUartPs_Send(&UartPs1, &RecvBuffer[TransmitCount],32);
		while (XUartPs_IsSending(&UartPs1)) {}
		remainBytes-=32;
	}
	if(remainBytes){
		TransmitCount+=XUartPs_Send(&UartPs1, &RecvBuffer[TransmitCount],remainBytes);

		while (XUartPs_IsSending(&UartPs1)) {}
	}

	return 0;
}

测试结果

发送文件

image image image image image

可见发送结果正确

补充说明,sscom的发送文件的设置

sscom可以设置每发送256bytes延时一定时间,让接收机有时间处理数据。这个非常人性化。

image

附录:用数据结构,整理成通用的函数库

.h文件

typedef struct{
	u8 rec_buff[65536*10];
	u32 recv_length;
} rec_buff_t;

void PS_UART_RX(rec_buff_t *pbuf);
void PS_UART_TX(rec_buff_t *pbuf);

.c文件

/***********************************************************************************************************
* 不定长度接收与发送
***********************************************************************************************************/
void PS_UART_RX(rec_buff_t *pbuf)
{
	PS_UART_Init(&UartPs1,XPAR_PS7_UART_0_DEVICE_ID, XUARTPS_OPER_MODE_NORMAL, 115200);

	u32 max_length=sizeof(pbuf->rec_buff);
	u32 ReceivedCount=0;
	u32 loop_cnt=0;
	while (ReceivedCount<=max_length) {
		u32 OneTimeCount=XUartPs_Recv(&UartPs1, &pbuf->rec_buff[ReceivedCount],
					  (max_length- ReceivedCount));
		ReceivedCount+=OneTimeCount;

		if(ReceivedCount>0){ /*只有当接收到数据后,才开始计数。最初没有接收到数据,不计数。*/
			if(OneTimeCount==0){/*当接收停顿后,开始计时*/
				usleep(10);
				loop_cnt++;
				if(loop_cnt>10000){ /*这个计数长度要大于sscom每发送256bytes后的停顿时间*/
					pbuf->recv_length=ReceivedCount;
					break;
				}
			}
			else{
				loop_cnt=0; /*一旦接收到数量不为零,那么计数值就清零*/
			}
		}
	}
}

void PS_UART_TX(rec_buff_t *pbuf)
{
	u32 TransmitCount = 0;
	u32 remainBytes=pbuf->recv_length;
	while (remainBytes >= 32) {
		TransmitCount+=XUartPs_Send(&UartPs1, &pbuf->rec_buff[TransmitCount],32);
		while (XUartPs_IsSending(&UartPs1)) {}
		remainBytes-=32;
	}
	if(remainBytes){
		TransmitCount+=XUartPs_Send(&UartPs1, &pbuf->rec_buff[TransmitCount],remainBytes);

		while (XUartPs_IsSending(&UartPs1)) {}
	}
}

main.c文件

rec_buff_t rec_buffer;

PS_UART_RX(&rec_buffer);
PS_UART_TX(&rec_buffer);

image