STM32-RS485通信软硬件实现
OS:Windows 64
Development kit:MDK5.14
IDE:UV4
MCU:STM32F103C8T6/VET6
AD:Altium Designer 18.0.12
1、RS485简介
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通信软件实现
#include "sys.h"
#include "stdio.h" #define USART1_RX_LEN 50 //接收最大字节
#define USART1_TX_LEN 50 //发送最大字节
#define RS485_TX_EN PAout(4) extern u8 USART1_RX_Buf[USART1_RX_LEN]; //接收缓冲
extern u8 USART1_TX_Buf[USART1_TX_LEN]; //发送缓冲
extern u8 USART1_RX_Data_Len; //实际接收数据字节长度
extern u8 USART1_TX_Data_Len; //待发送数据字节长度
extern u8 USART1_RX_Flag; //是否收到数据 void RS485_Config(u32 bound);
void USART1_IRQHandler(void);
void RS485_Send_Data(u8 *buf,u8 len);
485.h
#include "sys.h"
#include "delay.h"
#include "rs485.h" u8 USART1_RX_Buf[USART1_RX_LEN]; //接收缓冲
u8 USART1_TX_Buf[USART1_TX_LEN]; //发送缓冲
u8 USART1_RX_Data_Len = ; //实际接收数据字节长度
u8 USART1_TX_Data_Len = ; //待发送数据字节长度
u8 USART1_RX_Flag = ; //串口1是否接收完数据 void USART1_IRQHandler(void)
{
u8 res;
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收到数据
{
res =USART_ReceiveData(USART1); //读取接收到的数据
if(USART1_RX_Data_Len<USART1_RX_LEN)
{
USART1_RX_Buf[USART1_RX_Data_Len]=res; //记录接收到的值
USART1_RX_Data_Len++; //接收数据增加 1
}
USART1_RX_Flag=; //串口1接收到数据
}
} void RS485_Config(u32 bound)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure; /*********************配置串口1**************************/ /* config USART1 clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 , ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE); /* USART1 GPIO config */
/* Configure USART1 Tx (PA.02) as alternate function push-pull *///TX
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Configure USART1 Rx (PA.03) as input floating *///RX
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
GPIO_Init(GPIOA, &GPIO_InitStructure); /* USART1 mode config */ USART_InitStructure.USART_BaudRate = bound;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_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(USART1, &USART_InitStructure); /* USART1 接收中断 */
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; //使能串口 2 中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = ; //先占优先级 3 级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = ; //从优先级 2级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道
NVIC_Init(&NVIC_InitStructure);//初始化 NVIC 寄存器 USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //开启中断
USART_Cmd(USART1, ENABLE); //使能串口 //USART_ClearFlag(USART1, USART_FLAG_TC);//清发送完成标志 /**********************配置485控制口*********************/ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出 ,PA4,485Ctr
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_ResetBits(GPIOA, GPIO_Pin_4); //设置为接收模式,默认接收 } void RS485_Send_Data(u8 *buf,u8 len) //发送完改为接收
{
u8 t;
RS485_TX_EN=;//设置为发送模式
for(t=;t<len;t++)
{
while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
USART_SendData(USART1,buf[t]);
}
while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET); USART1_RX_Data_Len=;
RS485_TX_EN=;//设置为接收模式
}
485.c
通过以上代码我么们就能通过STM32的串口资源实现485的正常通信了。注意事项:
- 初始化串口:RX设置为浮空输入、TX设置为复用推挽输出
- 因为是从节点,默认为接收模式,485C初始化为低电平;主节点则相反。可根据需要修改
- 每次发送或接收时都应切换通信状态
STM32-RS485通信软硬件实现的更多相关文章
- RS485 通信接收时丢失0x11等数据
RS485通信接收方,丢弃掉了值为 0x11 的数据. 怀疑 0x11 被转义,没有按照原始数据接收, 查看ASCII码对应表 0x11 代表 “本文结束”, 因此丢弃是有可能的. 要想接收原始数据而 ...
- Stm32串口通信(USART)
Stm32串口通信(UART) 串口通信的分类 串口通信三种传递方式 串口通信的通信方式 串行通信的方式: 异步通信:它用一个起始位表示字符的开始,用停止位表示字符的结束.其每帧的格式如下: 在一帧格 ...
- STM32 串口通信使用奇偶校验
STM32串口通信如果使用奇偶校验,需要设置数据位长度为9bit USART_InitStructure.USART_BaudRate = 9600; USART_InitStructure.USAR ...
- STM32串口通信UART使用
STM32串口通信UART使用 uart使用的过程为: 1. 使能GPIO口和UART对应的总线时钟 2. 配置GPIO口的输出模式 3. 配置uart口相关的基本信息 4. 使能uart口的相关的中 ...
- RS485通信和Modbus协议(转)
转自:http://www.51hei.com/bbs/dpj-23230-1.html 在工业控制.电力通讯.智能仪表等领域,通常情况下是采用串口通信的方式进行数据交换.最初采用的方式是RS232接 ...
- RS485通信电路
RS485由RS232和RS422发展而来,弥补了抗干扰能力差.通信距离短.速率低的缺点,增加了多点.双向通信能力,即允许多个发送器连接在同一条主线上,同时增加了发送器的驱动能力和冲突保护特性,扩展了 ...
- stm32之通信
本文提到的内容有以下几个方面: 通信概述 串口通信 I2C通信 CAN通信 SPI通信 I2S通信 USB通信 其他通信 一.通信概述 按照数据传送方式分: 串行通信(一条数据线.适合远距离传输.控制 ...
- STM32 USB-HID通信移植步骤
大家可以使用压缩包中的UsbApp.exe调试本软件idVendor为:0483 idProduct为5750. 今天太晚了,明天还要上半天班,上位机软件找个时间在写一篇文章.请关注我的博客.压缩包 ...
- stm32串口通信实验,一点笔记
第一次深入学习stm32,花了好长时间才看懂代码(主要是C语言学习不够深入),又花了段时间自己敲了一遍,然后比对教程,了解了利用中断来串口通信的设置方法. 板子是探索版f407,本实验工程把正点原子库 ...
随机推荐
- 从iOS 11 UI Kit中谈谈iOS 11的新变化
北京时间9月20日凌晨1点,iOS 11终于迎来了正式版的推送,相信各位小伙伴已经在第一时间进行了升级.iOS 11毫无疑问是一次大规模的系统更新,UI.系统内核.锁屏等多方面都进行了不同程度的改进. ...
- Java设计模式(4)——单例模式
转载:http://wiki.jikexueyuan.com/project/java-design-pattern/singleton-pattern.html 单例模式根据实例化对象时机的不同分为 ...
- 20155317 2016-2017-2 《Java程序设计》第7周学习总结
20155317 2016-2017-2 <Java程序设计>第7周学习总结 教材学习内容总结 1.在只有Lambda表达式的情况下,参数的类型必须写出来. 2.Lambda表达式本身是中 ...
- C#分布式事务解决方案-TransactionScope(转)
出处:C#分布式事务解决方案-TransactionScope 引用一下别人的导读:在实际开发工作中,执行一个事件,然后调用另一接口插入数据,如果处理逻辑出现异常,那么之前插入的数据将成为垃圾数据,我 ...
- xib下这种方式创建cell
这种方法在iOS5.0之前是不能够创建成功的. MEConvertListTableViewCell *cell = [tableView dequeueReusableCellWithIde ...
- 51nod1057—N的阶乘—(大数阶乘)
1057 N的阶乘 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注 输入N求N的阶乘的准确值. Input 输入N(1 <= N <= ...
- 7、Docker Container
7.1 什么是Container 通过image创建(copy) 在Image layer之上建立一个Container layer(可读写) 类比面向对象:类和实例 Image负责APP的存储和分发 ...
- 解决PL/SQL Developer连接数据库时出现 “ORA-12541:TNS:无监听程序”错误
在用PL/SQL Developer连接数据库时出现“ORA-12541:TNS:无监听程序”错误. 1.检查listener.log日志发现下面错误:TNSLSNR for 32-bit Windo ...
- 6.nuget安装C#Driver驱动ZooKeeperNet
一: C# 的Drivers 1. nuget上下载 zookeeper.Net IWatcher是什么?: client 连接到 server 后,会在server上面注册一个watcher ...
- PG数据库错误: 检测到OA幸运飞艇源码ShareLock死锁处理
PostgreSQL 是一个免费数据库,OA幸运飞艇源码下载,详情咨询[企娥166848365]对于处理分析型+交易型混合型系统来说确实很不错,特别是版本的升级到11.2后性能提升很多,很多运行机制跟 ...