当前位置: 首页 > web >正文

STM32F4芯片RS485使用记录

STM32与RS485通信技术概述

  • RS485标准简介:差分信号、半双工通信、多点通信优势
  • STM32微控制器支持的外设:USART/UART与RS485的硬件连接需求
  • 典型应用场景:工业控制、传感器网络、长距离数据传输

硬件配置要求:

  • USART2配置为波特率9600,8数据位,无奇偶校验,1停止位
  • GPIO控制RS485收发方向(如PA1作为DE/RE控制引脚),却决于硬件如何连接不一定是PA1也可以是其他引脚。
    在这里插入图片描述

SP3485引脚功能说明

SP3485是一款低功耗半双工RS-485收发器芯片,以下是其8个引脚的详细功能:

引脚1(RO)
接收器输出端。将总线上的差分信号转换为TTL电平信号输出至控制器
数据流是:RS485_TXD -> MCU_UART2_PA3_RXD。器件要属于发送模式。

引脚2(RE#)
接收使能端(低电平有效)。当该引脚为低时,接收器处于工作状态;为高时接收器输出高阻态。

引脚3(DE)
驱动器使能端(高电平有效)。当该引脚为高时,驱动器处于工作状态;为低时驱动器输出高阻态。
总结:
RE 引脚跟 DE引脚是两个控制引脚,RE是低电平有效,当它为低电平时候,接收器处于工作状态,一般在发送完成数据后我们要立即设置成接收模式,就会设置这个引脚变成低电平。同样的,DE如果设置成高电平,驱动器处于工作状态,就是可以发送数据,所以我们会在发送数据前,拉高DE管脚,发送数据后我们会拉低RE引脚。
思考:为什么两个引脚要接在一起。
将SP3485的2脚(DE,驱动器使能)和3脚(/RE,接收器使能)通过跳线或直接焊接短接。这种连接方式使得两个控制引脚同步工作:
DE为高电平时,/RE也为高电平(由于两者短接),此时芯片处于发送模式。对应的MCU就是接收数据。
DE为低电平时,/RE也为低电平,芯片处于接收模式。对应的MCU就是发送数据,写代码的时候要特别注意。
这是AI写的一个代码 大概是这个意思,通过一个IO进行模式的切换。
// 发送数据前
HAL_GPIO_WritePin(DE_RE_GPIO_Port, DE_RE_Pin, GPIO_PIN_SET); // 使能发送
// 发送完成后
HAL_GPIO_WritePin(DE_RE_GPIO_Port, DE_RE_Pin, GPIO_PIN_RESET); // 切换为接收

引脚4(DI)
驱动器输入端。将控制器的TTL电平信号转换为差分信号输出至总线。
数据流是:MCU_UART2_PA2_TXD-> RS485_TXD。器件要处于接收模式。

引脚5(GND)
电源地。所有信号参考的公共地线。

引脚6(A)
总线正端。RS-485差分信号的正向传输线,需接120Ω终端电阻。

引脚7(B)
总线负端。RS-485差分信号的负向传输线,需接120Ω终端电阻。

引脚8(VCC)
电源正极。典型工作电压范围为3.0V至3.6V,最大不超过3.6V。

典型连接注意事项

  • RE#和DE引脚可并联控制,半双工模式下通常由同一GPIO控制
  • A/B总线建议串联22Ω电阻并增加TVS二极管防护
  • 空闲状态下,RO输出高电平(总线A>B时输出高,A<B时输出低)
  • 芯片静态电流典型值300μA,适合低功耗应用场景

失效保护特性

当总线开路/短路时,RO引脚会保持高电平输出,避免不确定状态。驱动器的短路电流限制可防止总线冲突损坏器件。

以下是基于STM32F407VGT6的配置代码,使用ST标准库实现USART2(PA2-TX, PA3-RX)与485芯片通信,通过PG8控制RE/DE引脚,并利用空闲中断和接收中断完成数据收发。
USART2与GPIO初始化
#include “stm32f4xx.h”
#include “stm32f4xx_gpio.h”
#include “stm32f4xx_rcc.h”
#include “stm32f4xx_usart.h”

#define RE_DE_PIN GPIO_Pin_8
#define RE_DE_PORT GPIOG

void GPIO_Configuration(void) {
GPIO_InitTypeDef GPIO_InitStruct;

// 使能GPIO和USART时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOG, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);// 配置PA2(TX), PA3(RX)为复用功能
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2);// 配置PG8(RE/DE)为推挽输出
GPIO_InitStruct.GPIO_Pin = RE_DE_PIN;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(RE_DE_PORT, &GPIO_InitStruct);
GPIO_ResetBits(RE_DE_PORT, RE_DE_PIN); // 默认接收模式

}

void USART2_Configuration(void) {
USART_InitTypeDef USART_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;

USART_InitStruct.USART_BaudRate = 115200;
USART_InitStruct.USART_WordLength = USART_WordLength_8b;
USART_InitStruct.USART_StopBits = USART_StopBits_1;
USART_InitStruct.USART_Parity = USART_Parity_No;
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART2, &USART_InitStruct);// 使能接收中断和空闲中断
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
USART_ITConfig(USART2, USART_IT_IDLE, ENABLE);// 配置NVIC
NVIC_InitStruct.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);USART_Cmd(USART2, ENABLE);

}

中断服务函数与模式切换
volatile uint8_t RxBuffer[256];
volatile uint16_t RxIndex = 0;
volatile uint8_t RxFlag = 0;

void USART2_IRQHandler(void) {
if (USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) {
RxBuffer[RxIndex++] = USART_ReceiveData(USART2);
USART_ClearITPendingBit(USART2, USART_IT_RXNE);
}

if (USART_GetITStatus(USART2, USART_IT_IDLE) != RESET) {USART_ReceiveData(USART2); // 清除IDLE标志RxFlag = 1; // 标记数据接收完成USART_ClearITPendingBit(USART2, USART_IT_IDLE);
}

}

void Set_485_TxMode(void) {
GPIO_SetBits(RE_DE_PORT, RE_DE_PIN); // RE/DE=1: 发送模式
}

void Set_485_RxMode(void) {
GPIO_ResetBits(RE_DE_PORT, RE_DE_PIN); // RE/DE=0: 接收模式
}

数据发送函数
void USART2_SendData(uint8_t *data, uint16_t len) {
Set_485_TxMode(); // 切换至发送模式
for (uint16_t i = 0; i < len; i++) {
USART_SendData(USART2, data[i]);
while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);
}
while (USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET); // 等待发送完成
Set_485_RxMode(); // 切换回接收模式
}

主函数示例
int main(void) {
GPIO_Configuration();
USART2_Configuration();

while (1) {if (RxFlag) { // 接收到完整数据帧RxFlag = 0;// 处理RxBuffer中的数据...USART2_SendData((uint8_t *)RxBuffer, RxIndex); // 回传数据RxIndex = 0; // 重置接收索引}
}

}

关键配置说明

485模式控制:PG8引脚高电平为发送模式,低电平为接收模式,通过Set_485_TxMode()和Set_485_RxMode()切换。
中断机制:USART_IT_RXNE中断逐字节接收数据,USART_IT_IDLE中断检测帧结束。
数据缓冲:使用RxBuffer存储接收数据,RxFlag标记帧接收完成。
波特率:示例设置为115200,可根据实际需求修改USART_InitStruct.USART_BaudRate。

使用时需在工程中包含STM32F4标准库头文件,并确保中断优先级配置合理。

在这里插入图片描述

http://www.xdnf.cn/news/20473.html

相关文章:

  • 小迪自用web笔记29
  • 少儿配音教育:广州声与色在线科技有限公司打造趣味课程,助力青少年语言能力提升
  • 电脑外接显示屏字体和图标过大
  • 实体商业创新观察:AI 驱动的本地生活服务新模式解析
  • 计算机网络:物理层---物理层的基本概念
  • OpenSSL 1.0.1e 下载解压和运行方法(小白适用 附安装包)​
  • Nginx性能调优:参数详解与压测对比
  • 小孔成像原理
  • 吴恩达机器学习(九)
  • 正态分布 - 正态分布的标准化
  • 音视频技术全景:从采集到低延迟播放的完整链路解析
  • 【鸿蒙 NEXT】V1迁移V2状态管理
  • VMWare和centOS的安装
  • 集成学习 —— 梯度提升树GBDT、XGBoost
  • Javaweb 14.4 Vue3 视图渲染技术
  • 【MySQL | 高级篇 分片规则与管理监控】
  • 从Java全栈到前端框架的全面实战:一次真实面试的深度解析
  • c++ sqlite3库
  • CentOS下Bind服务的安装与故障排查
  • pyAutoGUI 模块主要功能介绍-(1)鼠标功能
  • 从 Excel 趋势线到机器学习:拆解 AI 背后的核心框架​
  • 数位DP -
  • 【明道云】[工作表控件11] 地理位置控件与地图定位应用
  • 用内存顺序实现 三种内存顺序模型
  • 安装es和kibana
  • Linux之Firewalld防火墙实战篇
  • [光学原理与应用-435]:晶体光学 - 晶体的结构-基元/原胞/晶胞/点阵
  • 多次base64编码过滤垃圾字符
  • 讲一下模版特化和偏特化的区别
  • 如何在Kali Linux官网下载历史版本