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

news2024/9/24 15:27:11

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

  • RS-485说明
  • 接口芯片
  • 硬件连接
  • CubeMX设置
  • 代码编写
    • 引脚定义
    • 使能串口
    • 中断函数
    • 发送数据
    • 接收数据
  • 有一个问题,多收了一个数
  • 数据线上的波形
  • 问题分析
  • 问题解决

RS-485说明

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

接口芯片

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

硬件连接

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

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中断是用来接收数据, 每次接收个数据,并且在中断中再次开启这个中断
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标识
  
  MAX485_IN();
  uart2_state_typedef.len = 0;
  uart2_state_typedef.state = UART_READY;
  delay_us(10);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/67012.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LeetCode简单题之回环句

题目 句子 是由单个空格分隔的一组单词,且不含前导或尾随空格。 例如,“Hello World”、“HELLO”、“hello world hello world” 都是符合要求的句子。 单词 仅 由大写和小写英文字母组成。且大写和小写字母会视作不同字符。 如果句子满足下述全部条…

从 0 开始学习 Git + GitHub

文章目录一、GitHub创建仓库二、安装Git客户端1、安装2、配置身份三、为Github账户设置SSH key1、生成ssh key2、GitHub 新建SSh key3、测试连接是否成功四、上传本地项目到Github方法一:方法二:master分支到main分支迁移五、Git常用命令git initgit sta…

共享主机安全吗(以及如何保护它)?

共享主机是在一台服务器上存储多个网站的主机。通常,您的资源(例如 CPU、内存、数据库和带宽)会在用户之间溢出。由于它非常适合流量低的网站,且因具成本效益,共享主机相当普遍。如果您是博主和小型企业,则很有可能会选择共享主机…

聊聊我常用的5款动态数据可视化工具

视频当道的时代,数据可视化自然也要动起来。 我常用的动态可视化工具主要有Tableau、Echarts、Flourish、Python这几个,另外一个地图可视化神器kepler.gl,是技术群小伙伴的分享。 这五款可视化工具差异很大,在各自领域都是学霸级…

Grafana 快速配置可视化面板

一、如何快速搭建部署Grafana CSDNhttps://mp.csdn.net/mp_blog/creation/editor/128199952 二、快速配置可视化面板 1.新建数据源 首次新建数据源、首次新建看板 2.选择数据源类型 3.配置数据库 地址、账号、密码 备注:新建的数据源都可以在添加看板作为选项进…

Odoo丨如何在明细行中添加复选框?

最近,在项目实际业务中遇到需要对明细订单添加复选框和按钮进行操作的需求。 起初在拿到需求时,我联想到Odoo默认tree视图是有复选框和操作按钮的功能,于是查看了源码,确认了这个想法。 因为这个是属于字段中one2many 关系属性来…

【DPDK】dpdk样例源码解析之五:dpdk-rss

本篇文章介绍DPDK-RSS相关的功能,RSS是网卡提供的分流机制,简单讲就是一个HASH值,如果使用DPDK收包,开启RSS后,会根据配置项将数据包分流到不同的收包队列,用来是实现负载均衡。 通过DPDK-L3FWD样例&#…

关于Pytorch下载并进行部署

目录 1.关于Pytorch 2.Pytorch环境部署前提条件 3.部署方法 4.测试 1.关于Pytorch PyTorch是一个开源的Python机器学习库,基于Torch,用于计算机视觉、自然语言处理等应用程序。 2017年1月,由Facebook人工智能研究院(FAIR&…

数据库设计 ER图

三个基本概念 Entity Entity Set表示一类事物,类似于面向对象中类的概念,而Entity Instance表示一个具体的事物,类似于对象的概念。 Entity中可以有属性(Attribute),也可以与其他Entity之间存在关系(Relationship)。在设计数据库…

【最新版全插件】多功能同城优选小程序源码

内容目录一、详细介绍二、效果展示1.部分代码2.效果图展示三、学习资料下载一、详细介绍 1.为本地的线下商家提供线上销售渠道。一直以来本地商品、娱乐、休闲、旅游服务线上购买大家都是以美团为准。近几年来随着微信公众号、小程序的渗透力逐渐加强,越来越多的用…

【深度学习】实验6答案:图像自然语言描述生成(让计算机“看图说话”)

DL_class 学堂在线《深度学习》实验课代码报告(其中实验1和实验6有配套PPT),授课老师为胡晓林老师。课程链接:https://www.xuetangx.com/training/DP080910033751/619488?channeli.area.manual_search。 持续更新中。 所有代码…

ElasticSearch实战

一、es集群的搭建 1.集群相关概念 单节点故障问题 单台服务器,往往都有最大的负载能力,超过这个阈值,服务器性能就会大大降低甚至不可用。单点的elasticsearch也是一样那单点的es服务器存在哪些可能出现的问题呢? 单台机器存储…

[附源码]计算机毕业设计基于springboot在线影院系统

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

ROS MoveIT1(Noetic)安装总结

前言 由于MoveIT2的Humble的教程好多用的还是moveit1的环境,所以又装了Ubutun20.04和ROS1(Noetic)。【2022年12月6日】 环境 系统:Ubutun20.04LTS Ros:Noetic 虚拟机:VMware 安装 ROS Noetic 安装教程…

【微信小程序】canvasToTempFilePath遇到的问题

在微信小程序开发中,经常需要将绘制好的canvas保存到本地,这就需要调用canvasToTempFilePath将canvas画布转为本地临时文件。遇到过的问题如下: 1.create bitmap failed 2.fail canvas is empty 这个问题就是canvas还没画为空拿不到转化的临…

Eclipse+Maven+Tomcat 集成开发环境配置

在Eclipse中创建的Dynamic Web Project 类型的Web 项目, 通过Run As -> Run on Server 可以添加本地安装的Tomcat,在Eclipse 中启动Tomcat 进行整合开发。 但是如果创建的是Maven类型的项目,如果没有导入额外的包还正常, 但是…

Nginx入门到搭建

前言 上一篇文章我们分享了Linux的软件安装以及项目后端的部署,本篇文章将要分享的内容是,Nginx的入门安装、反向代理、负载均衡等。 一、Nginx简介 Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3) 代理服务…

如何让彩色网页变灰

如何让彩色网页变灰 在特殊的日子&#xff08;如清明节特殊纪念日等&#xff09;&#xff0c;需要让彩色网页变成灰色&#xff08;黑白色&#xff09;如下图所示&#xff0c;怎么做到呢&#xff1f; 下面先给出彩色正常的网页示例源码&#xff1a; <!DOCTYPE html> <…

消除数据库表中的重复组

重复组是在整个数据库表中重复的一系列字段/属性。大型和小型组织都面临着一个普遍的问题&#xff0c;这个问题可能会带来多种后果。例如&#xff0c;在不同区域中存在的同一组信息会导致数据冗余和数据不一致。而且&#xff0c;所有这些重复的数据可能会占用大量宝贵的磁盘空间…

【计算机图形学入门】笔记2:向量与线性代数(图形学中用到的线性代数)

02向量与线性代数&#xff08;图形学中用到的线性代数&#xff09;1.A Swift and Brutal Introduction to Linear Algebra!简单粗暴入门线性代数1.Graphics’ Dependencies 图形学依赖的一些知识2.Vectors 向量1.Dot product向量的点乘2.向量的叉乘Cross product3.矩阵Matrix4.…