485通信协议

文章目录

  • STM32-20-485
    • 1. 485总线
    • 2. 485相关HAL库驱动
    • 3. 485配置步骤
    • 4. 代码实现

STM32-20-485

1. 485总线

  • 串口、UART、TTL、RS232、RS422、RS485关系:
    在这里插入图片描述

    关系与区别:

    特性串口UARTTTLRS232RS422RS485
    定义数据传输接口硬件设备电平标准通信标准通信标准通信标准
    电平--0V/5V±3V到±15V-6V到+6V-6V到+6V
    通信方式串行串行串行串行差分串行差分串行
    最大传输距离--短距离100米1200米1200米
    支持设备数---点对点多点多点
    典型应用数据传输微控制器数字电路计算机外设工业自动化工业自动化

    串口通信是一种通用的通信接口,可以通过不同的硬件和电平标准(如UART、TTL、RS232、RS422、RS485)来实现各种不同的应用需求。这些标准各有优缺点,适用于不同的应用场景,如短距离高速通信或长距离多设备通信。

  • 485总线介绍:

    RS485是串行通信标准,使用差分信号传输,抗干扰能力强,常用于工控领域。RS485具有强大的组网功能,在串口基础协议之上还制定MODBUS协议

    • 串口基础协议:仅指封装了基本数据包格式的协议(基于数据位

    • MODBUS协议:使用基本数据包组合成通讯帧格式的高层应用协议(基于数据包或字节

    • 关系:

      特性串口基础协议MODBUS协议
      通信模式点对点主从模式
      数据传输方式异步或同步异步
      数据格式起始位、数据位、校验位、停止位设备地址、功能码、数据域、校验码
      波特率可变固定在特定应用中
      应用场景广泛应用于各种串行通信场景工业自动化系统
      校验方式奇偶校验或无校验CRC校验(RTU模式)或LRC校验(ASCII模式)
      数据传输效率较低较高(特别是RTU模式)

      串口基础协议是一种底层通信协议,用于实现基本的串行数据传输,而MODBUS协议是一种应用层协议,基于串行通信实现设备间的数据交换,特别适用于工业控制系统。MODBUS协议利用串口基础协议传输数据,但增加了设备地址、功能码和校验等机制,以实现更复杂和可靠的通信。

  • 连接示意图:
    在这里插入图片描述

  • 485通信电路分析:
    在这里插入图片描述

    TP8485是一种用于实现RS-485通信的收发器芯片。它的主要作用是将微控制器或其他设备的UART信号转换为RS-485标准的差分信号,从而实现可靠的远距离通信。

  • 单片机A发送数据到单片机B示意图:
    在这里插入图片描述

    单片机A代码:

    void RS485_Send_Init(void) 
    {//配置UART发送UART_Init(baud_rate);//配置DE和RE控制的GPIO引脚GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.Pin = DE_PIN | RE_PIN;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;HAL_GPIO_Init(GPIO_PORT, &GPIO_InitStruct);//初始化时将DE和RE设置为低电平HAL_GPIO_WritePin(GPIO_PORT, DE_PIN, GPIO_PIN_RESET);HAL_GPIO_WritePin(GPIO_PORT, RE_PIN, GPIO_PIN_RESET);
    }void RS485_Send(uint8_t *data, uint16_t length) 
    {//设置DE和RE为高电平,使能发送模式HAL_GPIO_WritePin(GPIO_PORT, DE_PIN, GPIO_PIN_SET);HAL_GPIO_WritePin(GPIO_PORT, RE_PIN, GPIO_PIN_SET);//发送数据HAL_UART_Transmit(&huart, data, length, HAL_MAX_DELAY);//发送完成后,将DE和RE设置为低电平,禁用发送器HAL_GPIO_WritePin(GPIO_PORT, DE_PIN, GPIO_PIN_RESET);HAL_GPIO_WritePin(GPIO_PORT, RE_PIN, GPIO_PIN_RESET);
    }
    

    单片机B代码:

    void RS485_Receive_Init(void) 
    {//配置UART接收UART_Init(baud_rate);//配置DE和RE控制的GPIO引脚GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.Pin = DE_PIN | RE_PIN;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;HAL_GPIO_Init(GPIO_PORT, &GPIO_InitStruct);//初始化时将DE设置为低电平,RE设置为低电平,使能接收器HAL_GPIO_WritePin(GPIO_PORT, DE_PIN, GPIO_PIN_RESET);HAL_GPIO_WritePin(GPIO_PORT, RE_PIN, GPIO_PIN_RESET);
    }uint8_t RS485_Receive(void) 
    {uint8_t rec_data;HAL_UART_Receive(&huart, &rec_data, 1, HAL_MAX_DELAY);return rec_data;
    }
    

    作为驱动器和接收器时,电平状态:
    在这里插入图片描述

    波形示意图:
    在这里插入图片描述

    接线示意图:
    在这里插入图片描述

2. 485相关HAL库驱动

驱动函数关联寄存器功能描述
__HAL_RCC_USARTx_CLK_ENABLE()使能串口时钟
HAL_UART_Init()USART_CR1/CR2初始化串口
__HAL_UART_ENABLE_IT()USART_CR1使能串口相关中断
HAL_UART_Receive()USART_DR串口接收数据
HAL_UART_Transmit()USART_DR串口发送数据
__HAL_UART_GET_FLAG()USART_SR查询当前串口的状态

3. 485配置步骤

  1. 配置串口工作参数

    HAL_UART_Init()
    
  2. 串口底层初始化

    HAL_UART_MspInit()
    
  3. 开启串口异步接收中断

    __HAL_UART_ENABLE_IT()
    
  4. 设置优先级,使能中断

    HAL_NVIC_SetPriority()
    HAL_NVIC_EnableIRQ()
    
  5. 编写中断服务函数

    USARTx_IRQHandler()
    HAL_UART_Receive()    
    
  6. 串口数据发送

    HAL_UART_Transmit()
    

4. 代码实现

  • 功能: 通过连接两个战舰STM32F103的RS485接口,然后由KEY0控制发送,当按下一个开发板的KEY0的时候,就发送5个数据给另外一个开发板,并在两个开发板上分别显示发送的值和接收到的值。

  • 硬件原理图:
    在这里插入图片描述

  • RS485初始化函数:

    void rs485_init(uint32_t baudrate)
    {// IO 及 时钟配置 RS485_RE_GPIO_CLK_ENABLE(); // 使能 RS485_RE 脚时钟 RS485_TX_GPIO_CLK_ENABLE(); // 使能 串口TX脚 时钟 RS485_RX_GPIO_CLK_ENABLE(); // 使能 串口RX脚 时钟 RS485_UX_CLK_ENABLE();      // 使能 串口 时钟 GPIO_InitTypeDef gpio_initure;gpio_initure.Pin = RS485_TX_GPIO_PIN;gpio_initure.Mode = GPIO_MODE_AF_PP;gpio_initure.Pull = GPIO_PULLUP;gpio_initure.Speed = GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(RS485_TX_GPIO_PORT, &gpio_initure); // 串口TX 脚 模式设置 gpio_initure.Pin = RS485_RX_GPIO_PIN;gpio_initure.Mode = GPIO_MODE_AF_INPUT;HAL_GPIO_Init(RS485_RX_GPIO_PORT, &gpio_initure); // 串口RX 脚 必须设置成输入模式 gpio_initure.Pin = RS485_RE_GPIO_PIN;gpio_initure.Mode = GPIO_MODE_OUTPUT_PP;gpio_initure.Pull = GPIO_PULLUP;gpio_initure.Speed = GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(RS485_RE_GPIO_PORT, &gpio_initure); // RS485_RE 脚 模式设置 // USART 初始化设置 g_rs485_handler.Instance = RS485_UX;                  // 选择485对应的串口 g_rs485_handler.Init.BaudRate = baudrate;             // 波特率 g_rs485_handler.Init.WordLength = UART_WORDLENGTH_8B; // 字长为8位数据格式 g_rs485_handler.Init.StopBits = UART_STOPBITS_1;      // 一个停止位 g_rs485_handler.Init.Parity = UART_PARITY_NONE;       // 无奇偶校验位 g_rs485_handler.Init.HwFlowCtl = UART_HWCONTROL_NONE; // 无硬件流控 g_rs485_handler.Init.Mode = UART_MODE_TX_RX;          // 收发模式 HAL_UART_Init(&g_rs485_handler);                      // HAL_UART_Init()会使能UART2 #if RS485_EN_RX // 如果使能了接收 // 使能接收中断 __HAL_UART_ENABLE_IT(&g_rs485_handler, UART_IT_RXNE); // 开启接收中断 HAL_NVIC_EnableIRQ(RS485_UX_IRQn);                    // 使能USART2中断 HAL_NVIC_SetPriority(RS485_UX_IRQn, 3, 3);            // 抢占优先级3,子优先级3 
    #endifRS485_RE(0); // 默认为接收模式 
    }
    
  • RS485发送len个字节函数:

    void rs485_send_data(uint8_t *buf, uint8_t len)
    {RS485_RE(1);                                         // 进入发送模式 HAL_UART_Transmit(&g_rs485_handler, buf, len, 1000); // 串口2发送数据 g_RS485_rx_cnt = 0;RS485_RE(0); // 进入接收模式 
    }
    
  • RS485查询接收到的数据函数:

    void rs485_receive_data(uint8_t *buf, uint8_t *len)
    {uint8_t rxlen = g_RS485_rx_cnt;uint8_t i = 0;*len = 0;     // 默认为0 delay_ms(10); // 等待10ms,连续超过10ms没有接收到一个数据,则认为接收结束 if (rxlen == g_RS485_rx_cnt && rxlen) // 接收到了数据,且接收完成了 {for (i = 0; i < rxlen; i++){buf[i] = g_RS485_rx_buf[i];}*len = g_RS485_rx_cnt; // 记录本次数据长度 g_RS485_rx_cnt = 0;    // 清零}
    }
    
  • 接收中断服务函数:

    uint8_t g_RS485_rx_buf[RS485_REC_LEN]; // 接收缓冲, 最大 RS485_REC_LEN 个字节. 
    uint8_t g_RS485_rx_cnt = 0;            // 接收到的数据长度 void RS485_UX_IRQHandler(void)
    {uint8_t res;if ((__HAL_UART_GET_FLAG(&g_rs485_handler, UART_FLAG_RXNE) != RESET)) // 接收到数据 {HAL_UART_Receive(&g_rs485_handler, &res, 1, 1000);if (g_RS485_rx_cnt < RS485_REC_LEN)         // 缓冲区未满 {g_RS485_rx_buf[g_RS485_rx_cnt] = res;   // 记录接收到的值 g_RS485_rx_cnt++;                       // 接收数据增加1 }}
    }
    
  • 主函数:

    int main(void)
    {uint8_t key;uint8_t i = 0, t = 0;uint8_t cnt = 0;uint8_t rs485buf[5];HAL_Init();                                 /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9);         /* 设置时钟, 72Mhz */delay_init(72);                             /* 延时初始化 */usart_init(115200);                         /* 串口初始化为115200 */led_init();                                 /* 初始化LED */lcd_init();                                 /* 初始化LCD */key_init();                                 /* 初始化按键 */rs485_init(9600);                           /* 初始化RS485 */lcd_show_string(30,  50, 200, 16, 16, "STM32", RED);lcd_show_string(30,  70, 200, 16, 16, "RS485 TEST", RED);lcd_show_string(30,  90, 200, 16, 16, "ATOM@ALIENTEK", RED);lcd_show_string(30, 110, 200, 16, 16, "KEY0:Send", RED);    /* 显示提示信息 */lcd_show_string(30, 130, 200, 16, 16, "Count:", RED);       /* 显示当前计数值 */lcd_show_string(30, 150, 200, 16, 16, "Send Data:", RED);   /* 提示发送的数据 */lcd_show_string(30, 190, 200, 16, 16, "Receive Data:", RED);/* 提示接收到的数据 */while (1){key = key_scan(0);if (key == 2)   /* KEY0按下,发送一次数据 */{for (i = 0; i < 5; i++){rs485buf[i] = cnt + i;      /* 填充发送缓冲区 */lcd_show_xnum(30 + i * 32, 170, rs485buf[i], 3, 16, 0X80, BLUE);    /* 显示数据 */}rs485_send_data(rs485buf, 5);   /* 发送5个字节 */}rs485_receive_data(rs485buf, &key);if (key)    /* 接收到有数据 */{if (key > 5) key = 5;    /* 最大是5个数据. */for (i = 0; i < key; i++){lcd_show_xnum(30 + i * 32, 210, rs485buf[i], 3, 16, 0X80, BLUE);    /* 显示数据 */}}t++;delay_ms(10);if (t == 20){LED0_TOGGLE();  /* LED0闪烁, 提示系统正在运行 */t = 0;cnt++;lcd_show_xnum(30 + 48, 130, cnt, 3, 16, 0X80, BLUE);    /* 显示数据 */}}
    }
    

声明:资料来源(战舰STM32F103ZET6开发板资源包)

  1. Cortex-M3权威指南(中文).pdf
  2. STM32F10xxx参考手册_V10(中文版).pdf
  3. STM32F103 战舰开发指南V1.3.pdf
  4. STM32F103ZET6(中文版).pdf
  5. 战舰V4 硬件参考手册_V1.0.pdf

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

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

相关文章

安享智慧理财金融测试项目

1. 项目介绍 安享智慧理财金融系统是基于 Java 语言开发&#xff0c;集 PC 端、APP 端、WAP 端为一体的 P2P&#xff08;个人对个人&#xff09;的借贷系统&#xff0c;提供了完整的借款和投资功能。 web用户端 说明&#xff1a;PC 网站&#xff0c;供借款人和投资人使用功能…

疯狂买买买!你的支付环境真的安全吗?

在日常生活中&#xff0c;移动电话为我们带来了更多的方便。然而&#xff0c;我们在享受手机支付的便捷之余&#xff0c;也应充分认识到风险&#xff0c;增强防范意识&#xff0c;慧眼识诈。 小亿提醒&#xff1a;大家在购物之余&#xff0c;务必要注意手机支付的安全性&#…

2021 hnust 湖科大 C语言课程设计报告+代码+流程图源文件+指导书

2021 hnust 湖科大 C语言课程设计报告代码流程图源文件指导书 目录 报告 下载链接 https://pan.baidu.com/s/14NFsDbT3iS-a-_7l0N5Ulg?pwd1111

系统架构——Spring Framework

目录 &#xff08;1&#xff09;基本介绍 &#xff08;2&#xff09;基本发展历史 &#xff08;3&#xff09;了解和学习 Spring 4.x 系列的系统架构 1、第一个模块&#xff1a;做核心容器&#xff08;Core Contaner&#xff09; 2、第二个模块&#xff1a;AOP与Aspects(这…

Flink 反压

反压 Flink反压是一个在实时计算应用中常见的问题&#xff0c;特别是在流式计算场景中。以下是对Flink反压的详细解释&#xff1a; 一、反压释义 反压&#xff08;backpressure&#xff09;意味着数据管道中某个节点成为瓶颈&#xff0c;其处理速率跟不上上游发送数据的速率…

Chrome插件开发入门:手把手教你创建第一个扩展

问题背景 最近&#xff0c;客户发布了一个新的任务 —— 开发一个Chrome插件。之前没有这方面的开发经验&#xff0c;准备想学习一下这块的内容&#xff0c;我发现网上的大多数视频都是几年前的&#xff0c;开发版本都是基于MV2&#xff0c;当前谷歌已经开始使用MV3&#xff0…

【区块链】以太坊白皮书深度解读:构建智能合约的分布式平台

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 以太坊白皮书深度解读&#xff1a;构建智能合约的分布式平台引言1. 以太坊的诞生…

Nuxt快速学习开发---Nuxt3视图Views

Views Nuxt提供了几个组件层来实现应用程序的用户界面 默认情况下&#xff0c;Nuxt 会将app.vue文件视为入口点并为应用程序的每个路由呈现其内容 应用程序.vue <template> <div> <h1>Welcome to the homepage</h1> </div> </template> …

油猴hook+内存爆破

hook方式 说明&#xff1a;来回翻页发现只有请求体的token需要逆向&#xff0c;而这个请求体是在params里&#xff0c;拼接到url里&#xff0c;可以直接用油猴hook url里的关键字token。 正常步骤 hook代码 // UserScript // name hookparams // namespace htt…

【C语言】扫雷游戏

Hi~&#xff01;这里是奋斗的小羊&#xff0c;很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~~ &#x1f4a5;&#x1f4a5;个人主页&#xff1a;奋斗的小羊 &#x1f4a5;&#x1f4a5;所属专栏&#xff1a;C语言 &#x1f680;本系列文章为个人学习…

springBoot多数据源使用、配置

又参加了一个新的项目&#xff0c;虽然是去年做的项目&#xff0c;拿来复用改造&#xff0c;但是也学到了很多。这个项目会用到其他项目的数据&#xff0c;如果调用他们的接口取数据&#xff0c;我还是觉得太麻烦了。打算直接配置多数据源。 然后去另一个数据库系统中取出数据…

深信服科技:2023网络钓鱼趋势分析报告

随着互联网的快速发展和广泛应用&#xff0c;网络钓鱼活动带来的安全隐患愈演愈烈。因应威胁发展&#xff0c;我 们编撰了此份分析报告&#xff0c;旨在全面了解其发展态势&#xff0c;并提醒相关部门、企业和公众加强防范。 在本报告中&#xff0c;我们将详细梳理网络钓鱼的近…

IBM,开始构建以量子为中心的超级计算机

6月6日&#xff0c;IBM与Pasqal宣布了一项重大合作!IBM和Pasqal打算合作开发一种以量子为中心的超级计算的通用方法并促进化学和材料科学的应用研究。IBM和Pasqal将与高性能计算领域的领先机构合作&#xff0c;为以量子为中心的超级计算奠定基础——将量子计算与先进的经典计算…

【WEB前端2024】3D智体编程:乔布斯3D纪念馆-第44课-骨骼动画

【WEB前端2024】3D智体编程&#xff1a;乔布斯3D纪念馆-第44课-骨骼动画 使用dtns.network德塔世界&#xff08;开源的智体世界引擎&#xff09;&#xff0c;策划和设计《乔布斯超大型的开源3D纪念馆》的系列教程。dtns.network是一款主要由JavaScript编写的智体世界引擎&…

开放式耳机哪个牌子好?2024五大闭眼入开放式耳机推荐!

想要购买开放式耳机&#xff0c;但面对很多品牌和型号&#xff0c;是否感到无从下手&#xff1f;别担心&#xff0c;作为耳机发烧友和测评专家&#xff0c;我为大家带来了几款热门开放式耳机的横向对比。从各个方面进行详细对比&#xff0c;还有我自己觉得还不错的五款开放式耳…

微型导轨的摩擦系数分析!

微型导轨的摩擦力主要包括滑动摩擦力和滚动摩擦力&#xff0c;摩擦系数是一个关键参数&#xff0c;它决定了滑块在导轨上运动时所受到的摩擦力大小&#xff0c;摩擦系数越低&#xff0c;系统的运动效率和精度就越高&#xff0c;而微型导轨的摩擦系数是受多个因素影响的。 微型导…

【docker hub镜像源失效】2024年6月6日 docker 国内镜像源失效

文章目录 概述中科大镜像源阿里镜像源其他镜像源可用的镜像源写在最后 之前违反社区规定了&#xff0c;做了和谐 概述 大家都知道使用docker hub官方镜像需要魔法&#xff0c;虽然大部人有魔法&#xff0c;但是网速也是很慢&#xff0c;还有部分同学没有&#xff0c;全靠国内各…

移远通信发布高性价比智能模组SC200P系列,赋能金融支付等行业智慧升级

近日&#xff0c;全球领先的物联网整体解决方案供应商移远通信宣布&#xff0c;为满足智慧金融、智能家居、智能穿戴、工业手持等消费和工业应用对高速率、多媒体、长生命周期等终端性能的需求&#xff0c;其正式推出基于紫光展锐UNISOC 7861平台的全新8核4G智能模组SC200P系列…

关于INCA的几个实用功能

01--VUI窗口设计 这个可以按照自己的想法设计INCA观测或标定窗口 首先进入到INCA的环境内&#xff0c;点击实验→加载VUI窗口 选择空的窗口 打开后如下所示&#xff1a; 点击UI开发模式&#xff0c;如下图 如下&#xff1a; 添加标定量、观测量、示波器 窗口的大小需要在开发…

ProtoBuf序列化协议简介

首先&#xff0c;常见的序列化方法主要有以下几种&#xff1a; TLV编码及其变体(tag, length, value)&#xff1a; 比如ProtoBuf。文本流编码&#xff1a;XML/JSON固定结构编码&#xff1a;基本原理是&#xff0c;协议约定了传输字段类型和字段含义&#xff0c;和TLV类似&…