OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4931|回复: 8

sp3485芯片+485通信CRC最后一位总是FF

[复制链接]

3

主题

16

帖子

0

精华

初级会员

Rank: 2

积分
61
金钱
61
注册时间
2018-7-9
在线时间
15 小时
发表于 2022-5-9 15:32:52 | 显示全部楼层 |阅读模式
本帖最后由 bb2511 于 2022-5-9 15:47 编辑

按照这个电路在STM32F103上,module bus 协议,485读数的时候,CRC最后一位总是FF,用TTL读串口数据CRC校验正常。请教各位大圣,可能是什么问题。
QQ图片20220509153004.png
QQ图片20220509152707.png
QQ图片20220509154542.png
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

12

主题

3344

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
8464
金钱
8464
注册时间
2020-5-11
在线时间
3904 小时
发表于 2022-5-10 14:44:34 | 显示全部楼层
bb2511 发表于 2022-5-10 14:40
void USART_SendChar(USART_TypeDef* USARTx,char data)
{
        SP3485_DE_H;

TC标志了解一下
傲游截图20220510144255.jpg

傲游截图20220510144336.jpg
专治疑难杂症
回复 支持 1 反对 0

使用道具 举报

3

主题

16

帖子

0

精华

初级会员

Rank: 2

积分
61
金钱
61
注册时间
2018-7-9
在线时间
15 小时
 楼主| 发表于 2022-5-9 15:35:42 | 显示全部楼层
上/下拉电阻改到3.3K ,去掉120欧姆电阻,RX上拉都是一样,CRC的最后一位是FF
回复 支持 反对

使用道具 举报

3

主题

16

帖子

0

精华

初级会员

Rank: 2

积分
61
金钱
61
注册时间
2018-7-9
在线时间
15 小时
 楼主| 发表于 2022-5-9 15:48:38 | 显示全部楼层
第一幅串口输出是通过SP3485读出来的,CRC最后一位FF,第二幅图是通过TTL读出的,CRC正常
回复 支持 反对

使用道具 举报

2

主题

130

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1870
金钱
1870
注册时间
2011-9-16
在线时间
419 小时
发表于 2022-5-9 21:35:28 | 显示全部楼层
网上的module bus RTU 协议有个问题,由于485芯片发送和接收状态切换太快导致的,在没有完成最后字节发送时切换到了接收状态。
在mbrtu.c 中
找到
BOOL
xMBRTUTransmitFSM( void )
其中,根据波特率选择增加一点延时
    case STATE_TX_XMIT:
        /* check if we are finished. */
        if( usSndBufferCount != 0 )
        {
            xMBPortSerialPutByte( ( CHAR )*pucSndBufferCur );
            pucSndBufferCur++;  /* next byte in sendbuffer. */
            usSndBufferCount--;
                                          if(usSndBufferCount==0)
                                                {
                                                        switch(boundrate)           
                                                        {
                                                                case 115200:
                                                                     delay_us(160);
                                                                           break;
                                                                case 9600:
                                                                                 delay_us(2000);
                                                                           break;
                                                                case 38400:
                                                                                 delay_us(600);
                                                                           break;
                                                                default:
                                                                                 delay_us(2000);
                                                                           break;
                                                        }
                                                }
        }
        else
        {
                                          
            xNeedPoll = xMBPortEventPost( EV_FRAME_SENT );
            /* Disable transmitter. This prevents another transmit buffer
             * empty interrupt. */
                                       
            vMBPortSerialEnable( TRUE, FALSE );   //因为一旦usSndBufferCount == 0,不管最后字节有没发送出去,就被切换为接收状态了,然后总线高电平,最后字节CRC就是0XFF
            eSndState = STATE_TX_IDLE;
        }
        break;
根据波特率调整合适的延时,可以避免上述现象,这也是本人在实际移植中发现并找到的解决方法。
回复 支持 反对

使用道具 举报

0

主题

668

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1926
金钱
1926
注册时间
2021-8-13
在线时间
262 小时
发表于 2022-5-10 09:54:27 | 显示全部楼层
帮顶一下   
回复 支持 反对

使用道具 举报

12

主题

3344

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
8464
金钱
8464
注册时间
2020-5-11
在线时间
3904 小时
发表于 2022-5-10 10:26:53 | 显示全部楼层
DIR-U1在数据还没发完时就设置为接收状态了。
发送函数没有等待发送完成标志。
专治疑难杂症
回复 支持 反对

使用道具 举报

3

主题

16

帖子

0

精华

初级会员

Rank: 2

积分
61
金钱
61
注册时间
2018-7-9
在线时间
15 小时
 楼主| 发表于 2022-5-10 14:40:06 | 显示全部楼层
LcwSwust 发表于 2022-5-10 10:26
DIR-U1在数据还没发完时就设置为接收状态了。
发送函数没有等待发送完成标志。

void USART_SendChar(USART_TypeDef* USARTx,char data)
{
        SP3485_DE_H;
//        delay_ms(1);
        USART_SendData(USART1, data);
        while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
        USART_ClearITPendingBit(USART1,USART_IT_RXNE);
        SP3485_DE_L;
//        delay_ms(1);
}

#define USART_FLAG_TXE                       ((uint16_t)0x0080)

有没有更好的建议怎么修改

回复 支持 反对

使用道具 举报

3

主题

16

帖子

0

精华

初级会员

Rank: 2

积分
61
金钱
61
注册时间
2018-7-9
在线时间
15 小时
 楼主| 发表于 2022-5-10 20:14:32 | 显示全部楼层

非常感谢,问题解决了
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-27 07:20

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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