嵌入式开发--RS-485通讯的问题

RS-485说明

RS-485一般简称485总线,是最常用的工业总线之一,一般采用2线的半双工模式,用差分方式收发信息。最高速度可达10M BPS。

接口芯片

单片机使用485总线时,是用UART或USART接口,通过RS-485收发器完成信号的输入和输出。常用的芯片有MAX485,MAX3485,SP3485等等。

硬件连接

在这里插入图片描述
硬件很简单,RO和DI连接到单片机的UART接口,是数据的收发引脚,RE和DE连通,接到单片机的GPIO,以控制数据流的方向,是输入还是输出。

CubeMX设置

CubeMX教程见这里:嵌入式开发–CubeMX使用入门教程
在这里插入图片描述
连接到UART2,具体设置如下:
在这里插入图片描述
这些参数需要根据你的设置要求进行,异步模式,波特率,位数,奇偶校验,停止位,其他默认即可。开启中断,以方便接收数据。
在这里插入图片描述
UART对波特率要求并不高,误差5%以内即可,所以晶振可以用片内的RC振荡器,当然更建议用外部石英晶振,频率更准,更重要的是可靠性高。

代码编写

引脚定义

#define MAX485_OUT()      HAL_GPIO_WritePin(CTL_485_PORT,CTL_485_PIN, GPIO_PIN_SET)
#define MAX485_IN()       HAL_GPIO_WritePin(CTL_485_PORT,CTL_485_PIN, GPIO_PIN_RESET)

使能串口

  HAL_UART_Receive_IT(&huart2, uart2_state_typedef.data, 1);	//开启串口,接收到的数据放到uart2_state_typedef.data,每次接收1个字节
  __HAL_UART_ENABLE_IT(&huart2, UART_IT_RXNE);	//启动RXNE中断
  __HAL_UART_ENABLE_IT(&huart2, UART_IT_IDLE);	//启动IDLE中断

RXNE中断是用来接收数据, 每次接收1个字节,并且在中断中再次开启这个中断
IDLE是用来做帧结束判断的,485每帧8个字节,总线空闲后会产生一个IDLE中断,进了这个中断,就表示一帧结束。

中断函数

void USART2_IRQHandler(void)
{
  /* USER CODE BEGIN USART2_IRQn 0 */

  /* USER CODE END USART2_IRQn 0 */
  HAL_UART_IRQHandler(&huart2);
  /* USER CODE BEGIN USART2_IRQn 1 */
  //RS485接口
  //收到1个字节的数据
  if(__HAL_UART_GET_FLAG(&huart2, UART_FLAG_RXNE))
  {
    __HAL_UART_ENABLE_IT(&huart2, UART_IT_RXNE);	//启动RXNE中断
    uart2_state_typedef.data[uart2_state_typedef.len] = huart2.Instance->RDR;
    uart2_state_typedef.len++;
  }
  
  //总线空闲时,会发生一次IDLE中断,此时意味着数据接收完成
  //不同的内核,清除IDLEIE的方式不同,请查阅手册
  if(__HAL_UART_GET_FLAG(&huart2, UART_FLAG_IDLE))
  {
    huart2.Instance->ICR |= USART_ICR_IDLECF;	 //向USART_CR1的IDLECF位写1,以清除IDLEIF标志,否则会一直进IDLEIE中断
  }

发送数据

void modbus_send(void)  //发送数据到串口,数据需要事先在modbus_send_array中准备好
 {
  MAX485_OUT();		//转换为输出模式
  delay_us(100); 	//延时,以等待接口芯片切换完成
  HAL_UART_Transmit(MODBUS_PORT, modbus_send_array,8, 100);   //从串口2发送数组命令
  MAX485_IN();  	//转换为输入模式
  delay_us(10);
}

接收数据

u8 modbus_receive(u16 timeout)        //发送指令后,读取伺服回传的数据,超时单位为ms
{
  u8 ret = 255;
  u8 i = 0;

  while(1)
  { 
    HAL_Delay(1);
    i++;
    
    if(i>timeout)
      break;
    if(uart2_state_typedef.state == UART_RECEIVE_OK)
    {
      uart2_state_typedef.state = 0;
      ret = 0;
      huart2.Instance->ICR |= (USART_ICR_EOBCF|USART_ICR_TCCF|USART_ICR_FECF|USART_ICR_PECF);//eobf   txe  tc  fe  pe
      return ret;
      break;
    }
  }
    return ret;
}

如此便可以发送和接收了。

有一个问题,多收了一个数

于是在串口中断内,数据接收,和IDLE处,分别触发了一个电平信号,以便观察。如下图:

数据线上的波形

第1行的波形是发送引脚
第2行的波形是接收引脚
第3行的波形是方向控制引脚
第4行是接收中断,进一次就有一个脉冲
第5行是IDLE中断,进一次就有一个脉冲。
在这里插入图片描述
下图是放大的,一帧数据的波形
在这里插入图片描述
注意红圈的这个脉冲,数据还没有开始接收,却已经进中断开始接收了一次数据,这也就是额外多出来的一个接收字符。
在这里插入图片描述

问题分析

这个脉冲是发生的位置,是在数据发送完成,并且485的方向切换到接收之后5ms处,显然是在那时,又进了一次RXNE中断,进中断的原因也很简单,在因为下图这个低电平跳变。
在这里插入图片描述
也就是说,当485的数据方向从接收变为发送以后,接收端口会检测到一个低电平,这被认为是串口接收数据的起始位,但是后续没有一个高电平的结束位,所以收到的这个数据肯定是错误的,UART2的ISR寄存器FE位也指出了这一点,如下图
在这里插入图片描述

问题解决

知道了问题,也就知道了如何解决,将发送函数略做修改,发送完成后,清一下ISR寄存器的RXNE标识问题解决

void modbus_send(void)  //发送读寄存器的指令到串口
{
  u32 i=0;
  
  
  HAL_UART_AbortReceive_IT(&huart2);
  __HAL_UART_DISABLE_IT(&huart2, UART_IT_RXNE);	//禁用RXNE中断

  MAX485_OUT();
  delay_us(100);
  HAL_UART_Transmit(MODBUS_PORT, modbus_send_array,8, 100);   //从串口2发送数组命令
  huart2.Instance->RQR |= USART_RQR_RXFRQ;	//清除485方向切换导致的RXNE标识
  huart2.Instance->ICR |= USART_ICR_IDLECF;	//清除空闲标识
  huart2.Instance->ICR |= USART_ICR_TCCF;	//清除发送完成标识

  __HAL_UART_ENABLE_IT(&huart2, UART_IT_RXNE);	//启动RXNE中断
  
  MAX485_IN();
  uart2_state_typedef.len = 0;
  uart2_state_typedef.state = UART_READY;
  delay_us(10);
}

在这里插入图片描述

在这里插入图片描述
进了8次接收中断,接收8个字符,进一次IDLE中断,表示这一帧结束,工作正常。

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Free Virtual Serial Port Tools是一款允许创建虚拟串的软件工具。串通信是计算机与外部设备之间的通讯方式之一,将数据以连续的串行方式传输,这些外设包括传感器、打印机等。与外设之间的物理连接通常通过串进行。但是,在许多应用程序中,一个计算机可能需要模拟多个串和外部设备的通信,这意味着计算机需要虚拟多个串。 Free Virtual Serial Port Tools可以创建多个虚拟串,使计算机上应用程序可以分别与不同的虚拟外部设备进行通信。用户可以通过选择端名称、波特率、数据位数、校验和停止位数等配置虚拟串的属性。软件还支持多种串通信协议,包括RS232、RS422和RS485等。虚拟串可以实现通过网络通信和模拟数据交换等功能。在开发嵌入式系统、测试应用程序和调试串设备时,Free Virtual Serial Port Tools是非常有用的工具。 总之,Free Virtual Serial Port Tools是一个免费、易于使用的虚拟串软件工具,方便用户模拟串设备的通信,以满足计算机上多种应用程序的需求。 ### 回答2: free-virtual-serial-port-tools sn 是一款免费的虚拟串工具,可以模拟真实的串操作,并通过计算机的串通信,实现不同设备之间的数据传输,同时方便实现一些串相关应用程序的调试和测试。这款软件支持多个虚拟串的创建,并且具备高稳定性和高可靠性。通过它,用户可以模拟串设备的通信方式,实现数据的发送和接收,并且可以对每个虚拟串进行详细的设置和配置。在使用上,free-virtual-serial-port-tools sn 需要用户安装在电脑上,并根据实际需求进行设置和调试,以便达到最佳的应用效果。使用这款软件不仅可以节省用户的时间成本,还能提高工作效率,是一款非常实用的虚拟串工具。总之, free-virtual-serial-port-tools sn 非常适合那些需要模拟串通信的用户,可以有效地提高数据传输的效率和可靠性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值