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;
}
测试结果
发送文件
可见发送结果正确
补充说明,sscom的发送文件的设置
sscom可以设置每发送256bytes延时一定时间,让接收机有时间处理数据。这个非常人性化。
附录:用数据结构,整理成通用的函数库
.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);