news 2026/10/28 3:51:18

施耐德M580与ATV930以太网通讯实战:Modbus TCP与EtherNet/IP双协议避坑指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
施耐德M580与ATV930以太网通讯实战:Modbus TCP与EtherNet/IP双协议避坑指南

简介:本资源是一份面向工业自动化工程师、PLC与变频器调试人员及高校控制类专业学生的实操型技术实验指导文档,聚焦施耐德M580 PLC与ATV930变频器的以太网通讯核心能力训练,解决Modbus TCP/IP与Ethernet/IP双协议现场集成中的配置差异、端口识别、参数设置及在线调试等典型问题。文档为单文件Word格式(.docx),共1个文件,大小3.55MB,内容结构完整,涵盖实验目的、设备清单、M580与ATV930硬件端口详解(含RJ45功能区分)、SoMove中关键通讯参数配置步骤(如IP分配、参考频率通道设定、组合控制模式启用)、以及两大通讯协议的分步实现流程(含READ_VAR/WRITE_VAR调用、硬件组态与安全解锁操作)。目前已有4415人学习下载,读者可直接复现实验环境,掌握从物理接线、IP规划、变频器参数固化到PLC程序块调用的全链路调试方法,显著提升工业以太网通信工程实施能力。

1. 施耐德M580与ATV930以太网通讯:不是配通IP就完事,Modbus TCP和EtherNet/IP双协议实操中真正卡住人的,是地址映射错一位、I/O Scanner没激活、DTM加载失败这三类“静默故障”

你手上有台BME H58 2040 PLC,一台ATV930U07M3变频器,网线插好了,IP也设对了(192.168.1.9 ↔ 192.168.1.99),可PLC里READ_VAR始终读不到%MW0的值,动态表里状态字一直停在0x50不动,转速死活上不去——这不是网络不通,而是通讯链路在协议层以下就断了。这份《M580与ATV930以太网通讯实验》文档,本质是一份带完整参数快照、寄存器映射表、功能块填参逻辑和DTM加载路径的“可执行故障树”。它不讲Modbus TCP和EtherNet/IP的OSI七层对比,只告诉你:当WRITE_VAR的EMIS指向%MW10:2时,ATV930的8501控制字必须对应“启动+正转+本地/远程切换”三位有效位;当用DTM浏览器添加Modbus Device时,“设备类型”下拉框里根本不会出现ATV930,除非你提前在SoMove里导出并手动注册了正确的EDS文件。实验耗时标称30分钟,但真实场景中,80%的调试时间花在确认“M580本体以太网口编号是0.0.3而非0.0.0”“ATV930的I/O Scanner默认启用但需断电重启才生效”“%MW10写入0x0006后必须再写0x0007才能完成启动握手”这三个反直觉细节上。适合刚接手施耐德中大型传动项目的现场工程师、院校自动化实验室带教老师,以及正在为产线升级做通讯方案预验证的系统集成商——你要的不是理论正确性,而是下一秒就能让电机转起来的确定性。

2. Modbus TCP/IP通讯落地:从READ_VAR/WRITE_VAR填参到I/O Scanner直连,两种路径的寄存器映射逻辑与硬件约束

2.1 为什么必须先解锁M580以太网端口的安全服务?

M580默认启用“安全访问控制”,所有远程读写请求(包括READ_VAR/WRITE_VAR)会被拦截,现象是功能块Q输出始终为FALSE,ERROR=16#8001(访问被拒绝)。这不是IP冲突或防火墙问题,而是固件级策略。操作路径:硬件组态 → 双击CPU以太网端口 → “安全”标签页 → 点击“解锁安全” → 勾选“允许所有服务”和“允许所有访问”。注意:此操作需在下载程序前完成,且重启PLC后该设置不会丢失(区别于部分旧型号需每次重置)。解锁后,端口会开放TCP 502(Modbus)、44818(EtherNet/IP)、2222(Unity Pro调试)三个关键端口。若跳过此步,后续所有寄存器读写均返回超时,但日志无明确报错,极易误判为物理链路故障。

2.2 READ_VAR/WRITE_VAR功能块参数填法:ADR、NUM、RECP/EMIS的物理意义拆解

文档中ADR='ADDM('0.0.3{192.168.1.99}')'这一写法常被新手复制粘贴却不知其义。这里拆解三层含义:

  • 0.0.3:M580 CPU本体集成以太网口的硬件标识符,非IP地址。M580机架槽位编号规则为机架号.模块号.通道号,而CPU内置网口固定为0.0.3(0=主背板,0=CPU模块,3=以太网通道)。若误填为0.0.0,功能块将尝试访问不存在的模块,ERROR=16#801A(模块未找到)。
  • {192.168.1.99}:ATV930的IPv4地址,必须与SoMove中设置的“固定IP”完全一致,且子网掩码需匹配(文档要求255.255.255.0)。若PLC侧IP为192.168.1.9而变频器为192.168.2.99,PING通但Modbus事务失败,因ARP解析失败。
  • ADDM():地址描述宏,告诉PLC“这是一个远程设备地址”,不可省略括号。

NUM(起始地址)和NB(数量)需严格对应ATV930的Modbus寄存器布局。文档给出两套方案:

  • 方案A(I/O Scanner映射):NUM=0,NB=2。此时PLC读写的是ATV930内部I/O Scanner缓冲区,该缓冲区已预定义映射关系(%MW0→状态字、%MW1→输出转速)。优点是无需查寄存器手册,缺点是灵活性低,仅支持固定4个字(状态/转速/控制/给定)。
  • 方案B(直连Modbus寄存器):NUM=3201(状态字)、8501(控制字)、8502(频率给定),NB=1或2。此时PLC直接操作ATV930底层寄存器,需在SoMove中将“Modbus地址”设为3(对应ADR末尾追加3,即ADDM('0.0.3{192.168.1.99}3')),且寄存器地址为十进制(3201=0x0C81)。常见错误是混淆十进制与十六进制,如将3201误输为0xC81,导致功能块报ERROR=16#8021(地址无效)。

2.3 RECP与EMIS的内存分配陷阱:为什么%MW0:2必须连续,而GEST要预留4字?

RECP(接收地址)和EMIS(发送地址)定义PLC内存中用于暂存数据的区域。文档要求%MW0:2(即%MW0和%MW1两个连续字)存放读取结果,%MW10:2存放写入数据。此处有硬性约束:

  • 连续性强制:Modbus TCP帧要求数据块在内存中物理连续。若%MW0和%MW1之间被其他变量占用(如%MW0为状态字,%MW1被定义为温度值),READ_VAR将读取错误数据或触发总线错误。解决方案:在变量表中将相关变量声明为数组,如Status_Speed : ARRAY[0..1] OF WORD;,然后RECP=Status_Speed。
  • GEST(交换数据管理区)的4字玄机:GEST是READ_VAR/WRITE_VAR内部使用的临时缓冲区,用于存储事务ID、协议头等元数据。文档要求%MW100:4和%MW104:4,是因为每个功能块需独立GEST区,且最小单位为4个WORD(8字节)。若GEST空间不足,功能块Q输出为FALSE,ERROR=16#8032(资源不足)。实测发现,即使只读1个字,GEST也必须分配4字,这是Unity Pro编译器的硬编码规则,无法绕过。

2.4 I/O Scanner配置验证:如何确认ATV930的I/O映射已生效?

I/O Scanner是ATV930将Modbus寄存器自动映射到内部数据区的机制,但必须断电重启才能激活。现象是:SoMove中已设置“参考频率通道1=嵌入式以太网”“控制模式=组合通道”,但PLC读取%MW0始终为0x0000。排查步骤:

  1. 在SoMove中进入“诊断”→“I/O Scanner状态”,查看“Scanner运行状态”是否为“运行中”;
  2. 若显示“停止”,则必须关闭ATV930主电源(非仅控制电源),等待10秒后重新上电;
  3. 重启后,在SoMove“参数列表”→“通信”→“端口-Modbus TCP/以太网IP”→“I/O Scanner配置”中,确认“输入映射”指向3201(状态字)、3202(输出转速),“输出映射”指向8501(控制字)、8502(频率给定);
  4. 最终验证:用PC端Modbus Poll工具(IP=192.168.1.99,Port=502,Unit ID=3)读取寄存器3201,应返回非零值(如0x0050表示就绪)。只有此步成功,PLC侧READ_VAR才能获取有效数据。

3. EtherNet/IP通讯实现:从Explicit Message配置到Class 3连接,为何CIP连接比Modbus更难调通?

3.1 EtherNet/IP与Modbus TCP的本质差异:连接导向 vs 事务导向

Modbus TCP是无连接协议,每次READ_VAR都发起新TCP连接,发送请求帧后等待响应,失败即重试。而EtherNet/IP基于CIP(Common Industrial Protocol),必须建立持久化连接。M580作为Scanner(主站),ATV930作为Adapter(从站),需先完成三次握手:

  1. Register Session:M580向ATV930的TCP 44818端口发送会话注册请求,获取Session Handle;
  2. Forward Open:使用Session Handle发起连接请求,指定I/O数据长度、RPI(Requested Packet Interval)等参数;
  3. I/O Data Exchange:连接建立后,周期性交换数据(如每10ms更新一次控制字)。
    若跳过Forward Open或RPI设置过大(如1000ms),PLC会持续报ERROR=16#8045(连接超时),但网络层PING仍正常。这是EtherNet/IP调试中最易被忽略的底层逻辑。

3.2 Explicit Message功能块配置:Target IP与Connection Path的双重校验

文档中EtherNet/IP实验使用Explicit Message功能块(而非Modbus的READ_VAR),其参数需同时满足网络层和应用层要求:

  • Target IP:必须为ATV930的IP地址(192.168.1.99),与Modbus一致;
  • Connection Path:格式为1,0,1,0,0,0,其中:
    • 1,0:表示“端口标识符”,ATV930固定为1(以太网端口);
    • 1,0:表示“连接类型”,1=Explicit(显式消息),0=Class 3(面向连接);
    • 0,0:表示“目标设备对象实例”,ATV930的Adapter对象实例为0。
      若Connection Path错误(如误填为1,0,2,0,0,0),功能块返回ERROR=16#805A(路径无效),且不会触发重连。实测发现,ATV930的Connection Path必须严格按文档填写,任何字段偏差都会导致连接失败。

3.3 CIP Class 3连接的RPI设置:为什么10ms比100ms更可靠?

RPI(Requested Packet Interval)是EtherNet/IP连接的核心参数,定义数据交换周期。文档未明确给出推荐值,但实测经验如下:

  • RPI=10ms:适用于高速控制(如转速闭环),要求网络延迟<1ms。在实验室千兆交换机环境下稳定,但若使用普通五类线或存在其他设备干扰,可能触发“Connection Timeout”;
  • RPI=100ms:通用推荐值,兼容性最强。ATV930的默认RPI为100ms,若PLC侧设为50ms,Adapter会拒绝连接(因无法满足刷新率);
  • RPI=1000ms:仅用于参数配置等低频操作,若用于实时控制,会导致响应迟滞。
    验证方法:在Unity Pro中打开“在线诊断”→“CIP连接状态”,查看“Connection State”是否为“Connected”,“Last Scan Time”是否稳定在设定RPI±10%范围内。若频繁显示“Connecting”或“Faulted”,首要检查RPI匹配性。

3.4 ATV930的EtherNet/IP固件要求:如何确认你的变频器支持该协议?

并非所有ATV930固件版本都支持EtherNet/IP。必须满足:

  • 硬件版本:U07M3及更高型号(含U15M3、U30M3等);
  • 固件版本:≥V2.0(可通过SoMove“诊断”→“系统信息”查看);
  • 许可证:需购买并激活“EtherNet/IP通信选件”(文档中未提及,但实际项目中常被遗漏)。
    若固件过旧,SoMove中“通信”→“端口-EtherNet/IP”选项卡将不显示,或配置后无法保存。升级固件需通过SoMove的“固件更新”功能,且升级过程必须保持24V控制电源稳定,否则变频器将变砖。血泪经验:某项目因使用V1.8固件强行配置EtherNet/IP,导致ATV930反复重启,最终返厂刷写。

4. DTM方式通讯:当图形化配置失效时,如何定位EDS文件缺失、DTM注册失败、在线修改权限不足三大堵点

4.1 DTM浏览器无法识别ATV930的根源:EDS文件未导入或版本不匹配

DTM(Device Type Manager)是施耐德提供的图形化设备管理组件,但其前提是ATV930的EDS(Electronic Data Sheet)文件已注册到Unity Pro。常见现象:点击“DTM浏览器”→“添加设备”,列表为空或仅有Modbus Generic Device。原因及解决:

  • EDS文件缺失:SoMove安装目录下C:\Program Files\Schneider Electric\SoMove\EDS中应存在ATV930_*.eds文件(如ATV930_V2.0.eds)。若不存在,需从施耐德官网下载对应固件版本的EDS包,解压后手动复制到该目录;
  • EDS版本不匹配:ATV930固件为V2.1,但导入的是V2.0 EDS,DTM会拒绝加载。验证方法:用文本编辑器打开EDS文件,搜索Revision="2.1"确认版本号;
  • 注册未生效:复制EDS后,需重启Unity Pro,否则缓存未刷新。实测发现,即使EDS存在,若Unity Pro未重启,DTM浏览器仍无法识别设备。

4.2 DTM设备添加后的“灰色参数”:为什么在线修改控制字被禁用?

成功添加ATV930 DTM设备后,双击设备图标打开参数界面,常发现“控制字”“频率给定”等关键参数呈灰色不可编辑。这是因为:

  • 在线修改权限未开启:SoMove中需进入“参数列表”→“通信”→“端口-Modbus TCP/以太网IP”→“在线修改”,勾选“允许在线修改参数”;
  • PLC与PC连接方式错误:文档强调“若想在线修改DTM,PC和PLC必须通过网线连接”。若当前使用Mini USB电缆连接PLC,DTM的在线修改功能将被禁用,参数始终只读。必须改用网线连接PC与M580的RJ45端口(如192.168.1.10↔192.168.1.9),并在Unity Pro中“PLC”→“连接”选择“以太网连接”。
  • 用户权限不足:SoMove中需以“Administrator”角色登录,普通用户无法启用在线修改。

4.3 DTM与I/O Scanner的耦合关系:修改DTM参数后为何PLC读数不变?

DTM配置的参数(如I/O映射地址)需同步到ATV930的I/O Scanner,但该同步非实时发生。现象是:在DTM中将“输入映射”改为3205(自定义寄存器),但PLC读取%MW0仍为原3201的值。解决步骤:

  1. 在DTM参数界面修改后,点击“下载到设备”按钮(图标为向下箭头),将配置写入ATV930 RAM;
  2. 必须断电重启ATV930,使I/O Scanner重新加载映射表;
  3. 重启后,在SoMove“诊断”→“I/O Scanner状态”中确认“输入映射地址”已更新为3205;
  4. 此时PLC侧READ_VAR的NUM参数也需同步改为3205,否则读取位置错误。
    此过程暴露了DTM的“配置-下载-重启”三步强依赖,任何一步遗漏都会导致PLC与变频器数据视图不一致。

4.4 DTM调试中的“假成功”陷阱:状态字显示0x0050但电机不转的深层原因

DTM界面中“状态字”显示0x0050(二进制000001010000),表示“就绪、无故障、本地控制”,看似正常,但给定转速后电机无反应。此时需穿透DTM看底层:

  • 检查控制模式:SoMove中“命令和参考”→“控制模式配置”必须为“组合通道模式”,若为“独立通道模式”,则以太网通道被禁用;
  • 验证控制权归属:状态字bit4(0x0010)为1表示“远程控制有效”,但若ATV930面板上的“LOC/REM”拨码开关置于“LOC”(本地),则bit4强制为0,即使PLC写入控制字也无法生效;
  • 确认动力电源:状态字bit0(0x0001)为1仅表示“主回路供电正常”,但若接触器未吸合或熔断器烧毁,电机仍无法启动。需用万用表实测ATV930输出端U/V/W相间电压。
    DTM的图形化界面掩盖了这些硬件层状态,调试时必须养成“DTM看逻辑、SoMove查参数、万用表量电压”的三层验证习惯。

5. 避坑:Modbus TCP与EtherNet/IP通讯中5类高频翻车现场及根因修复

提示:以下问题均来自真实产线调试记录,非理论推测。每条均按“现象→原因→解决”结构编写,可直接对照排查。

5.1 现象:PLC下载程序后,READ_VAR功能块Q输出始终为FALSE,ERROR=16#8021

原因:NUM参数输入了十六进制地址(如0xC81),但Unity Pro的READ_VAR要求NUM为十进制整数。0xC81=3201,若直接填0xC81,编译器将其解释为十进制12,导致访问非法寄存器。
解决:在NUM字段输入纯数字3201,禁止添加0x前缀。若需快速转换,可用Windows计算器“程序员模式”进行进制切换。

5.2 现象:ATV930在SoMove中显示“I/O Scanner运行中”,但PLC读取%MW0恒为0x0000

原因:ATV930的I/O Scanner虽运行,但其映射的Modbus地址与PLC功能块ADR中指定的Unit ID不匹配。文档中ADR='ADDM('0.0.3{192.168.1.99}3')'的3是Unit ID,而SoMove中“Modbus地址”必须设为相同值(3),否则ATV930拒绝响应。
解决:在SoMove“参数列表”→“通信”→“端口-Modbus TCP/以太网IP”→“常规设置”中,确认“Modbus地址”=3;若为其他值(如1),则需同步修改ADR为ADDM('0.0.3{192.168.1.99}1')。

5.3 现象:使用DTM添加ATV930后,设备图标显示“离线”,右键“连接”无响应

原因:PC与M580的以太网连接未在Unity Pro中激活。DTM依赖Unity Pro的底层连接服务,若Unity Pro中“PLC”→“连接”未选择“以太网连接”并点击“连接”,DTM无法建立通道。
解决:在Unity Pro菜单栏“PLC”→“连接”→选择“以太网连接”→输入M580 IP(192.168.1.9)→点击“连接”;确认右下角状态栏显示“Connected”。

5.4 现象:EtherNet/IP通讯中,Explicit Message功能块ERROR=16#8045,但PING和端口扫描(nmap -p 44818)均正常

原因:ATV930的EtherNet/IP服务未启用。SoMove中“通信”→“端口-EtherNet/IP”→“启用”必须勾选,且“IP分配模式”需为“固定地址”(DHCP模式下EtherNet/IP可能不工作)。
解决:在SoMove中启用EtherNet/IP服务,设置固定IP,重启ATV930;重启后用Wireshark抓包,过滤ethernetip,确认有Forward Open请求发出。

5.5 现象:PLC写入%MW10=0x0006(启动)后,%MW0状态字bit0(运行中)始终为0

原因:ATV930的“启动使能”功能未激活。SoMove中“参数列表”→“完整设置”→“命令和参考”→“启动使能”必须设为“嵌入式以太网”,否则控制字bit0(启动)被忽略。
解决:在SoMove中设置“启动使能=嵌入式以太网”,断电重启ATV930;重启后,写入0x0006应触发bit0置1,状态字变为0x0051。

6. 进阶验证技巧:用Wireshark抓包定位协议层故障,以及三步法固化通讯可靠性

6.1 Wireshark抓包实战:如何从Modbus TCP帧中一眼定位地址错位?

当PLC与ATV930通讯异常,PING通但功能块失败时,Wireshark是终极验证工具。操作步骤:

  1. 在PC上安装Wireshark,选择M580连接的网卡;
  2. 设置捕获过滤器:ip.addr == 192.168.1.9 and ip.addr == 192.168.1.99 and tcp.port == 502;
  3. 启动捕获,触发PLC中READ_VAR执行;
  4. 停止捕获,查找Modbus TCP请求帧(Function Code=03,Read Holding Registers);
  5. 展开“Modbus Application Protocol”,查看“Starting Address”字段值。若此处显示0x0000,说明NUM=0配置正确;若显示0x0C81(3201),则NUM=3201配置生效;若显示0x000C(12),则NUM被误设为12。
    关键洞察:Wireshark显示的地址是ATV930接收到的实际请求地址,与PLC程序中NUM值完全一致。若抓包看到地址正确但无响应,则问题在ATV930侧(如Unit ID不匹配、I/O Scanner未启);若地址错误,则PLC程序填参有误。

6.2 三步法固化通讯可靠性:从单次通到长期稳的工程实践

单次通讯成功不等于产线可用。我经手的12个施耐德传动项目中,7个在试运行阶段暴露出隐性故障。为此总结出三步法:
第一步:压力测试
用Unity Pro的“强制表”循环修改%MW11(频率给定)为0→1500→0→1500,间隔100ms,持续1小时。观察:

  • %MW0状态字是否始终在0x0050/0x0051间切换(无0x0000意外出现);
  • 动态表中%MW1(输出转速)是否跟随给定值变化,无跳变或停滞;
  • PLC CPU负载是否稳定在<40%,避免高负载导致通讯中断。

第二步:断网恢复验证
手动拔掉M580与ATV930间网线10秒后插回。观察:

  • READ_VAR/WRITE_VAR是否在30秒内自动恢复(Modbus TCP需重连,EtherNet/IP需重连+Forward Open);
  • 恢复后%MW0状态字是否为0x0050(就绪),而非0x0000(初始化中);
  • 若恢复失败,检查PLC程序中是否添加了“连接状态监控”逻辑(如用%SW500读取连接状态),并在断线时触发报警。

第三步:固件与配置双备份

  • 固件备份:用SoMove导出ATV930完整配置(.sop文件),包含所有参数、I/O映射、通讯设置;
  • PLC备份:Unity Pro中“项目”→“导出”→选择“完整项目”,生成.zip包;
  • 网络配置备份:记录M580所有IP(主地址、A/B地址)、ATV930 IP、子网掩码、网关,存为txt文件。
    某项目曾因ATV930固件损坏,靠备份.sop文件30分钟内恢复全部参数,避免产线停机8小时。

从那以后我每次交付施耐德传动项目,都强制走一遍这三步:压力测试跑满1小时、断网恢复测3次、固件配置双备份存三处。不是信不过文档,而是信得过自己亲手验证过的确定性。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/28 3:51:18

caveman:用bash、rsync和SQLite打造可解释可离线的极简自托管系统

把时间往前推一年&#xff0c;我还在老老实实当一名“现代工具党”。家里一台吃灰多年的旧笔记本&#xff0c;被我翻出来塞了四五个自托管服务&#xff0c;觉得这样就叫“数字生活”。结果更新一次就坏一次&#xff0c;某个深夜我看着满屏的systemd报错&#xff0c;差点把键盘砸…

作者头像 李华
网站建设 2026/10/28 3:50:39

LeetCode哈希表高频考点解析与实战技巧

1. LeetCode Hot 100哈希专题解析哈希表作为算法面试中的高频考点&#xff0c;在LeetCode Hot 100题目中占比超过20%。这个数据结构之所以备受面试官青睐&#xff0c;是因为它完美体现了计算机科学中经典的时空权衡思想——用O(1)的平均时间复杂度换取O(n)的空间开销。在实际解…

作者头像 李华
网站建设 2026/10/28 3:50:37

MySQL数据库环境搭建与优化实战指南

1. MySQL入门&#xff1a;从零开始搭建数据库环境对于刚接触MySQL的新手来说&#xff0c;最令人头疼的往往不是SQL语法本身&#xff0c;而是环境搭建过程中的各种"坑"。我在过去五年带过上百个数据库新人&#xff0c;发现90%的初学者都会在环境配置阶段浪费至少3小时…

作者头像 李华
网站建设 2026/10/28 3:50:26

Docker镜像管理故障排查与应急处理指南

1. Docker镜像管理故障的典型场景与应急思路在容器化部署环境中&#xff0c;镜像管理故障往往表现为以下几种典型症状&#xff1a;镜像拉取失败&#xff08;HTTP 404/500错误&#xff09;镜像层校验不通过&#xff08;digest mismatch&#xff09;存储驱动导致的镜像损坏&#…

作者头像 李华
网站建设 2026/10/28 3:50:19

KEYMOS eMMC 5.1 国产方案:HS400与RPMB实战避坑指南

简介&#xff1a;本资源为KEYMOS品牌eMMC 5.1嵌入式存储芯片的官方技术规格书&#xff08;Datasheet&#xff09;&#xff0c;面向嵌入式系统工程师、硬件开发人员及存储方案设计者&#xff0c;用于选型评估、原理图设计、PCB布局与驱动适配。文档完整涵盖128GB&#xff08;KE1…

作者头像 李华
网站建设 2026/10/28 3:50:19

马尾发型不伤头皮:从发圈选择到拉扯性脱发预防全攻略

早上八点通勤路上&#xff0c;在电梯里照见自己的头发塌在肩膀上&#xff0c;有多少人会下意识抬手把头发薅成一个马尾&#xff1f;马尾大概是所有发型里最被低估的那个&#xff1a;不需要烫染、不需要卷棒、三秒钟就能出门&#xff0c;还能顺便把前一天没洗头的尴尬遮掉七成。…

作者头像 李华