STM32-RS485通信软硬件实现
原文:https://www.cnblogs.com/WhiteTears/p/8810801.html
阅读目录
- 1、RS485简介
- 2、RS485特性
- 3、RS485通信硬件实现
- 4、RS485通信软件实现
OS:Windows 64
Development kit:MDK5.14
IDE:UV4
MCU:STM32F103C8T6/VET6
AD:Altium Designer 18.0.12
回到顶部
1、RS485简介
RS-485又名TIA-485-A, ANSI/TIA/EIA-485或TIA/EIA-485。
RS485是一个定义平衡数字多点系统中的驱动器和接收器的电气特性的标准,该标准由电信行业协会和电子工业联盟定义。使用该标准的数字通信网络能在远距离条件下以及电子噪声大的环境下有效传输信号。RS-485使得廉价本地网络以及多支路通信链路的配置成为可能。RS485接口组成的半双工网络,一般是两线制(以前有四线制接法,只能实现点对点的通信方式,现很少采用),多采用屏蔽双绞线传输。这种接线方式为总线式拓扑结构在同一总线上最多可以挂接32个结点。在RS485通信网络中一般采用的是主从通信方式,即一个主机带多个从机。很多情况下,连接RS-485通信链路时只是简单地用一对双绞线将各个接口的“A”、“B”端连接起来。RS485接口连接器采用DB-9的9芯插头座,与智能终端RS485接口采用DB-9(孔),与键盘连接的键盘接口RS485采用DB-9(针)。
在低速、短距离、无干扰的场合可以采用普通的双绞线,反之,在高速、长线传输时,则必须采用阻抗匹配(一般为120Ω)的RS485专用电缆(STP-120Ω(用于RS485 & CAN)一对18AWG),而在干扰恶劣的环境下还应采用铠装型双绞屏蔽电缆(ASTP-120Ω(用于RS485 & CAN)一对18AWG)。
回到顶部
2、RS485特性
- RS-485的电气特性:逻辑“0”以两线间的电压差为+(2—6)V表示;逻辑“1”以两线间的电压差为-(2—6)V表示。接口信号电平比RS-232降低了,就不易损坏接口电路的芯片,且该电平与TTL电平兼容,可方便与TTL电路连接
- RS-485的数据最高传输速率为10Mbps
- RS-485接口是采用平衡驱动器和差分接收器的组合,抗共模干扰能力增强,即抗噪声干扰性好
- RS-485接口的最大传输距离标准值为4000英尺(约1219米),实际上可达3000英尺,另外RS-232接口在总线上只允许连接1个收发器,即单站能力。而RS-485接口在总线上是允许连接多达128个收发器。即具有多站能力,这样用户可以利用单一的RS-485接口方便地建立起设备网络。
回到顶部
3、RS485通信硬件实现
博主使用的485芯片为MAX3485,实现半双工通信。应用电路如下图:
R6为120欧的阻抗匹配电阻,如果长距离通信的话,一定要在最后一个节点接上这一个电阻;但是短距离通信的话焊上R6反而出错(博主在实验中发现,焊上匹配电阻后,主从节点通信异常,调试发现大量的00字节在自动收发),因此建议大家先不要焊上,但是在电路设计时保留。RXD485、TXD485分别接控制芯片的USART1_RX、USART1_TX(串口号可自行选择,这里使用串口1),此外;485C接芯片的PA4引脚(随意选择)用以切换485的通信状态。J1、J2为两个JST接口,方便485通信线路的连接,由于是从节点因而留出两个。以下为其余连接电路:
回到顶部
4、RS485通信软件实现
1 #include "sys.h"2 #include "stdio.h"3 4 #define USART1_RX_LEN 50 //接收最大字节5 #define USART1_TX_LEN 50 //发送最大字节6 #define RS485_TX_EN PAout(4)7 8 9 extern u8 USART1_RX_Buf[USART1_RX_LEN]; //接收缓冲 10 extern u8 USART1_TX_Buf[USART1_TX_LEN]; //发送缓冲 11 extern u8 USART1_RX_Data_Len; //实际接收数据字节长度 12 extern u8 USART1_TX_Data_Len; //待发送数据字节长度 13 extern u8 USART1_RX_Flag; //是否收到数据 14 15 void RS485_Config(u32 bound); 16 void USART1_IRQHandler(void); 17 void RS485_Send_Data(u8 *buf,u8 len);
1 #include "sys.h"2 #include "delay.h"3 #include "rs485.h"4 5 u8 USART1_RX_Buf[USART1_RX_LEN]; //接收缓冲6 u8 USART1_TX_Buf[USART1_TX_LEN]; //发送缓冲7 u8 USART1_RX_Data_Len = 0; //实际接收数据字节长度8 u8 USART1_TX_Data_Len = 0; //待发送数据字节长度9 u8 USART1_RX_Flag = 0; //串口1是否接收完数据 10 11 void USART1_IRQHandler(void) 12 { 13 u8 res; 14 if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收到数据 15 { 16 res =USART_ReceiveData(USART1); //读取接收到的数据 17 if(USART1_RX_Data_Len<USART1_RX_LEN) 18 { 19 USART1_RX_Buf[USART1_RX_Data_Len]=res; //记录接收到的值 20 USART1_RX_Data_Len++; //接收数据增加 1 21 } 22 USART1_RX_Flag=1; //串口1接收到数据 23 } 24 } 25 26 void RS485_Config(u32 bound) 27 { 28 GPIO_InitTypeDef GPIO_InitStructure; 29 USART_InitTypeDef USART_InitStructure; 30 NVIC_InitTypeDef NVIC_InitStructure; 31 32 /*********************配置串口1**************************/ 33 34 /* config USART1 clock */ 35 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 , ENABLE); 36 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE); 37 38 /* USART1 GPIO config */ 39 /* Configure USART1 Tx (PA.02) as alternate function push-pull *///TX 40 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; 41 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出 42 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 43 GPIO_Init(GPIOA, &GPIO_InitStructure); 44 /* Configure USART1 Rx (PA.03) as input floating *///RX 45 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; 46 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入 47 GPIO_Init(GPIOA, &GPIO_InitStructure); 48 49 50 51 52 /* USART1 mode config */ 53 54 USART_InitStructure.USART_BaudRate = bound; 55 USART_InitStructure.USART_WordLength = USART_WordLength_8b; 56 USART_InitStructure.USART_StopBits = USART_StopBits_1; 57 USART_InitStructure.USART_Parity = USART_Parity_No ; 58 USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; 59 USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; 60 USART_Init(USART1, &USART_InitStructure); 61 62 /* USART1 接收中断 */ 63 NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; //使能串口 2 中断 64 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; //先占优先级 3 级 65 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //从优先级 2级 66 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道 67 NVIC_Init(&NVIC_InitStructure);//初始化 NVIC 寄存器 68 69 USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //开启中断 70 USART_Cmd(USART1, ENABLE); //使能串口 71 72 //USART_ClearFlag(USART1, USART_FLAG_TC);//清发送完成标志 73 74 75 /**********************配置485控制口*********************/ 76 77 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; 78 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出 ,PA4,485Ctr 79 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 80 GPIO_Init(GPIOA, &GPIO_InitStructure); 81 GPIO_ResetBits(GPIOA, GPIO_Pin_4); //设置为接收模式,默认接收 82 83 } 84 85 void RS485_Send_Data(u8 *buf,u8 len) //发送完改为接收 86 { 87 u8 t; 88 RS485_TX_EN=1;//设置为发送模式 89 for(t=0;t<len;t++) 90 { 91 while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET); 92 USART_SendData(USART1,buf[t]); 93 } 94 while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET); 95 96 USART1_RX_Data_Len=0; 97 RS485_TX_EN=0;//设置为接收模式 98 }
通过以上代码我么们就能通过STM32的串口资源实现485的正常通信了。注意事项:
- 初始化串口:RX设置为浮空输入、TX设置为复用推挽输出
- 因为是从节点,默认为接收模式,485C初始化为低电平;主节点则相反。可根据需要修改
- 每次发送或接收时都应切换通信状态
STM32-RS485通信软硬件实现相关推荐
- STM32:RS485通信和Modbus通信协议汇总
RS485通信和Modbus通信协议汇总 1. 主从模式 RS-485上的软件层协议ModBus主要依赖于主从模式.主从模式是指在半双工通讯方式上,2个或者2个以上的设备组成的通讯系统中: (1) 至 ...
- STM32物联网项目-RS485通信(Modbus协议)
RS485通信(Modbus协议) 协议介绍 RS485介绍:http://t.csdn.cn/bOuFX Modbus协议:http://t.csdn.cn/mgioX CubeMX配置 RS-48 ...
- 基于UCOSII的RS485通信(STM32F107)
一.实现效果 基于ucosii实时操作系统的RS485通信,采用USART + DMA进行收发, 二.开发环境 开发工具:KEIL V5 开发板: STM32f107RC 采用方式:USART + D ...
- 基于STM32F103单片机的智能温室大棚RS485通信温湿度监测
系统功能设计 (末尾附文件) STM32单片机智能大棚485上传温湿度光照检测补光 本系统由STM32单片机RS485采集板和STM32单片机RS485显示按键板组成. 采集板由STM32F103C8 ...
- STM32+RS485+Modbus-RTU(主机模式+从机模式)-标准库/HAL库开发
modbus协议 完成modbus协议的编程之后,设备可以分别作为modbus协议的主机或者从机进行测试,使用模拟软件测试完毕后,完整代码以三个版本的形式进行介绍 1.版本一:使用串口接收数据超时完成 ...
- 安装STM32CubeMX,stm32串口通信
目录 一.串口通信和RS-232标准 1.串口通信 波特率 数据位 停止位 奇偶校验 2.RS-232标准 二.安装STM32CubeMX,搭建STM32的开发环境 1.安装jdk 2.安装STM32 ...
- STM32 RS485传输ADC值代码
STM32 RS485传输ADC值的代码需要分为两部分:ADC采集和RS485通信. 首先,对于ADC采集,你需要配置STM32的ADC模块,并读取ADC的值.具体的代码实现可以参考STM32官方文档 ...
- 51单片机串口2的RS485通信调试总结
过完年,一到公司主管就催我赶紧把这个项目的PC和单片机的RS485通信给调通.这几天,一直在实验室度过的.开始我从单片机简单发送一串数据,用串口调试助手测试.上位机根本没有接收到数据,用示波器测了发送 ...
- RT-Thread 应用笔记 - STM32 CAN 通信双机
RT-Thread 应用笔记 - 不正确使用LOG也会引发hard fault RT-Thread 应用笔记 - RTC Alarm组件的使用 RT-Thread 应用笔记 - freemodbus ...
最新文章
- 第二次作业+105032014116
- JDBC读取新插入Oracle数据库Sequence值的5种方法
- 对于java的命名规范(标识符)
- 淘系音视频技术的演进之路
- java join()用法_四种联系(join)的区别及用法
- DSDV的问题(Problems of DSDV)
- 程序员如何用六年时间打造价值10亿的帝国?
- C++构造函数(复制构造函数)、析构函数
- matlab画圆的命令_matlab画矩形和matlab画圆
- 三种计算机控制系统是,计算机控制系统3
- GEE-Python遥感大数据分析
- 怎么在计算机里找到CF里保存的视频,Win10电脑上查看穿越火线录制保存视频的具体方法...
- Arduino + Lcd1602 显示当前环境温度
- matlab中的unique
- 我又被当当骗了!!!
- angular使用service应用分层
- 显示远程服务器图片与映射远程服务器到本地
- TextMate 2.0 RC 23 特别版 Mac 著名的文本编辑器软件
- 注册ChatGPT时提示Oops! The email you provided is not supported
- IIS上安装Web平台安装程序