简介:本资源是一套基于STM32F103微控制器的RS-485通信实战实验工程,面向嵌入式初学者、高校电子类专业学生及工业通信入门开发者,聚焦解决UART转RS-485硬件接口设计、半双工通信控制与工业总线协议实践等核心问题。压缩包共84个文件,含38个头文件(.h)定义外设驱动与协议结构、37个源文件(.c)实现USART配置、MAX485收发切换逻辑、中断处理及主从通信流程,另有Keil工程文件(.uvprojx/.uvoptx)、启动代码(.s)、调试配置(.ini)、可执行固件(.hex)及说明文档(.txt),整体体积仅368KB,结构清晰、模块分离度高。已有110人下载学习,配套完整Keil MDK工程,开箱即用,涵盖GPIO方向控制、UART波特率精确配置、DE/RE引脚时序管理、终端电阻匹配要点及抗干扰调试提示,是理解工业级RS-485物理层与MCU协同控制的典型教学范例。 我直接做了个485总线控制的项目,板子用的是STM32F103,从硬件电路到软件协议全走了一遍,中间踩了不少坑。这篇就当作一个实战笔记来写,内容覆盖485通信原理、自动收发电路设计、STM32F103的UART配置、Modbus协议实现,以及几个工业场景下的真实案例,适合正在做485通信开发、或者想把老设备接入总线控制系统的朋友参考。不同基础的人都能从里面拿到自己需要的东西,新手可以照着电路和代码跑通,老手可以看看我在时序和波形上踩过的坑。
1. 项目背景:为什么选了485而不是CAN或者以太网
这个项目最初的诉求特别简单:想用上位机远程控制一台变频器的启停和频率,同时读回电机的实时电流和转速。按理说现在工业上CAN和以太网已经很普及,但在单点对多点、距离几十米到一千米、节点数量几十个以内、成本还要压到最低的场景里,RS-485依然是性价比最高的选择。
485是差分信号传输,两个线分别标A和B,靠它们之间的电压差来判断逻辑电平。A比B高就是逻辑1,反过来就是逻辑0。这和UART的TTL电平完全不同,TTL是单端信号,靠对地电压判断高低,抗干扰能力差,传输距离也短。RS-485接收端输入阻抗很高,所以一条总线上可以挂很多设备,标准情况下是32个节点,如果用低负载的收发器可以挂更多。
我在这个项目里还考虑了另一个原因:485协议栈非常成熟。Modbus RTU是工业领域的事实标准,几乎所有PLC、变频器、温控器、电表都支持,这意味着我做的控制板以后对接其他设备的时候,不需要重新发明协议,直接套Modbus就行。而且485是半双工,虽然速率没有CAN那么高,但在工控场景下,9600和19200波特率已经足够用了。
功耗也是一个考量点。485收发器静态电流很小,很多型号都是微安级别,非常适合做低功耗的采集终端。相比之下,CAN收发器的功耗要高一些,以太网的PHY芯片就更不用说了。
还有一个很现实的原因:485只需要两根线,而且不需要像以太网那样做阻抗匹配的差分对布线,普通双绞线就能跑。在改造老设备接线的时候,线缆成本低,施工也方便。这个项目要接的设备分散在车间不同工位,用485总线拉过去是最省事的方案。
2. 硬件电路设计:STM32F103最小系统和485电路要点
2.1 最小系统的启动配置与时钟
STM32F103最小系统本身不复杂,但BOOT0和BOOT1的配置很容易翻车。BOOT0拉低就是从Flash启动,这是正常运行的模式;如果BOOT0拉高,就会进系统存储器,进入ISP下载模式。BOOT1一般接GND,只有在需要从SRAM启动调试的时候才用到。
晶振我用的是8MHz无源晶振,两个20pF的负载电容分别接地。这个电容值的选择要看晶振手册的CL参数,如果晶振要求的负载电容大,就要适当增大电容值,不然起振困难。我还加了一个1MΩ的反馈电阻并联在晶振两端,帮助稳定起振。实测下来,只要并联匹配电容的容差不过大,这个配置很稳定。
复位电路用的是10kΩ上拉电阻加0.1μF电容到地,复位的低电平时间大概是1ms,足够完成可靠复位。STM32F103的复位时间要求是至少1.5μs,这个电路余量充足。
供电部分我用了一片AMS1117-3.3,输入接5V,输出3.3V给MCU供电。要注意STM32F103的ADC参考电压是VDDA,如果电路里面同时有模拟采集和数字通信,最好把VDDA单独用磁珠和电容做滤波,避免数字噪声影响采样精度。我一开始偷懒没做,ADC读取电机电流的时候纹波非常大,后来加了磁珠才解决。
2.2 485收发器选型和基本电路
485收发器我选了MAX3485,兼容3.3V逻辑电平,可以直接和STM32F103连接,不需要额外的电平转换。市面上常见的SP3485也是同样的引脚定义,可以互换使用。
需要注意的一点是ST公司的L9637D和ISO3082这类隔离型收发器,如果信号隔离做不好,还不如直接上非隔离的。这个项目里电源是统一供电,没有跨设备的长距离跨接,所以我用非隔离的MAX3485就够了。
MAX3485的RO接STM32的RX引脚(PA10),DI接TX引脚(PA9),RE和DE接在一起,由单片机的一个GPIO控制方向。硬件上要特别注意:如果RE和DE是分开控制的,一个不小心就会造成总线冲突,最简单可靠的做法是把它们短接在一起,用一个引脚控制收发方向。
关于PA9和PA10到底哪个是TX、哪个是RX:PA9是USART1_TX,PA10是USART1_RX。很多人第一次用的时候会搞反,以为是PA9收、PA10发。这个搞反的直接后果就是自己发出去的数据自己收到,但对方设备完全没反应。我排查这个问题的时候花了好几个小时,最后用示波器看波形才发现问题所在。
2.3 自动收发电路:省掉一个GPIO的聪明方案
传统485电路必须要用一个GPIO控制收发方向,发送前拉高DE,发送完拉低RE。但有一种自动收发电路可以完全省去这个控制引脚,原理是利用发送数据的起始位和停止位自动切换方向。
电路的核心是:DI引脚通过一个电阻和电容组成的延时网络连接到发送端,发送数据的时候,起始位的低电平会通过RC网络快速拉低DE/RE引脚,进入发送模式;数据发送完毕,总线回到空闲状态,RC网络放电后自动回到接收模式。
这个电路我实测在9600和19200波特率下工作得很稳定,但有一个前提条件:发送字节之间的间隔不能太短,否则RC电容来不及放电复位,会导致下一位数据的前半段还在发送状态,后半段就切回了接收,数据会出错。
自动收发电路的优点是省GPIO,而且软件实现简单,不需要维护方向切换的时序。缺点是对波特率敏感,高速率下(超过115200)RC时间常数不好匹配,而且接收方向切换存在些许延时会丢失第一个字节。如果对成本不敏感、GPIO充足,我还是建议用传统的方向控制方式,更稳妥。
2.4 保护电路:TVS管、PTC和终端电阻
485总线工作在工业现场,静电和浪涌是家常便饭。我在A、B线上各加了一个PESD1CAN的TVS管,管子的阳极接GND、阴极接总线,限制共模电压超过6V时泄放能量。同时还在总线上串联了两个10Ω的PTC自恢复保险丝,防止两个节点间出现持续短路故障时过流损坏收发器。
终端电阻的处理需要注意:如果总线上只有两个设备,两端各加一个120Ω终端电阻。如果设备是菊花链连接的,就在物理最远的两端加终端电阻。如果有设备是星型连接的,不要在那个支线上加终端电阻,否则会破坏总线阻抗匹配,反射信号会更严重。
我在实际项目里发现,很多人在每个节点上都加120Ω终端电阻,结果总线负载太大,信号衰减严重,通信距离稍微长一点就出错。正确做法是只在总线两端各加一个,中间节点不加。
3. 软件实现:STM32F103的UART配置和485驱动
3.1 用标准库还是HAL库
这个项目我用了标准外设库。不是说HAL库不好,而是485这种底层协议对时序要求比较高,标准库的精力集中在寄存器操作上,更容易控制数据发送和方向切换的精确时机。HAL库的优势是代码可移植性好,如果你不想深入研究485时序,用HAL库加CubeMX生成代码也完全够用。
用HAL库有一个好消息:STM32F103的HAL库确实有SDIO的相关例程,但是和485通信没有关系。如果你在找的是485相关的HAL库例程,直接看USART中断和DMA的例程就可以了,485本身没有专门的HAL模块,它本质就是一个UART加方向控制。
3.2 串口参数配置要点
USART1的配置参数:波特率9600、数据位8、停止位1、无校验。这里要注意Modbus RTU协议规定的是8位数据位、无校验或偶校验,不能是9位数据位,否则和标准协议不兼容。
波特率配置有一个坑:STM32F103的USART时钟来自APB2总线,默认是72MHz。波特率寄存器BRR的值算法比较复杂,如果直接用库函数USART_Init就不需要操心;但如果是用寄存器配置,要注意如果USARTDIV的小数部分四舍五入后超出了4位精度,波特率误差会比较大。9600波特率下误差可以忽略,但上升到115200的时候,如果时钟配错了,误差可能高达2%以上,会导致通信不稳定。
我推荐使用内部参考手册里的公式手算一遍,确认最后的波特率误差在±1%以内。比如72MHz时钟下,9600波特率的USARTDIV是750,BRR寄存器写入的十六进制数是0x1D4C,这个值在手册里能找到对应示例,照着核对一遍就知道自己配置是否正确。
3.3 485方向切换的时序处理
用传统方式控制方向时,软件上最容易被忽略的是方向切换的时机。我在代码里是这样处理的:
void RS485_SendData(uint8_t *buf, uint16_t len) { RS485_DIR_HIGH(); // 切换到发送模式 delay_us(5); // 等待收发器完全切换 for(uint16_t i = 0; i < len; i++) { while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); USART_SendData(USART1, buf[i]); } while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET); // 等待发送完成 delay_us(5); // 等待最后一个字节完全发出 RS485_DIR_LOW(); // 切换回接收模式 }这里有两个关键延时:发送前切换方向后要延时5μs,让收发器稳定;发送完最后一个字节后要等TC标志置位,再延时几个微秒,确保移位寄存器里的数据全部发完,才能切换方向。如果切换早了,最后一个字节可能会被截断;切换晚了,总线会被发送器占用太长,对方设备可能超时。
我实测发现,MAX3485的方向切换时间大约在几十纳秒,远小于5μs,所以5μs的延时有很大余量。但如果是用光耦隔离的收发器,切换时间会显著增大,延时就要加到50μs以上。
3.4 Modbus RTU从站实现
Modbus RTU协议的核心是:帧间隔至少3.5个字符时间,地址1字节、功能码1字节、数据若干字节、CRC校验2字节。我实现了一个从站,功能码支持03(读保持寄存器)、06(写单个寄存器)和16(写多个寄存器)。
帧接收用定时器和串口中断配合:串口每收到一个字节就清零定时器,定时溢出时间设为5ms。如果5ms内没有新字节到达,就认为一帧结束。这个时间要大于3.5字符时间(9600波特率下约4ms),所以我选了5ms作为超时阈值。
void USART1_IRQHandler(void) { if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) { uint8_t byte = USART_ReceiveData(USART1); if(rxIndex < RX_BUF_SIZE) { rxBuf[rxIndex++] = byte; } TIM_Cmd(TIM2, DISABLE); TIM_SetCounter(TIM2, 0); TIM_Cmd(TIM2, ENABLE); } }定时器超时中断里处理完整帧,解析地址、校验CRC、分功能码执行、回发响应。CRC计算用查表法,速度很快,在72MHz主频下几微秒就完成了。
3.5 关于PWM输出和CAN通讯
STM32F103的PWM输出和485通信组合是个很常见的搭配。我在这块板子上用TIM3的通道1输出了一路可调频率的PWM,用来控制一个步进电机的速度参考,通过Modbus寄存器改PWM的周期值,就能在线调速。
TIM3的时钟来自APB1,72MHz时钟经过预分频后,ARR寄存器的值决定PWM周期,CCR寄存器的值决定占空比。如果主机通过485下发的频率值是10到200Hz,对应到ARR就是72000000 / 分频 / 目标频率 - 1,这个转换关系在固件里要提前算好,避免溢出和舍入误差。
CAN通讯我也在同一个板子上试过,STM32F103内置了bxCAN控制器,使用PA11(CAN_RX)和PA12(CAN_TX),通过TJA1050收发器接到CAN总线上。485和CAN的区别在于:CAN带硬件帧ID过滤和仲裁机制,多主机通信不用考虑冲突问题;485是单主机轮询机制,所有从站被动等待主站查询。如果设备数量多且数据量大,CAN更合适;如果只是采集仪表数据、控制变频器,485的Modbus协议更通用,调试也简单。
4. 调试工具:485调试助手和总线波形分析
4.1 485调试助手的正确用法
调试485通信,一个趁手的串口调试助手必不可少。我这里说的485调试助手,指的是USB转485的调试工具,电脑端用一个串口助手软件,USB转485模块把TTL信号转成485差分信号挂在总线上。
我推荐的组合是:一个USB转485模块(芯片建议FT232RL加MAX485,不要用CH340的,CH340的驱动在Linux下历史遗留问题多)加一个免费的串口调试助手软件。串口调试助手选支持hex发送、定时发送、带发送时间戳的,我在调试Modbus帧间隔的时候,时间戳功能帮了大忙。
用调试助手模拟主站时,要先把波特率、数据位、停止位、校验位和从站配置一致,然后手动组帧发送。比如读从站地址1的保持寄存器0x0000开始的4个寄存器,报文就是01 03 00 00 00 04 44 09,最后两个字节是CRC。如果从站回帧正确,说明通信基本通了。
4.2 示波器测量总线波形
如果用调试助手收不到回帧,就要上示波器测量A、B线之间的差分波形。标准485信号在空闲状态下,A和B之间是负电压(逻辑1),发送起始位时变成正电压(逻辑0),波形看起来是一个个脉冲。
把示波器探头接在A线上、地接GND,看到的是单端信号;把示波器设成差分模式(或者用两个探头做数学减法),看到的是A-B的差模信号。正常波形应该方波边沿清晰,没有过冲和振铃。如果边沿有振铃,说明终端电阻没加或者总线上有分支;如果波形圆润、幅度低,说明总线负载过重,可能是终端电阻加多了。
用示波器还可以验证波特率:测一个字节的起始位低电平时间,9600波特率下应该是104μs(1/9600秒)。这个测量可以直接判断主站的波特率配置是否正确,排查对方设备波特率设错了的问题。
4.3 逻辑分析仪的8通道物尽其用
我有一台8通道的逻辑分析仪,调试485的时候,把通道0接MCU的TX引脚,通道1接RX引脚,通道2接方向控制引脚DE,三路信号同时抓,就能完整复现一帧数据从产生到发出的整个过程。软件上设置好解码协议为UART,波特率配置正确,逻辑分析仪会自动把波形解码成十六进制数据,省去人工数电平的麻烦。
在分析帧间隔异常的问题时,逻辑分析仪的时间轴单位是ns级,可以精确定位两个字节之间的时间差,排查是否满足Modbus的3.5字符间隔要求。这里我调出过一次很经典的bug:发送完响应帧后,我立刻把方向切回接收,但因为代码里没有等TC标志,实际最后一字节还在移位寄存器里没发完,逻辑分析仪上明显看到response帧的最后一位被截断了。
5. 工业场景案例分析:从PLC到变频器的485通信
5.1 西门子1200 PLC和G120XA变频器485通讯
有个朋友在改造一台老式传送带,原来用的是模拟量调速,他们想升级成通过PLC远程设定速度。方案是西门子1200 PLC通过485通信控制G120XA变频器。
这个方案有几个关键点:G120XA的485接口支持Modbus RTU和USS协议,PLC侧用CM1241 RS485模块,或者用1200的RS485扩展板。接线时A/B不要接反,G120XA的端子定义和国产变频器不完全一样,需要对照手册。G120XA的Modbus地址和西门子的G120略有不同,启动命令是40100,频率设定是40101,状态字是40200。
在PLC里用Modbus指令库,调用MB_COMM_LOAD设置通信参数,再调MB_MASTER发送读写请求。写入频率前要先算好数据格式:G120XA的频率设定是以0.01Hz为单位的16位整数,要写50Hz就发送5000。用MB_MASTER写保持寄存器40101,数据区里填5000即可验证。
这个案例说明了一个通用问题:不同厂家的485设备,寄存器地址和数据类型千差万别,对接前必须先读设备手册确认地址映射,不要想当然。
5.2 欧姆龙E5CC温控器的485设置
欧姆龙E5CC是我调试过的一个温控器,支持RS-485通信,组态软件在电脑上通过485总线可以连多台。E5CC的默认通信参数是9600、8、E、1,注意默认是偶校验,不是无校验。很多人默认选择无校验,结果怎么都连不上,就是这个原因。
E5CC的寄存器地址从0x0000开始,温度读数是保持寄存器0000,目标温度是0002,控制输出0040。在组态软件里把设备地址、波特率、校验方式都配好后,用调试助手读一下温度看看反应,正常几秒钟内就能返回数据。
我在现场遇到过一个很奇怪的问题:用欧姆龙的组态软件能读到温度,但自己的上位机读不到。后来发现组态软件发送的是功能码04(读输入寄存器),返回温度值的单位是0.1℃,而我的上位机发的是功能码03(读保持寄存器),两者的地址空间完全不重合。所以对接温控器第一步就是确认它用的是03功能码还是04功能码,这个和厂家的内部架构有关,没有统一标准。
5.3 三菱FX1N通过485读伺服绝对值编码器位置
三菱FX1N支持485通讯,配合FX1N-485BD板模块,可以走专用协议或者Modbus。我用它读取一台伺服的绝对值编码器位置,接线是FX1N的SDA/SDB接到伺服驱动器的485端口,参数设置里要把PLC和伺服都配成相同的通信ID、波特率和协议。
FX1N读取伺服位置用的是专用指令ADPRW,功能码对应伺服的参数地址。绝对值编码器的位置数据通常是32位,分高位和低位两个寄存器存储,所以一次读取要同时读两个寄存器再拼接。拼接的时候要注意大小端顺序,不同伺服厂家的存储顺序差别很大。我当时排查了一个多小时,发现读回来的值高低位反了,导致位置显示负数,后来把高低位交换才解决。
这个案例的教训是:读取多字节数据,一定要先确认厂家规定的字节序,不要在程序里猜。
5.4 托利多仪表和斯菲尔电表的485地址问题
托利多的称重仪表和斯菲尔的电表在485总线上都有固定的寄存器地址,这里涉及一个很经典的问题:多个同型号设备挂在一条总线上,地址冲突怎么办。
托利多仪表默认地址是1,如果现场有两台托利多,必须通过面板修改其中一台的地址。斯菲尔电表和托利多类似,出厂地址可能相同。我的做法是:先接一台设备,用调试助手发一个广播命令确认它在线并读回当前地址,然后单独修改该设备的地址,改完再换下一台,保证每条总线上同一时间只有一台设备处于可修改状态。
这里要特别强调:修改地址一般用广播地址0或者设备自身地址,操作完成后原始地址就会失效,所以一边改地址一边要同步在标签上标注。我遇到过一个人现场改完地址忘了记录,第二天找不着哪台是几号,只能挨个拔线去摸查,浪费时间。
5.5 电动自行车电路图里的485通讯线
这个属于比较容易混淆的场景。新一代电动自行车的控制器和仪表之间,有的确实是走UART或者485通讯,目的是把速度、电量、故障码这些信息从控制器传到仪表显示。电动自行车电路图上的485通讯线,一般是两根很细的信号线,标有A和B,或者T/R+和T/R-,和动力线一起穿在总成线束里。
如果你要在这个场景里调试,最需要注意的就是:电动自行车的485信号是12V或者5V电平,和STMF103的3.3V TTL不兼容,必须做电平转换,否则直接接上去轻则通信失败,重则烧毁单片机的引脚,我在调试一块48V的电动自行车控制器时遇到过这个问题,后来用了隔离收发器才解决。
6. 常见问题与排查技巧实录
6.1 现象一:收不到任何数据,示波器看总线有波形
这个问题的可能性排序是:接线、波特率、地址、CRC。先用调试助手发一帧,示波器看总线上的波形是否正常。如果波形正常,就查设备地址和功能码设计。如果波形都不正常,就检查A/B有没有接反、终端电阻有没有接对、收发器的电源和地有没有接上。
这里要特别提醒:调试助手的USB转485模块,发送时如果不能正常切换方向,也会导致收不到数据。有些USB转485模块的收发器是自动切换的,它依赖电脑串口发送端的电平变化来切换,有时候电脑端发送数据的间隔太短,模块来不及切换,就会丢数据。换一个带硬件方向控制的手动切换模块,很多问题能迎刃而解。
6.2 现象二:波特率对不上,数据乱码
如果收到的数据是一堆乱码,大概率是波特率配置不一致。这个时候别急着改程序,先用调试助手的自动波特率检测功能试一下,它通过测量起始位宽度算出实际波特率,能快速定位谁配错了。
另外一种可能是晶振频率偏差过大。STM32F103的HSI内部振荡器精度不够,全温度范围内可能有±2%的偏差,如果是用HSI做系统时钟,串口波特率偏差会累积得更大。我建议把所有需要串口通信的设计都改用外部8MHz晶振,不要贪省事用内部时钟。
6.3 现象三:总线挂死,所有从站无响应
这个问题多半是某个节点的485收发器损坏,把A、B线短路了,或者某根线虚接导致总线电平不在有效范围内。逐个拔掉从站的接线,找到导致总线异常的节点;用万用表测A线到B线之间的电阻,正常应该是120Ω左右(两端有终端电阻),如果接近0Ω就是短路,如果开路就要检查终端电阻。
还有一种软件导致的“总线挂死”:某个从站在接收数据后,因为代码bug没有释放方向控制引脚,始终处于发送模式,把总线电平一直拉高。这种问题可以用示波器看总线空闲时的电平,正常的485总线空闲应该是稳定的负电压。
6.4 现象四:多机通信时,某一台从站偶尔响应超时
多从站轮询时响应超时,大概率是超时时间的设置问题。Modbus规定从站必须在接收到请求后的几十到几百毫秒内返回响应,如果从站的某个功能码处理时间较长,比如写EEPROM或者读传感器,主站判断超时的时间就需要相应加长。
我用了一个简单的方法:在主站端用逻辑分析仪记录下发和回帧的时间戳,看真实响应时间。实测发现某些从站在写参数后要50ms才能回下一帧,而主站默认超时只有20ms,就会经常报超时。把主站超时时间调整到200ms后,所有问题都消失了。
6.5 现象五:自动收发电路的“第一个字节丢失”问题
自动收发电路用RC网络去切换方向,在接收模式下,总线上第一个字节的起始位到来时,RC网络需要时间去响应并切换到接收模式,如果这个响应时间过长,第一个字节就会丢失。特别是总线上的第一个数据包,如果对方发送前没有给一段空闲时间,很容易丢。
解决办法有两个:一是调整RC参数,减小电容值,让切换时间缩短;二是协议层面,主站发送前先发若干个0x00字节作为唤醒前导,从站收到前导字节后忽略,从真正的起始标志开始接收。
7. 调试经验总结与个人心得
做485通信项目,最大的体会是:485协议本身很成熟也很简单,真正考验人的往往是硬件细节和现场环境。我项目中几次排查时间最长的故障,最后发现都是很简单的原因——A/B接反、终端电阻加多了、电平不匹配、地址配错了。
给各位几个个人实操中的建议:
第一,485总线的布线一定用双绞线,绞距越小越好。现场干扰大的时候,双绞线能有效抑制共模干扰。走线尽量远离变频器输出线、大电流动力线和大功率开关电源。如果实在躲不开,用屏蔽双绞线,屏蔽层单端接地。
第二,新项目上电前,先用调试助手模拟主站验证通信,再操作自己的控制板。这样可以区分问题是出在上位机还是设备端。
第三,系统里如果有多个从站,先单点调试,每个从站单独测通之后,再挂到一起联调。不要一次性把所有节点接上去,否则找问题就像大海捞针。
第四,建议程序里把CRC校验做扎实。485通信协议本身的错误检测不是特别强,CRC是最后一道防线,不要把CRC的计算做错或者漏掉。我见过有人把CRC的低字节和高字节写反了,结果自己调试能通,换一个主站就完全不通。
这个项目整体做完,我对485通信的可靠性有了比较扎实的认知。485虽然看起来是一个老掉牙的协议,但它在工业现场的生命力远没结束,新的以太网、CAN设备层出不穷,但485凭借其简单、低成本、坚固耐用的特点,在很多老设备改造和小型系统中依然是首选。如果你也在做STM32和其他设备的485通信,希望这篇实战笔记能帮你少走一些弯路。
最后再分享一个上面没提到的小技巧:485总线从站的地址,建议把拨码开关或者EEPROM存储做成可配置,程序启动时读取配置来决定本机地址,这样挂载多个从站时,只需要拨动拨码开关,不需要重新烧录固件。我在项目里就是用两个拨码开关组成了4位地址,最多支持15个从站,现场维护起来特别省心。
本文还有配套的精品资源,点击获取