搜索
bottom↓
回复: 23

为什么MAX3485发送数据时丢失最后一位,求高人指点。

[复制链接]

出0入0汤圆

发表于 2011-12-22 18:55:09 | 显示全部楼层 |阅读模式
我用stm32串口0接了max3485作485通讯,发送字符串时最后一位总是丢失。
    刚才试了发不了图片,我的电路是把max3485的DE和/RE连在一起用一个IO控制的,程序如下:
    void Uart1_Send_Char(u8 ch)
{
        delay_us(1);
        RS485=1;       

        USART1->DR = ch;

        while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET)
    {
    }

        RS485=0;
        delay_us(1);
}

void Uart1_Send_String(u8 *str)          
{
        while(*str != '\0')
        {
            Uart1_Send_Char(*str);
            ++str;
        }
}

第一次用485通讯,还请高手指点。

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

发表于 2011-12-22 19:16:04 | 显示全部楼层
stm32没用过,不知道有没有fifo,如果有的话原因就是数据还没有真正发送到总线上收发控制端就切换到接收状态了,可以试着在接收控制前增加延时时间来验证原因。

出0入0汤圆

发表于 2011-12-22 19:17:44 | 显示全部楼层
为什么不用示波器看一下?

出0入0汤圆

发表于 2011-12-22 19:41:56 | 显示全部楼层
++str;
为什么不用str++呢?

出0入0汤圆

发表于 2011-12-22 19:47:01 | 显示全部楼层
回复【3楼】dzymushi dzymushi
   ++str;  
为什么不用str++呢?
-----------------------------------------------------------------------

一样的。问题不在这里。

出0入0汤圆

发表于 2011-12-22 19:51:25 | 显示全部楼层
delay_us(1);
RS485=1;              //把这句话提到delay_us(1); 上面


USART1->DR = ch;

while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET)
    {
    }

RS485=0;       //把这句话放到delay_us(1); 下面
delay_us(1);
}
我不信还不行

出0入0汤圆

发表于 2011-12-22 19:55:35 | 显示全部楼层
发送完最后一位,延时一段时间再置RS485=0;

出0入0汤圆

发表于 2011-12-22 20:17:11 | 显示全部楼层
报文末尾空发2个字符就可以解决,我用的1487就是这样办的

出0入0汤圆

发表于 2011-12-22 21:29:36 | 显示全部楼层
楼上各位你们就别误导楼主了。
问题原因就是数据还在缓冲区中未发送完毕就把485芯片置成接收状态了。
那么怎么判断数据是否发送完毕呢?难道UART状态寄存器中的那些标志位都是吃白饭的啊。
加延时或许能解决问题,但是1.延时过短,问题不能解决,2.延时过长,浪费CPU时间。3.延时正好:那是不可能的。
如果不想while循环判断标志位等待,可以开启发送完毕中断。

出0入0汤圆

发表于 2011-12-22 21:35:52 | 显示全部楼层
发送字符串时,没有必要每个字符都控制DE/RE。

void Uart1_Send_Char(u8 ch)
{

USART1->DR = ch;

while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET)
    {
    }


}

void Uart1_Send_String(u8 *str)   
{
RS485=1;
delay_us(10);
while(*str != '\0')
{
    Uart1_Send_Char(*str);
    ++str;
}
delay_us(10);
RS485=0;
}

要发送单个字符,用下面的函数:
void Uart1_Send_SingleChar(u8 ch)
{
RS485=1;
delay_us(10);
USART1->DR = ch;

while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET)
    {
    }
delay_us(10);
RS485=0;
}

编辑原因:
补充
利用发送完成中断作为切换DE/RE的依据也一样会有丢字符的问题,延时才是最简单有效的办法

出0入0汤圆

 楼主| 发表于 2011-12-22 21:44:41 | 显示全部楼层
回5楼:延时位置前后都没用。

回7楼:我目前就是这样处理的,在发送最后一位加一个空格字符就好了,不够感觉这样不好。

回8楼:你说的有道理,正是数据还没发送完成就设置为接受状态了,不过你说用中断我觉得还是麻烦了点,我觉得还是在字符串尾部加上一个空字符简单些,不知还有什么简单点的处理方法,呵呵。

出0入0汤圆

发表于 2011-12-22 21:49:19 | 显示全部楼层
你把while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET) 改成
while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET) 试试

出0入0汤圆

发表于 2011-12-22 22:13:10 | 显示全部楼层
485发送后要延时,8楼说的很正确,看你采取哪种方式了

出0入0汤圆

发表于 2011-12-22 22:19:54 | 显示全部楼层
回复【8楼】lcofjp 卡尔夫
楼上各位你们就别误导楼主了。
问题原因就是数据还在缓冲区中未发送完毕就把485芯片置成接收状态了。
那么怎么判断数据是否发送完毕呢?难道uart状态寄存器中的那些标志位都是吃白饭的啊。
加延时或许能解决问题,但是1.延时过短,问题不能解决,2.延时过长,浪费cpu时间。3.延时正好:那是不可能的。
如果不想while循环判断标志位等待,可以开启发送完毕中断。
-----------------------------------------------------------------------

那只是表示串口的发送完成了,和485芯片发送完成有必然关系吗?
我也很确定是延时的问题
他每次都置一次RS485=0,是不是1US的时间不足以切换收发状态
延时肯定是有效的,只是要根据芯片确定一下到底花多长的延时

出0入0汤圆

发表于 2011-12-22 22:31:22 | 显示全部楼层
尾巴再多发一个字节没用的数据,确实是485收发切换问题

出0入0汤圆

发表于 2011-12-22 22:34:50 | 显示全部楼层
回复【13楼】dzymushi  dzymushi
-----------------------------------------------------------------------

485芯片是纯硬件,基本不存在延时,有也是pS,nS级别的,基本可以忽略。
程序这样写没什么大问题。

出0入0汤圆

发表于 2011-12-22 22:58:43 | 显示全部楼层
看别人总结的3点:

1 485半双工收发时必须延时,以保证系统的稳定性、可靠性

2 总线上不间断(长时间连续)的发送数据会产生累积误差(不同晶振频率的误差)。所以用延时(暂停通信一段时间)来消除波特率的误差,避免数据错误
3 485器件在收、发状态转换时,需要转换时间来过渡到稳定状态

如果纯硬件延迟是PS的话,最起码上M的速率是可以的,可一般的连115200还都不稳定,所以要对国产485有很大的包容心

出0入0汤圆

 楼主| 发表于 2011-12-23 08:49:32 | 显示全部楼层
多谢各位指点,我现在加延时好了。

16楼说的有道理,我昨天没加延时,用115200的波特率不停的发送数据,在字符串末尾加一个空字符,一开始还好,后来就丢数据了,看来还是要加延时啊,等会再测试一下长时间发数据怎么样。

出0入0汤圆

发表于 2011-12-23 10:29:02 | 显示全部楼层
之前我们也遇到类似的问题,不过是头两个字节错误。

后来换了485的IC,就完全ok了。

出0入0汤圆

发表于 2012-7-6 11:53:08 | 显示全部楼层
你们MAX3485的芯片哪里买的,能否告诉我一个联络方式,我用FPGA向3485发数据,老是丢最后一个字节,加了一些延时,貌似也是不管用,

出0入0汤圆

发表于 2012-7-6 12:31:31 | 显示全部楼层
要用TC信号,不是TXE

出0入0汤圆

发表于 2013-6-1 08:30:42 来自手机 | 显示全部楼层
Mark…
来自:amoBBS 阿莫电子论坛 Windows Phone 7 客户端

出0入0汤圆

发表于 2014-3-6 22:16:13 | 显示全部楼层
这个问题当初折腾了我好久,现在偶尔还有丢包的问题。

出0入0汤圆

发表于 2015-2-1 13:59:55 | 显示全部楼层
应该是发送控制端关闭提前了,在一个是接收端问题;可能性最大的是软件问题
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-6-7 13:01

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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