打印
[STC单片机]

STC8串口数据多了后漏发数据

[复制链接]
1610|27
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 梦在那 于 2024-9-9 17:11 编辑

在主程序里实现把接收到的数据再用串口发出去,每次数据格式基本固定,
内容多了后就会出现少发数据的情况,这是啥情况。晶振:22.1184MHz,波特率19200、38400、57600都试了,都会出现少发数据的情况图片是接收的是已经发出来的数据
        while (1)
        {
                delay_ms(5);
               
                if(COM1.RX_TimeOut > 0)                //超时计数
                {
                        if(--COM1.RX_TimeOut == 0)
                        {
                                P54=!P54;
                                PrintString1("No01:\r\n");
                                if(COM1.RX_Cnt > 0)
                                {
                                       
                                        for(i=0; i<COM1.RX_Cnt; i++)        
                                        TX1_write2buff(RX1_Buffer[i]);        //收到的数据原样返回
                                }
                                                                        
                                COM1.RX_Cnt = 0;
                        }
                }
        }
}


微信截图_20240909170459.png (142.27 KB )

串口收到的数据

串口收到的数据

使用特权

评论回复
评论
梦在那 2024-9-9 17:12 回复TA
最后这个 No01: 8 这里就少发了一次数据 8 

相关帖子

沙发
LcwSwust| | 2024-9-9 17:30 | 只看该作者
问题可能就在你没发出来的代码里,比如RX_cnt是不是8位的,看你的长度可能有200了,有没有防止溢出的处理?
buffer长度够不够?
发送数据有没有关闭接收中断?

使用特权

评论回复
板凳
梦在那|  楼主 | 2024-9-9 17:37 | 只看该作者
本帖最后由 梦在那 于 2024-9-9 17:43 编辑

在每字节数据发送后都加了个10us延时,目前测试了10分钟,少发情况大大减少。还得改,后续再观察观察
while (1)
        {
                delay_ms(5);
               
                if(COM1.RX_TimeOut > 0)                //超时计数
                {
                        if(--COM1.RX_TimeOut == 0)
                        {
                                P54=!P54;
                                PrintString1("No01:\r\n");
                                if(COM1.RX_Cnt > 0)
                                {
                                       
                                        for(i=0; i<COM1.RX_Cnt; i++)        
                                        TX1_write2buff(RX1_Buffer);        //收到的数据原样返回
                                        Delay10us();
                                }
                                                                        
                                COM1.RX_Cnt = 0;
                        }
                }
        }

使用特权

评论回复
评论
梦在那 2024-9-10 12:01 回复TA
@LcwSwust :现在测了快一个小时了,目前没问题。非常感谢 
LcwSwust 2024-9-10 11:14 回复TA
@梦在那 :ok 
梦在那 2024-9-10 11:12 回复TA
@LcwSwust :我又查看了下,我的buffer长度定义的就是188,我改成了255,现在用串口直连测试没有问题。我是单片机把接收的数据通过无线模块再发出去,电脑接收。我再用模块试试。感谢提醒 
梦在那 2024-9-10 09:21 回复TA
@LcwSwust :有效是有效,但还是有少发情况 
LcwSwust 2024-9-9 18:26 回复TA
看起来延时在for循环之外啊,确定有效? 
地板
梦在那|  楼主 | 2024-9-9 17:46 | 只看该作者
LcwSwust 发表于 2024-9-9 17:30
问题可能就在你没发出来的代码里,比如RX_cnt是不是8位的,看你的长度可能有200了,有没有防止溢出的处理?
buf ...

长度是184字节,RX_cnt是u8的,RX1_Buffer也是u8,u8定义的是unsigned char
typedef struct
{
        u8        id;                                //串口号

        u8        TX_read;                //发送读指针
        u8        TX_write;                //发送写指针
        u8        B_TX_busy;                //忙标志

        u8         RX_Cnt;                        //接收字节计数
        u8        RX_TimeOut;                //接收超时
        u8        B_RX_OK;                //接收块完成
} COMx_Define;

使用特权

评论回复
5
linxi6414| | 2024-9-9 17:54 | 只看该作者
不要怀疑芯片,如果这么低级的错误,芯片公司都会犯,他早倒闭了。

使用特权

评论回复
6
linxi6414| | 2024-9-9 17:58 | 只看该作者
你这个还只是串口,相对来说还要简单一些,前几天在调试STC32G12K64,调485收发,串口DMA发送,普通接收,也是遇到问题,调了一天多,才调好,最后发现还是自己的问题,之前做了很多的项目都是用的STC单片机,开始都以为是芯片的问题,最后发现全部是自己的问题,这些基础功能,他们是不会那么容易出现BUG的,出BUG的都是一些特殊场合的应用,数据手册中会有说明,如何避坑。

使用特权

评论回复
7
LcwSwust| | 2024-9-9 18:28 | 只看该作者
梦在那 发表于 2024-9-9 17:46
长度是184字节,RX_cnt是u8的,RX1_Buffer也是u8,u8定义的是unsigned char

buffer空间有多大?接收数据往里写有没有防溢出?
两组数据一起来它能正确处理不?

使用特权

评论回复
8
linxi6414| | 2024-9-9 18:40 | 只看该作者
给你一个参考,串口接收数据的时候,一定要等一帧数据接收完了再去读取,不然会出错。

使用特权

评论回复
9
linxi6414| | 2024-9-9 19:00 | 只看该作者
最近正在调试的板子,4路485,1路CAN,4路485有3种波特率,四路串口全部都需要同时工作,一样工作的很稳定,用的STC32G12K64.

使用特权

评论回复
10
coody| | 2024-9-9 22:03 | 只看该作者
串口有线通信,基本也没有干扰,你还是主动发送,怎么可能会漏?仔细检查程序吧。

使用特权

评论回复
11
丙丁先生| | 2024-9-10 04:58 | 只看该作者

使用特权

评论回复
12
xionghaoyun| | 2024-9-10 08:17 | 只看该作者
是不是中断打断了

使用特权

评论回复
13
WoodData| | 2024-9-10 09:22 | 只看该作者
转发的时候要禁止接收,转发完才能继续接收。
还有你最好接收一帧完成置个标志,循环查询标志后转发。
像你上面写的就是延时一段时间,查到有收到数据就转发,都没有确定是不是一整帧数据,可能没接收到整帧数据就转发了

使用特权

评论回复
14
梦在那|  楼主 | 2024-9-10 09:22 | 只看该作者
linxi6414 发表于 2024-9-9 17:58
你这个还只是串口,相对来说还要简单一些,前几天在调试STC32G12K64,调485收发,串口DMA发送,普通接收, ...

是的,肯定还是自己程序有问题,没怀疑过芯片的问题

使用特权

评论回复
15
梦在那|  楼主 | 2024-9-10 11:14 | 只看该作者
WoodData 发表于 2024-9-10 09:22
转发的时候要禁止接收,转发完才能继续接收。
还有你最好接收一帧完成置个标志,循环查询标志后转发。
像你 ...

在串口程序中有中断完成标志位的
void UART1_int (void) interrupt UART1_VECTOR
{
        if(RI)
        {
                RI = 0;
                if(COM1.B_RX_OK == 0)
                {
                        if(COM1.RX_Cnt >= COM_RX1_Lenth)        COM1.RX_Cnt = 0;
                        RX1_Buffer[COM1.RX_Cnt++] = SBUF;
                        COM1.RX_TimeOut = TimeOutSet1;
                }
        }

        if(TI)
        {
                TI = 0;
                if(COM1.TX_read != COM1.TX_write)
                {
                         SBUF = TX1_Buffer[COM1.TX_read];
                        if(++COM1.TX_read >= COM_TX1_Lenth)                COM1.TX_read = 0;
                }
                else        COM1.B_TX_busy = 0;
        }
}

使用特权

评论回复
评论
梦在那 2024-9-12 16:16 回复TA
@LcwSwust :好的,我试试看 
LcwSwust 2024-9-10 13:37 回复TA
原来问题在这:if(COM1.RX_Cnt >= COM_RX1_Lenth) COM1.RX_Cnt = 0; 好不容易收到的数据干嘛要清零,建议用这种方式: d=sbuf; if(n<len)buf[n++]=d; 
16
梦在那|  楼主 | 2024-9-10 12:03 | 只看该作者
linxi6414 发表于 2024-9-9 19:00
最近正在调试的板子,4路485,1路CAN,4路485有3种波特率,四路串口全部都需要同时工作,一样工作的很稳定 ...

板子画的很规整,学习了

使用特权

评论回复
17
linxi6414| | 2024-9-10 12:36 | 只看该作者
梦在那 发表于 2024-9-10 12:03
板子画的很规整,学习了

一直感觉自己画的板不好,跟个垃圾似的,这个只是一个首版的测试板,根据测试需求,后面再修改。

使用特权

评论回复
18
dami| | 2024-9-11 08:46 | 只看该作者
发完一个才能再发。时间间隔要能够,与波特率有关。

使用特权

评论回复
19
kissdb| | 2024-9-11 21:16 | 只看该作者
最好用环形缓冲区接收发送

使用特权

评论回复
20
cooldog123pp| | 2024-9-12 10:57 | 只看该作者
感觉是不是发的频率太快,如果你的数据量大你的波特率要高一些,而且要发完一个再发下一个,不能被中断。

使用特权

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

本版积分规则

37

主题

234

帖子

2

粉丝