tianyaxtutianya 发表于 2013-5-18 15:45:21

STM32控制SP3485,发现总是丢数据,谁知道这是怎么回事

STM32控制SP3485,发现总是丢数据,谁知道这是怎么回事!用一个STM32控制一个SP3485发送数据,一个STM32控制SP3485接收数据,都加入控制信号!发现发送5个字节的数据,只有前面3个字节的数据被正常收到,其他数据莫名其妙的不见了!谁知道是怎么回事啊?
还有一个问题就是两个3485通信的话,是A脚连A脚,B脚连B脚嘛;还是应该反过来连?

stely 发表于 2013-5-18 16:11:49

A对A,B对B。好好检查程序吧。SP3485用过很多,直接周力功拿的片子,没碰到出问题的。

tianyaxtutianya 发表于 2013-5-18 16:17:00

stely 发表于 2013-5-18 16:11 static/image/common/back.gif
A对A,B对B。好好检查程序吧。SP3485用过很多,直接周力功拿的片子,没碰到出问题的。 ...

我是做了一个RS232和SP3485的硬件电路,可以通过跳线来选择是通过RS232还是选择SP4385来通信    RS232已经测试通过了,用原来的程序来跑SP485加入了控制引脚的代码,但是发现会出现丢数据的现象?要是程序有问题,那么RS232应该测试也通不过!
    485和232的区别就是多了一个控制引脚对吧,另外就是485我选用的是半双工方式,而232是全双工方式

jiaowoxiaolu 发表于 2013-5-18 16:30:59

你的收发控制引脚切换加点延时, 数据没发完就已经切换了就丢数据

jssd 发表于 2013-5-18 16:41:46

用示波器看看出来的数据对不对。

tianyaxtutianya 发表于 2013-5-18 16:42:40

jiaowoxiaolu 发表于 2013-5-18 16:30 static/image/common/back.gif
你的收发控制引脚切换加点延时, 数据没发完就已经切换了就丢数据

我采用的是DMA发送方式,一般是等DMA发送中断产生的时候我才会把发送状态切换到接收状态,莫非在STM32这边认为发送完成了,但是到SP3485的时候硬件上发送还存在一点延时对吧

jiaowoxiaolu 发表于 2013-5-18 17:06:44

dma发送中断后实际上usart里面的数据还没完全送出去,你有两种处理方法,一个是dma中断后加延时再处理收发引脚,另外一个是dma中断后开启uart发送完成中断,然后在uart发送完成中断里面处理收发控制引脚,这是实际项目实践出来的经验

推荐第2种方法,非常好用

tianyaxtutianya 发表于 2013-5-18 17:14:49

jiaowoxiaolu 发表于 2013-5-18 17:06 static/image/common/back.gif
dma发送中断后实际上usart里面的数据还没完全送出去,你有两种处理方法,一个是dma中断后加延时再处理收发 ...

这点到确实是我没想到的,现在就是发现每次都固定丢了两个字节,估计是这个问题造成的!这样的话得牺牲主程序时间来确保数据的发送完成!

R_Development 发表于 2013-5-18 17:22:12

tianyaxtutianya 发表于 2013-5-18 17:14 static/image/common/back.gif
这点到确实是我没想到的,现在就是发现每次都固定丢了两个字节,估计是这个问题造成的!这样的话得牺牲主 ...

所以的芯片都有这个时间差,你不牺牲都不行

tianyaxtutianya 发表于 2013-5-18 17:32:54

R_Development 发表于 2013-5-18 17:22 static/image/common/back.gif
所以的芯片都有这个时间差,你不牺牲都不行

因为系统整个工作在一个对时间要求比较高的状态,所以整个程序都没有用延时函数,一旦加入延时就对整个系统的稳定性和及时响应都构成很大威胁,真是头痛啊

LZDZ 发表于 2013-5-18 17:36:34

tianyaxtutianya 发表于 2013-5-18 17:32 static/image/common/back.gif
因为系统整个工作在一个对时间要求比较高的状态,所以整个程序都没有用延时函数,一旦加入延时就对整个系 ...

电路改成自动切换的那种,发送完成,485引脚自动切换状态。

tianyaxtutianya 发表于 2013-5-18 17:45:46

LZDZ 发表于 2013-5-18 17:36 static/image/common/back.gif
电路改成自动切换的那种,发送完成,485引脚自动切换状态。

怎么做到自己切换   楼上的能否贴个电路上来看看!

LZDZ 发表于 2013-5-18 18:56:44

tianyaxtutianya 发表于 2013-5-18 17:45 static/image/common/back.gif
怎么做到自己切换   楼上的能否贴个电路上来看看!

我用上网本上网的目前,没有图现在,不过论坛里有,或者百度下都能找到。关键字:485自动切换

why800 发表于 2013-5-18 19:29:03

jiaowoxiaolu 发表于 2013-5-18 17:06 static/image/common/back.gif
dma发送中断后实际上usart里面的数据还没完全送出去,你有两种处理方法,一个是dma中断后加延时再处理收发 ...

+1

楼主按这位仁兄的方法改吧。很好用,就是还要注意开串口发送完成中断前,要清除这个中断。否则还是丢2个字节。ST有官方例子,但官方例子就是没清除中断,造成还是丢两个。

付上官方例子。需要在开串口TC中断前清除TC。保你成功。我刚做完。





tianyaxtutianya 发表于 2013-5-20 16:19:11

why800 发表于 2013-5-18 19:29 static/image/common/back.gif
+1

楼主按这位仁兄的方法改吧。很好用,就是还要注意开串口发送完成中断前,要清除这个中断。否则还是丢 ...

感谢楼上提供的资料,现在已经测试通过了,现在把测试通过的中断函数部分代码贴出来,我用的是串口3,写的不好的地方欢迎大家拍砖

/*******************************************************************************
**函数名称:void USART3_IRQHandler(void)
**函数功能:串口3发送中断
**输入参数:无
**返回值:无
*******************************************************************************/
void USART3_IRQHandler(void)
{
        if(USART_GetITStatus(USART3, USART_IT_TC) != RESET)          //串口发送中断
        {        
          
               USART_ITConfig(USART3, USART_IT_TC, DISABLE);          //禁止发送中断
               
               /* Clear USART3 TC pending bit */
                                 USART_ClearFlag(USART3, USART_FLAG_TC);

               //USART_ClearITPendingBit(USART3, USART_IT_TC);    //清除发送中断标志位
               
               SP485_RXD_ENABLE;       //当发送完成后,控制485接收使能
                  
               /*
                                 *当启动DMA发送结束,将g_ucDmaSendUsart3_Flag置为使能,表明可以再次启动数据发送
                    */
                          g_ucDmaSendUsart3_Flag = DMA_SNED_ENANBLE_FLAG;
        }
               
}


/**********************************************************************************
**函数名称:void DMA1_Channel2_IRQHandler(void)
**函数功能:串口3 DMA方式发送中断
**输入参数:无
**返回参数:无
**函数调用:中断函数
**********************************************************************************/
void DMA1_Channel2_IRQHandler(void)
{
   
   if(DMA_GetITStatus(DMA1_IT_TC2) != RESET)   //DMA通道2传输完成,即发送数据完毕
   {
          DMA_ClearFlag(DMA1_FLAG_TC2);              //清除标志位
             
          DMA_Cmd(DMA1_Channel2,DISABLE);      //关闭DMA
          
          /*
         *当启动DMA发送结束,将g_ucDmaSendUsart3_Flag置为使能,表明可以再次启动数据发送
             */
          //g_ucDmaSendUsart3_Flag = DMA_SNED_ENANBLE_FLAG;
          
          //Delay_ms(2);            //延时2MS,确保数据完全发送.
                //SP485_RXD_ENABLE;       //当发送完成后,控制485接收使能

                USART_ClearFlag(USART3, USART_FLAG_TC);            //这个地方需要特别注意,STM32官方给出的例子中没有这一句,不加的话容易造成数据丢失

                //USART_ClearITPendingBit(USART3, USART_IT_TC);    //清除发送中断标志位

                USART_ITConfig(USART3, USART_IT_TC, ENABLE);   //使能发送中断
                                                   
   }
   
   DMA_ClearITPendingBit(DMA1_IT_TC2);              //清除DMA通道2传输完成标志位
}


tianyaxtutianya 发表于 2013-5-20 17:13:08

LZDZ 发表于 2013-5-18 18:56 static/image/common/back.gif
我用上网本上网的目前,没有图现在,不过论坛里有,或者百度下都能找到。关键字:485自动切换 ...

感谢楼上的意见,我去找找看   如果你那边有这块的测试通过的电路,方便的话到时候传一份上来看看

云贵3314 发表于 2024-5-12 20:44:45

楼主的这个好使,,,也遇到这个问题了,,,DMA中断都产生了,结果时序还没走完,,最后的字节都有收不到的,这是芯片的BUG吧

陆小凤之北京 发表于 2024-5-13 10:59:32

和芯片完全没关系,这芯片工业上用的很多了。就是你的通讯时序,先把发送中断都去掉,把时序关系搞清楚。

发送多少字节,实际会用多少时间,测试一下就知道了。收发器会花费些时间,485隔离之类的也会花费时间。

16312610 发表于 2024-5-13 11:23:50

jiaowoxiaolu 发表于 2013-5-18 17:06
dma发送中断后实际上usart里面的数据还没完全送出去,你有两种处理方法,一个是dma中断后加延时再处理收发 ...
(引用自7楼)

我也碰到这个问题,用自收发模块没有点事,加了控制脚就出问题了

16312610 发表于 2024-5-13 11:25:12

tianyaxtutianya 发表于 2013-5-18 17:45
怎么做到自己切换   楼上的能否贴个电路上来看看!
(引用自12楼)

有自动收发模块买TD301M485

jianfengxixi 发表于 2024-5-13 12:35:55

直接使能硬件控制就好了
页: [1]
查看完整版本: STM32控制SP3485,发现总是丢数据,谁知道这是怎么回事