len = UART1_RecvString(RxBuff);
if(len)
{
PRINT("RECV_OK");
UART1_SendString(RxBuff, len);
}
这个代码 下载后,可以每次都转发收到得数据,但是print不会执行输出,并且在反复转发十几遍后会连续打印出来几十个print得字符串就是“recv_ok”,请问是不是库函数得问题,要如何解决
len = UART1_RecvString(RxBuff);
if(len)
{
PRINT("RECV_OK");
UART1_SendString(RxBuff, len);
}
这个代码 下载后,可以每次都转发收到得数据,但是print不会执行输出,并且在反复转发十几遍后会连续打印出来几十个print得字符串就是“recv_ok”,请问是不是库函数得问题,要如何解决
使用默认的工程配置,需要在PRINT字符串后面加一个‘\n’才显示,比如这样写PRINT("RECV_OK\n");
也可以不用加这个'\n',见下方博客中的勾选配置。
非常感谢工程师恢复,以上问题解决了,又有一个新问题,麻烦工程师抽时间帮忙看一下,
还是这段代码,我往单片机发送ABCD
if(len)
{
PRINT("recv-ok");
UART1_SendString(RxBuff, len);
}
打印出来的信息是这样的
recv-okA
recv_okBCD
打印出来了两行,而且把收到的字符串给拆分了,请问这个是哪里操作的不对,谢谢
您好,R8_UART1_RFC在收到第一个字节数据的时已经置为了1,在没有占用串口PRINT的情况下,在下一个字节收到之前就已经处理完了这1个字节数据,等待下个字节,也就是说会逐个字节处理。PRINT打印“recv-ok”需要一段时间,这段时间刚好够接收接下来的3个字节,故出现以上现象。
建议使用串口中断,FIFO设置字节触发可以避免逐个字节处理。非要用查询的话也可以自行添加逻辑,比如说R8_UART1_RFC小于n时就不接收BRB中的数据,若一直小于n超过自定义时长后,就判断为超时,全部接收。
感谢工程师回复,以上问题已经明白了,现在又遇到一个问题要麻烦工程师,
len = UART1_RecvString(RxBuff);
if(len)
{
endp = ThisUsb2Dev.GpVar[2]; // send端点
PRINT(" ---len= %02x\n",len);
用这个函数去读取串口接收得数据,只能收8个字节,8个以下正常,超过8个就只显示8个,长度也是8个,如果强制给len+1,多打印出来得那个字节就是00,不是正常发送的数据。
uint16_t UART1_RecvString(uint8_t *buf)
{
uint16_t len = 0;
while(R8_UART1_RFC)
{ PRINT(" -len- %02x\n",len);
*buf++ = R8_UART1_RBR;
len++;
}
return (len);
}
我在库函数里面加了一个print,打印出来也是0到7,只要发送超过8个字节就只能收到8个,麻烦工程师不忙的时候给指点以下,是哪里没弄明白,感谢感谢
您好,串口接收fifo最多缓存8个字节的数据,调用一次UART1_RecvString也就只能接收缓存中的数据,超过不了8个。接收更多的数据需要多次调用UART1_RecvString,如果没有及时接收数据,会出现丢包问题。
谢谢谢谢,明白了,原来是这个问题,请问老师,我要使用蓝牙,是不是就没办法使用串口中断了?麻烦请老师您给个思路,要怎么做才能避免丢包,感谢感谢
使用蓝牙功能,可以继续使用串口中断进行收发数据。但是如果开启睡眠功能会遇到一个问题:睡眠只有通过GPIO或者TMOS的任务进行唤醒,此时如果串口来数据,蓝牙正在睡眠会出现收不到数据的情况。因此在进行串口接收数据时一定要先将串口的功能切换为通用GPIO作为唤醒。
具体操作:串口在数据到来时会出现高电平到低电平的信号,利用这个下降沿或者低电平信号作为GPIO的唤醒源,在信号到来时芯片被唤醒进入到中断接收数据。此时需要在中断中置一个标志,这个标志是为了等待串口的数据接收完成,在数据接收未完成的情况下,蓝牙由于协议栈管理会自动进入睡眠,这时需要根据这个标志手动的去退出睡眠(return)。等待数据接收完成后再将标志置位重新恢复睡眠功能。
可以参考一下这篇博客:
CH579 CH573 CH582 串口切换GPIO睡眠唤醒操作 - debugdabiaoge - 博客园 (cnblogs.com)