RS485 -- 在发送状态切换到接收状态多发送个0的解决办法

最近调试485的通讯的问题,在485由发送状态切换到接收状态时候多出一个字节的00的问题,查阅相关资料算是暂时解决,做一下笔记,也希望能帮到需要的童鞋。

大概现象就是这样的:

下面是以我这边的485的原理设计

使用的485的芯片为MAX3486,将485上的A和B信号转换为串口的TXD和RXD方式传送到控制芯片,就上面提到的问题大概分析为:

在485发送完成后,TX为高电平,485总线上A线电压 > B线电压;
将485从发送切换到接收,485接口芯片的促使A、B线为高阻态;
此时由于A、B线之间的匹配电阻120R,使A、B线的电压差减小到0;

那有可能有两种情况:

1、如果考虑总线上电感的因素,有可能导致B线的电压 > A线电压;
因此,这个时刻对于接收端来说,会出现一个0电平。

2、由于在转换为接收状态的的时候,A、B信号线转换为高阻状态,但是RS232在空闲时期TTL电平总为高电平状态,在485转换状态切换时候控制器端TTL变为低电平,满足了232的起始的条件。

由于在232的硬件里边,接收端RX脚上出现一个下降沿,满足232的起始位条件,可以认为是一个字节传输的开始。

所以就导致了接收端接收了一个“0”字节。
至于接收端认为启动了一个字节的传输,满足了起始条件,但是并不满足232传输的停止位;这个问题就不清楚了。
综上说明,简单的几个解决的方法为:

1、在串口的RXD信号线上接一个上拉电阻(我开始使用上拉电阻的阻值为6.8K,没有解决问题,换成4.7K的阻值,解决了);

2、在485的A、B线上,分别对地接一个小电容;

3、120R的匹配电阻,可以换成其他阻值,或者如果短距离的话可以不接匹配电阻;

  • 10
    点赞
  • 60
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
好的,关于基于stm32单片机写一个RS485通信的接收发送函数,可以提供以下代码供参考: RS485通信初始化代码: ``` void RS485_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO, ENABLE); //使能GPIO和AFIO复用功能时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); //使能USART时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //USART2_TX GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; //USART2_RX GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉输入 GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; //USART2_DE GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); USART_InitStructure.USART_BaudRate = 9600; //波特率为9600bps USART_InitStructure.USART_WordLength = USART_WordLength_8b; //8位数据位 USART_InitStructure.USART_StopBits = USART_StopBits_1; //1位停止位 USART_InitStructure.USART_Parity = USART_Parity_No; //无奇偶校验位 USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //无硬件流控制 USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //发送接收模式 USART_Init(USART2, &USART_InitStructure); //初始化USART2 USART_Cmd(USART2, ENABLE); //使能USART2 GPIO_SetBits(GPIOA, GPIO_Pin_4); //设置为发送状态 } ``` RS485通信发送函数: ``` void RS485_SendData(uint8_t* data, uint16_t len) { GPIO_SetBits(GPIOA, GPIO_Pin_4); //设置为发送状态 USART_SendData(USART2, *data++); //发送第一个字节 while(--len) { while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, *data++); //发送数据 } while(USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET); GPIO_ResetBits(GPIOA, GPIO_Pin_4); //设置为接收状态 } ``` RS485通信接收函数: ``` void RS485_ReceiveData(uint8_t* data, uint16_t* len) { if(USART_GetFlagStatus(USART2, USART_FLAG_RXNE) == SET) //有接收到数据 { *len = 0; //计数器清零 while(USART_GetFlagStatus(USART2, USART_FLAG_RXNE) == SET) { *data++ = USART_ReceiveData(USART2); //接收数据 (*len)++; //计数器累加 } } } ``` 注意事项: 1. 以上代码为STM32F103RC处理器的串口收发代码,只能供参考。 2. 在通信之前,需要设置RS485收发控制引脚为“发送状态”,否则会出现通信失败的情况。在发送数据完成之后,需要保持一定的时间,等待数据发送完成之后再将RS485控制引脚从“发送状态切换为“接收状态”,否则会出现数据错乱的情况。 3. 在接收数据时,需要使用一个计数器来进行字节数统计,以便后续的数据处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

青椒*^_^*凤爪爪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值