发新帖我要提问
12
返回列表
[技术问答]

UART碰到的一些问题

[复制链接]
楼主: pq113_6
手机看帖
扫描二维码
随时随地手机跟帖
lihui567| | 2019-10-31 12:46 | 显示全部楼层
pq113_6 发表于 2019-10-30 09:45
开一个buffer,UART中断把数据存在buffer中,定时1ms判断这个buffer是否有数据。最大是267个字节数据,我 ...

都设置串口中断优先级了,不会有冲突的,程序问题较大

使用特权

评论回复
pq113_6|  楼主 | 2019-11-1 13:23 | 显示全部楼层
JasonLee27 发表于 2019-10-31 09:14
printf本来就是通过uart2输出格式化字符串,如果uart2在用于打印输出,不建议再通过其他方式使用,或者在 ...

有人可以看看这个问题吗?看看会不会也有问题?

使用特权

评论回复
TechHolder| | 2019-11-1 14:51 | 显示全部楼层
pq113_6 发表于 2019-10-31 11:23
我用官方例程改了一个uart的程序,复现到问题了,测试方法如下:
1. 例程改为2路UART,UART1作为通信使用 ...

你的意思是UART1接收不管怎么样总是会丢一个字节?

使用特权

评论回复
pq113_6|  楼主 | 2019-11-1 15:36 | 显示全部楼层
TechHolder 发表于 2019-11-1 14:51
你的意思是UART1接收不管怎么样总是会丢一个字节?

我基本上是看到丢一个字节,不是固定的位置。

使用特权

评论回复
JasonLee27| | 2019-11-4 16:16 | 显示全部楼层
pq113_6 发表于 2019-10-31 11:23
我用官方例程改了一个uart的程序,复现到问题了,测试方法如下:
1. 例程改为2路UART,UART1作为通信使用 ...
int32_t UART_IRQHandler(uint8_t port, uint32_t LSR0, uint32_t LSR1)
{
    UART_Type *UARTx;
    if(port == 1)
        UARTx = UART1;
    else
        UARTx = UART2;
        if ((UARTx->UARTn_IER.ERXNE == 1) && (LSR0 & LSR0_DR))
    {
        uint8_t uartData = UART_ReceiveData(UARTx);
        UART_SendData(UART2, uartData);
        while(!UART2->UARTn_LSR0.TC);
        if ((!g_recvedDataRdy) && (g_recvDataTtlLen < UART_DATA_LEN_SEL))//½ÓÊÕÊý¾Ý
                {
                        g_recvedDataBuf[g_recvDataTtlLen++] = uartData;
                        if (g_recvDataTtlLen == UART_DATA_LEN_SEL)//Êý¾Ý½ÓÊÕÍê±Ï
                        {
                                g_recvedDataRdy = TRUE;
                                g_recvDataTtlLen = 0;
                        }
                }
    }

    if ((UARTx->UARTn_IER.ETXE == 1) && (LSR0 & LSR0_THRE))//·¢ËÍÊý¾Ý
    {
      
    }

    return 0;
}
我觉得UART中断这部分代码这样写是有问题的,你UART1中断中收到数据后将数据送入UART2并等待UART2发送完成,等于你UART2的发送完全是在UART1中断中执行的,那么很容易导致UART1产生溢出,测试的方法是在中断里面再增加一个溢出标志检查,通过仿真的方式看UART1是否产生溢出标志。或者你可以换种方式,在UART2发送前先判断再发送,或者直接发送不判断。这样可以避免UART2的发送占用UART1的中断时间。

使用特权

评论回复
pq113_6|  楼主 | 2019-11-13 16:12 | 显示全部楼层
Update一下,问题已经解决,不是芯片的问题,是代码有个bug,正好这颗芯片碰到了。

使用特权

评论回复
JasonLee27| | 2019-11-13 17:03 | 显示全部楼层
pq113_6 发表于 2019-11-13 16:12
Update一下,问题已经解决,不是芯片的问题,是代码有个bug,正好这颗芯片碰到了。 ...

所以这颗芯片还有查bug的能力?

使用特权

评论回复
TechHolder| | 2019-11-13 17:19 | 显示全部楼层
pq113_6 发表于 2019-10-31 11:23
我用官方例程改了一个uart的程序,复现到问题了,测试方法如下:
1. 例程改为2路UART,UART1作为通信使用 ...

使用你的代码做了一下测试,没有屏蔽while(!UART2->UARTn_LSR0.TC);代码前是会丢失数据,屏蔽后不会丢失数据,连续测试了几分钟,如下图: UART_3.png

也附上修改后的代码,你可以测试一下。

UART_Sample.rar

2.39 MB

使用特权

评论回复
pq113_6|  楼主 | 2019-11-13 17:47 | 显示全部楼层
JasonLee27 发表于 2019-11-13 17:03
所以这颗芯片还有查bug的能力?

哈哈,确实是,可能正好撞上那个点上了,之前用ST用的比较多,所以没撞到问题,其实ST也有这个问题,只是代码有检查是否错误,ST的多try了几次就通信成功了,现在改了这个bug后通信速率明显上升了。

使用特权

评论回复
pq113_6|  楼主 | 2019-11-13 17:49 | 显示全部楼层
TechHolder 发表于 2019-11-13 17:19
使用你的代码做了一下测试,没有屏蔽while(!UART2->UARTn_LSR0.TC);代码前是会丢失数据,屏蔽后不会丢失 ...

是的,我之前也看到这个问题了,确实是在中断里面处理时间太久导致溢出了,奇怪的是明明有FIFO怎么还溢出。

使用特权

评论回复
JasonLee27| | 2019-11-13 18:52 | 显示全部楼层
pq113_6 发表于 2019-11-13 17:49
是的,我之前也看到这个问题了,确实是在中断里面处理时间太久导致溢出了,奇怪的是明明有FIFO怎么还溢出 ...

这个延时会积累的,所以即使有fifo,延时累积到一定程度后必然会造成溢出

使用特权

评论回复
pq113_6|  楼主 | 2019-11-14 16:31 | 显示全部楼层
本帖最后由 pq113_6 于 2019-11-14 16:34 编辑
JasonLee27 发表于 2019-11-13 18:52
这个延时会积累的,所以即使有fifo,延时累积到一定程度后必然会造成溢出 ...

看到问题点了,测试代码如附件 uart_basic.zip (3.3 KB)

使用特权

评论回复
JasonLee27| | 2019-11-15 18:54 | 显示全部楼层
pq113_6 发表于 2019-11-14 16:31
看到问题点了,测试代码如附件
测试方法是发送267字节,然后判断第一个字节为0xaa时就打开使能信息打印。
...
void uartDebugReceive(void)
{
    uint16_t i;
        uint16_t currentCount;
    if(debug == 0)
        return;
        currentCount = gTimerDelayCount;
    Printf("recv count:%x\n", count);
    Printf("count:%x\n", currentCount);
    for(i = 0; i < sizeof(g_recvedDataBuf); i++)
    {
        Printf("0x%x ", g_recvedDataBuf[i]);
    }
    Printf("\n\n");
    //debug = 0;
}


你这样改试试,这里使用的printf函数是实时打印的,按115200的速度计算,十几个字节就有1ms时间了

使用特权

评论回复
operating| | 2019-11-17 17:44 | 显示全部楼层
一般串口都是要自己开缓冲buffer的

使用特权

评论回复
pq113_6|  楼主 | 2019-11-18 10:24 | 显示全部楼层
operating 发表于 2019-11-17 17:44
一般串口都是要自己开缓冲buffer的

PC一次发送267个字节,串口开了267个字节的buffer。现在的问题是串口中断似乎一直占用CPU,不知道是不是进出串口中断时间太长了导致的问题。

使用特权

评论回复
gyxlizhong| | 2020-5-7 17:36 | 显示全部楼层
pq113_6 发表于 2019-11-18 10:24
PC一次发送267个字节,串口开了267个字节的buffer。现在的问题是串口中断似乎一直占用CPU,不知道是不是 ...

你可以在串口中断入口、出口各加一个GPIO置位、复位代码,用示波器观察时间就可判断。你原代码在串口接受中断里一直判断另一个串口的发送完成,当两个串口波特率一致时,将会因为PC串口和MCU串口速率微小差异的持续累积导致丢字节

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则