找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2949|回复: 6
打印 上一主题 下一主题
收起左侧

STC15单片机rs485数据收发切换,数据有丢失和乱码的问题,求指教

[复制链接]
跳转到指定楼层
楼主
ID:911776 发表于 2021-6-29 16:17 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
STC15单片机 485数据收发切换,数据有丢失和乱码的问题, 求指教

波特率9600, 每隔150ms发送8字节,每隔100ms收取10字节

1. 485串口数据进行发送和接收,是通过中断来实现的;
2. 一定的频度下,单单发送,单单接收都是正常的;
3. 当收发频繁切换进行通讯的时候,尤其是收发的时差在60-70ms上下的时候,会出现数据有丢失和数据混乱的现象。而且这种频度越高越容易出现。

尝试过在收发切换的时候,延时,但是输出数据的情况看,并没有多大的效果
求大神指点!

附相关代码:
void Send1StrWithLen(uchar *s, uchar len)
{
    if(len <= 0)
    {
        return;
    }

    if(Send.busy)
    {
        return;
    }
   
    if(Recv.busy)
    {
        return;
    }

    T485();
    //Delay5ms();   
    Send.strLen = len;
    Send.pStr = s;
    SBUF = *(Send.pStr);
    Send.busy = 1;
    Send.cnt = 0;
}


void Uart1ISR() interrupt 4
{

    if (RI)
    {
        RI = 0;                 //清除RI位
                Recv.dat = SBUF;
                RecCmd[Recv.cnt] = Recv.dat;
                if(Recv.cnt == 0)
                {
                    Recv.busy = 1;
                }
                Recv.cnt++;
                if(Recv.cnt >= CMD_LEN)
                {
                    Recv.cnt = 0;
                    Recv.busy = 0;
                    Recv.endFlag = 1;
                    //T485();  //加上接收数据不能正常进行
                }
}


    if (TI)
    {
        TI = 0;                 //清除TI位
                Send.cnt++;
              if(Send.cnt >= Send.strLen)
                {
                    //Delay40ms();
                    R485();
                    Send.busy = 0;               //清忙标志
                    return;
                }
                SBUF =  *(Send.pStr + Send.cnt);
    }
}
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:123289 发表于 2021-6-30 17:43 | 只看该作者
串口串来数据是连续的,它不等人!如果你不及时取走,就丢数据了!!!
教你一下如何发送吧:
1、开辟一个发送缓冲区A,用于存放需要发送的数据,例如:发送缓冲区大小=256个字节,则可以放置送256个字符。采循环放置,无需擦除,循环时覆盖。如果能及时发送,则数据量无限!
2、建立两个指针:PCW(写入指针)、PCR(取走指针)它俩同时指向A区的数据位置。初始PCW=PCR=0,同时指向A区首字节。PCW、PCR最大=255(指向最后一个字节),再多即=256时,就归0(循环计数)。
3、当你需要发送一组字符时(如"ABCDEFG"),就将"ABCDEFG" 依序写入A区PCW所指的地方,且每写一个,将PCW+1。注意:这时仅仅是写入A区并未真正的发送!PCW=256时要归0!
4、发送:当PCR<>PCW时,就从A区中取出一个PCR指向的字节发送出去,发完后,将PCR+1。
提示:这段程序可以写在发送中断程序中,每次发送中断只发一个数据。下次中断再发下一个,不等待。
这样做的好处是:
A、发送时不需考虑系统忙不忙,因为你只向A区写数据,不存在忙不忙。
B、只要PCW改变就可能引起PCR<>PCW,也就起动了发送。
C、串口发送是中断一次发一个字节,也不需检验系统忙不忙,只要PCR<>PCW就发一个,发了一个字节就退出。不需要发送等待,节省的CPU的时间,所以永远不会影响接收数据,也就丢不掉接收的数据了。
5、第一个字节数据:发送中断只发生于数据发送之后,那么第一个字节在发送之前是不会有发送中断发生的!那么第一个字节需要如何发送呢?这里留个悬案,让楼上自己解决。
以上也是我用于实战的方案,从未丢过任何一个数据。原因就是收、发数据时间最短,没有等待。

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

板凳
ID:911776 发表于 2021-7-1 12:58 | 只看该作者
https://www.chinafix.com/thread-137012-1-1.html
收藏今天看到的一个神贴
回复

使用道具 举报

地板
ID:226055 发表于 2021-7-2 17:45 | 只看该作者
    可以考虑下硬件上面检查下,比如把RS485收发芯片换成MAX系列的。
回复

使用道具 举报

5#
ID:883242 发表于 2021-7-2 21:29 | 只看该作者
485不把协议定清楚,很难在一条线上做到收发不冲突,你的协议都没弄好就开始撸代码了。
回复

使用道具 举报

6#
ID:911776 发表于 2021-7-3 15:10 | 只看该作者
本帖最后由 yhy08090 于 2021-7-3 15:31 编辑
cocolala 发表于 2021-7-2 17:45
可以考虑下硬件上面检查下,比如把RS485收发芯片换成MAX系列的。
单单收,单单发都是OK的,会是硬件的问题?
我们的收发芯片是SP3485
回复

使用道具 举报

7#
ID:911776 发表于 2021-7-3 15:21 | 只看该作者
本帖最后由 yhy08090 于 2021-7-3 16:44 编辑
Hephaestus 发表于 2021-7-2 21:29
485不把协议定清楚,很难在一条线上做到收发不冲突,你的协议都没弄好就开始撸代码了。

是类似MOBUS的软件层协议?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表