news 2026/10/7 6:47:01

AS5600磁编码器从选型到FOC闭环的实战避坑指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
AS5600磁编码器从选型到FOC闭环的实战避坑指南

1. 为什么磁编码器值得花时间折腾

如果你正在做云台、无刷电机FOC控制、机械臂关节或者任何需要精确知道"轴转到哪儿了"的项目,那AS5600这个名字你大概率已经见过不止一次了。它是一颗12位分辨率的磁性旋转位置传感器,输出0到4095对应0到360度,通过IIC接口跟主控通信,SSOP-8封装,价格亲民,外围电路简单到令人发指——一颗芯片加一颗径向充磁的磁铁,基本就能跑起来。

但"能跑起来"和"跑得稳、读得准、不丢数据"之间,隔着不少坑。我见过太多人第一次用AS5600的时候,IIC扫不到地址、读出来的角度一直在跳、磁铁位置稍微偏一点数据就废了。这些问题不是芯片的锅,而是磁编码器这个品类本身对机械安装、IIC时序、寄存器配置都有比较具体的要求,而大部分教程只告诉你"接上SDA/SCL就能读",剩下的全靠自己踩。

这篇内容面向的是已经有一定单片机基础、准备把AS5600真正用进项目里的开发者。不管你是用STM32、ESP32还是树莓派,不管你是用硬件IIC还是软件模拟,下面这些从选型、接线、寄存器操作到数据滤波的完整流程,都是我实际项目中反复验证过的。读完你至少能少走两三个晚上的弯路。

2. AS5600核心原理与IIC通信基础拆解

2.1 磁编码器到底在测什么

先把这个东西的物理原理说清楚,不然后面调参你都不知道在调什么。AS5600内部有四个霍尔传感器,呈90度排列在芯片中心周围。当你把一颗径向充磁的磁铁放在芯片正上方并且磁铁中心对准芯片中心时,磁铁的旋转会在四个霍尔传感器上产生相位差90度的正弦信号。芯片内部的DSP把这些模拟信号做反正切运算,算出一个绝对角度值,再量化成12位数字量存到寄存器里。

这里有几个关键点直接决定了你的使用效果。第一,磁铁必须是径向充磁的,也就是磁铁的N极和S极在圆柱的侧面各占一半,而不是像普通磁铁那样上下两面是N和S。你拿一个普通的圆片磁铁放上去,读出来的数据基本是废的。第二,磁铁和芯片之间的气隙有讲究,典型值是0.5到3毫米,太近了磁场饱和,太远了信号太弱,都会导致角度跳变。第三,磁铁的中心必须尽量对准芯片中心,偏移超过1毫米精度就会明显下降。

我一般推荐用直径6毫米、厚度2.5毫米的径向充磁钕铁硼磁铁,这个尺寸跟AS5600的推荐匹配度最好。买的时候一定要跟卖家确认"径向充磁"四个字,很多卖家默认发的是轴向充磁,拿到手你装上去发现数据不对,再回头换货就耽误时间了。

2.2 IIC通信协议在AS5600上的具体表现

AS5600的IIC地址是固定的0x36(7位地址),这个地址不可更改,所以你在一条IIC总线上只能挂一颗AS5600。如果你需要多个关节角度检测,要么用IIC多路复用器,要么换用SPI接口的型号比如AS5047P。

IIC的通信速率方面,AS5600支持标准模式100kHz和快速模式400kHz。实测下来400kHz完全稳定,再高就不建议了,因为AS5600的内部寄存器读取需要一定的处理时间。这里有个细节:AS5600在收到读命令后,内部需要大概150微秒来准备数据,如果你用400kHz的时钟频率连续读取,中间不加延时,可能会读到重复的旧数据。我的做法是在每次读取之间加一个200微秒左右的短延时,或者直接以100Hz到200Hz的频率读取角度,这个速率对绝大多数控制场景已经绰绰有余。

IIC总线的上拉电阻取值是个老生常谈的问题。在3.3V系统下,4.7kΩ是最常用的值,总线电容小的时候也可以用2.2kΩ来提高上升沿速度。但如果你总线上挂了多个设备或者走线比较长,电容大了之后上拉电阻太小会导致低电平灌电流过大,这时候反而要加大到10kΩ。我的经验是:先焊4.7kΩ,用示波器看SCL和SDA的上升沿,如果上升时间超过1微秒,就适当减小电阻;如果低电平下不去0.3V以下,就加大电阻。

2.3 寄存器映射:你需要关心的只有这几个

AS5600的寄存器表在数据手册里有完整列出,但实际使用中你真正需要操作的只有几个。我把它整理成下面这个表,方便你直接对照:

寄存器地址名称功能常用值
0x0CRAW_ANGLE_H原始角度高8位只读
0x0DRAW_ANGLE_L原始角度低4位只读
0x0EANGLE_H经过ZPOS/MPOS处理的角度高8位只读
0x0FANGLE_L经过ZPOS/MPOS处理的角度低4位只读
0x07CONF_H配置寄存器高位0x00
0x08CONF_L配置寄存器低位0x00
0x01ZPOS_H零位设置高位按需
0x02ZPOS_L零位设置低位按需
0x03MPOS_H最大位置设置高位按需
0x04MPOS_L最大位置设置低位按需
0x0BSTATUS磁铁状态只读
0x1AAGC自动增益控制值只读

RAW_ANGLE和ANGLE的区别在于:RAW_ANGLE是芯片直接算出来的绝对角度,范围0到4095;ANGLE是经过ZPOS和MPOS映射之后的角度。如果你不需要设置零位和量程,直接用RAW_ANGLE就行,省去配置步骤。

STATUS寄存器值得特别关注。它的bit5是MD(Magnet Detected),bit4是ML(Magnet Too Weak),bit3是MH(Magnet Too Strong)。读取角度之前先检查这三个位,如果MD为0说明磁铁没检测到,ML为1说明磁场太弱,MH为1说明磁场太强。这个自检功能非常实用,可以在初始化阶段就发现安装问题,不用等到读数据发现跳变再回头查。

AGC值反映的是内部自动增益控制的当前状态。磁铁位置合适的时候,AGC值通常在0到255的中间范围,大概在100到150之间。如果AGC接近0或者接近255,说明磁场太强或太弱,需要调整气隙。我习惯在初始化时把AGC值打印出来,作为安装质量的参考指标。

3. 硬件连接与初始化配置实操

3.1 最小系统接线方案

先把硬件跑通再谈软件。AS5600的最小系统只需要以下几根线:

  • VCC接3.3V(注意:AS5600不支持5V供电,虽然有些模块板载了稳压,但芯片本身是3.3V的)
  • GND接地
  • SDA接主控的IIC数据线,同时通过4.7kΩ上拉到3.3V
  • SCL接主控的IIC时钟线,同时通过4.7kΩ上拉到3.3V
  • DIR接地或接VCC,决定角度增加的方向

DIR引脚很多人忽略,但它决定了你读到的角度是顺时针增加还是逆时针增加。DIR接地时,从芯片正面看(有字的那面朝上),磁铁顺时针旋转角度增加;DIR接VCC时方向相反。如果你发现角度变化方向和实际旋转方向反了,不用改代码,直接把DIR引脚的电平换一下就行。

另外,AS5600的OUT引脚是模拟/PWM输出,如果你只用IIC,这个引脚可以悬空。PGO引脚是编程使能,正常使用时接地。

3.2 用STM32CubeMX配置IIC的完整流程

如果你用STM32,CubeMX可以省掉很多初始化代码。打开CubeMX之后,在Pinout视图里找到IIC外设,选择IIC模式。以IIC1为例,PB6自动分配为SCL,PB7自动分配为SDA。在Configuration标签页里,把IIC Speed Mode设为Fast Mode,Clock Speed设为400000Hz。

这里有个容易踩的坑:CubeMX默认的IIC时钟配置有时候会导致实际速率偏差较大。你需要在Clock Configuration页面确认IIC外设的时钟源频率,然后回到IIC配置页面看实际的SCL频率。如果偏差超过10%,手动调整一下分频系数。

生成代码之后,HAL库的IIC读写函数直接用HAL_IIC_Mem_Read和HAL_IIC_Mem_Write就行。AS5600的寄存器是8位的,所以MemAddressSize用IIC_MEMADD_SIZE_8BIT。下面是一个读取原始角度的函数示例:

#define AS5600_ADDR 0x36 << 1 // HAL库需要左移一位 uint16_t AS5600_ReadRawAngle(void) { uint8_t buf[2]; HAL_IIC_Mem_Read(&hiic1, AS5600_ADDR, 0x0C, IIC_MEMADD_SIZE_8BIT, buf, 2, 100); return ((uint16_t)(buf[0] & 0x0F) << 8) | buf[1]; }

注意RAW_ANGLE_H的高4位是无效的,只有低4位是有效数据,所以要和0x0F做与运算。这个细节数据手册里有写,但很容易看漏。

3.3 ESP32下的IIC配置差异

ESP32的IIC外设叫IIC,在Arduino环境下用Wire库最方便。初始化代码如下:

#include <Wire.h> #define AS5600_ADDR 0x36 void setup() { Serial.begin(115200); Wire.begin(21, 22); // SDA=21, SCL=22 Wire.setClock(400000); } uint16_t readRawAngle() { Wire.beginTransmission(AS5600_ADDR); Wire.write(0x0C); Wire.endTransmission(false); Wire.requestFrom(AS5600_ADDR, 2); uint8_t high = Wire.read(); uint8_t low = Wire.read(); return ((uint16_t)(high & 0x0F) << 8) | low; }

ESP32的IIC引脚可以任意映射,但默认的21和22是最常用的组合。如果你用的是ESP32-S3或者其他型号,引脚号可能不同,查一下对应的数据手册就行。

ESP32有个需要注意的地方:它的IIC内部上拉比较弱,如果你没有外接上拉电阻,在400kHz下可能通信不稳定。我建议无论如何都在SDA和SCL上各焊一个4.7kΩ的上拉电阻,不要依赖内部上拉。

4. 角度数据读取与滤波处理

4.1 原始数据读取与角度换算

读到了12位原始数据之后,换算成角度很简单:

float angle_deg = raw_angle * 360.0f / 4096.0f;

但实际使用中,我建议你保留原始整数值做后续处理,只在最终显示或上报的时候才转成浮点角度。原因是浮点运算在中断或者高频循环里开销比较大,而整数比较和差值计算要快得多。

还有一个细节:12位分辨率意味着最小角度分辨率是360/4096,约等于0.088度。这个精度对于大多数云台和电机控制已经够了,但如果你需要更高精度,可以考虑AS5047P,它是14位的,分辨率提高到0.022度。不过AS5047P是SPI接口,接线和代码都要改,选型的时候要提前想清楚。

4.2 多圈角度累计的实现方法

单圈角度只能告诉你轴在0到360度之间的位置,但很多应用需要知道轴转了多少圈。比如一个丝杆滑台,电机转10圈对应滑台移动一定距离,你就需要累计圈数。

实现思路是:每次读取新角度,和上一次的角度做差,如果差值超过2048(也就是半圈),就认为发生了一次过零,圈数加一或减一。代码大概长这样:

int32_t getMultiTurnAngle(uint16_t new_raw) { static uint16_t last_raw = 0; static int32_t turns = 0; int16_t diff = (int16_t)(new_raw - last_raw); if (diff > 2048) { turns--; } else if (diff < -2048) { turns++; } last_raw = new_raw; return turns * 4096 + new_raw; }

这里用int16_t做差值运算很关键,它自动处理了无符号整数的回绕问题。如果你用int32_t做差再判断,代码会多好几行,还容易出错。

这个方法的精度取决于你的读取频率。如果轴转得很快,两次读取之间角度变化超过半圈,就会丢圈。假设你以1kHz的频率读取,轴转速不能超过500圈/秒,这个上限对绝大多数应用都够用。但如果你的读取频率只有100Hz,上限就降到50圈/秒,高速场景下就要注意了。

4.3 滑动平均与卡尔曼滤波的取舍

AS5600的原始数据本身已经比较干净了,但在电机驱动场景下,PWM开关噪声会耦合到IIC线上,导致偶尔出现跳变。我一般用两种滤波方式:

第一种是滑动平均,简单粗暴。维护一个长度为8的环形缓冲区,每次读取新值放进去,输出8个值的平均。这个方法对随机噪声效果好,但会引入大约4个采样周期的延迟。如果你的控制周期是1ms,延迟就是4ms,对大多数云台够用,但对高速FOC控制可能偏大。

第二种是一阶低通滤波,公式是output = alpha * new + (1-alpha) * output。alpha取0.2到0.5之间,根据你的噪声情况调。这个方法延迟小,但滤波效果不如滑动平均。我通常先用示波器看原始数据的噪声幅度,如果跳变在正负5个LSB以内,用一阶低通就够了;如果跳变超过20个LSB,说明硬件上可能有干扰,先查硬件再谈滤波。

注意:任何滤波都会引入延迟,在闭环控制系统中,延迟直接影响相位裕度。如果你发现加了滤波之后系统开始振荡,先把滤波去掉,确认是控制参数的问题还是滤波延迟的问题。

5. 常见问题排查与实战避坑经验

5.1 IIC扫不到地址的排查顺序

这是新手遇到最多的问题。我的排查顺序是这样的:

第一步,确认供电。用万用表量AS5600的VCC引脚,必须是3.3V。有些模块板载了5V转3.3V的LDO,你给它供5V也能工作,但如果你直接给芯片供5V,它可能已经烧了。

第二步,确认上拉电阻。用万用表量SDA和SCL对VCC的电阻,应该是4.7kΩ左右。如果量出来是无穷大,说明上拉电阻没焊或者虚焊。

第三步,确认地址。AS5600的7位地址是0x36,但很多IIC扫描程序输出的是8位地址,也就是0x6C。如果你用0x36去扫扫不到,试试0x6C。

第四步,用示波器看波形。如果SDA和SCL都有波形但就是没有应答,检查一下时序参数。AS5600对IIC的建立时间和保持时间有要求,如果你的主控IIC速率太快或者上升沿太慢,可能导致通信失败。把速率降到100kHz试试。

第五步,检查DIR和PGO引脚。DIR悬空的时候状态不确定,可能影响通信。PGO如果接高电平,芯片会进入编程模式,IIC可能不响应。把这两个引脚都明确接地。

5.2 角度跳变的硬件排查清单

角度数据偶尔跳变,九成以上是硬件问题,不是软件问题。按下面这个清单逐项检查:

现象可能原因排查方法
角度偶尔跳到0或4095磁铁偏心或气隙过大读AGC值,正常应在100-150
角度周期性波动电机PWM干扰示波器看VCC纹波,加100nF去耦电容
角度单向漂移磁铁温度漂移检查磁铁温度系数,必要时换低温漂磁铁
角度完全不动IIC通信失败读STATUS寄存器,检查MD位
角度跳变幅度固定某一位数据错误检查IIC上拉和走线,缩短线长

我遇到过一次很隐蔽的问题:AS5600的VCC和电机驱动共用一条电源线,电机加速的时候角度数据就会跳。后来在AS5600的VCC引脚旁边加了一个100nF的陶瓷电容和一个10uF的钽电容,问题就解决了。磁编码器对电源纹波很敏感,去耦电容不能省。

5.3 磁铁安装的实操心得

磁铁安装看起来简单,实际上是最容易出问题的地方。我总结了几条经验:

磁铁和芯片之间的气隙,先用3mm左右的非磁性垫片垫着,读AGC值,然后逐渐减小气隙,观察AGC值的变化。AGC值在100到150之间对应的气隙就是合适的。如果AGC值一直很低,说明磁铁磁场太弱,换更强的磁铁或者减小气隙。

磁铁的中心对准,可以用一个简单的办法:在芯片上方放一张白纸,把磁铁放在纸上,慢慢移动,同时观察RAW_ANGLE的值。当磁铁中心对准芯片中心时,旋转磁铁一圈,RAW_ANGLE的变化应该是均匀的。如果某个角度范围内变化特别快或者特别慢,说明磁铁偏心或者磁铁本身的磁场不均匀。

磁铁的固定方式也很重要。用胶水粘的时候,胶水固化过程中的收缩可能会让磁铁偏移。我一般用UV胶,点上去之后先用紫外灯预固化几秒,确认位置没动再完全固化。热熔胶也可以,但温度高了会软化,不适合高温环境。

5.4 从单圈到闭环:AS5600在FOC中的实际表现

很多人用AS5600做无刷电机的FOC控制,这里说几个实际数据。AS5600的12位分辨率对应0.088度,对于极对数为7的电机,电角度分辨率是0.088乘以7等于0.616度。这个精度对于低速平稳运行够用,但在高速下,由于IIC读取速率限制,角度更新率可能跟不上。

我实测过用STM32F103以400kHz IIC读取AS5600,读取一次完整角度(发地址、发寄存器地址、读两个字节)大概需要80微秒,加上处理时间,实际角度更新率可以做到5kHz左右。对于转速在3000RPM以下的电机,这个更新率足够。但如果你的电机转速超过5000RPM,建议换用SPI接口的AS5047P,它的读取速率可以轻松做到10kHz以上。

另外,AS5600的绝对角度输出意味着你不需要像霍尔传感器那样做启动对齐。上电之后直接读到的就是绝对位置,FOC算法可以直接用。这是磁编码器相比霍尔的一大优势,省掉了启动时的抖动和对齐过程。

6. 进阶应用与扩展思路

6.1 用AS5600做旋钮编码器

除了电机控制,AS5600也很适合做高精度旋钮。相比传统的机械编码器,磁编码器没有磨损、寿命长、分辨率高。你只需要在旋钮轴上装一颗径向充磁磁铁,下面放AS5600,就能得到一个12位的绝对角度旋钮。

做旋钮的时候,我建议加上"吸附"效果,也就是在软件里把角度量化到固定档位。比如每15度一个档位,总共24个档位。实现方法是把角度除以15取整,再乘以15。这样旋钮转动的时候会有段落感,手感更好。

6.2 多AS5600组网方案

前面说过,AS5600的IIC地址固定,一条总线上只能挂一颗。如果你需要多个关节角度检测,有两个方案:

方案一,用IIC多路复用器比如TCA9548A,它可以把一条IIC总线扩展成8条,每条挂一颗AS5600。TCA9548A本身也是IIC设备,地址可以通过A0/A1/A2引脚配置,最多可以级联8片,理论上支持64颗AS5600。

方案二,用主控的多个IIC外设。STM32F4系列一般有3个IIC,ESP32有2个IIC,可以同时挂多颗。如果还不够,可以用软件模拟IIC,理论上任意GPIO都可以做IIC。

方案三,换用SPI接口的AS5047P。SPI的片选机制天然支持多设备,而且速率更高。如果项目对成本不敏感,我推荐直接用AS5047P,省去多路复用器的麻烦。

6.3 磁编码器选型对比:AS5600 vs AS5047P

参数AS5600AS5047P
分辨率12位14位
接口IICSPI
最大速率400kHz10MHz
供电3.3V3.3V/5V
封装SSOP-8TSSOP-14
价格较低中等
适用场景低速云台、旋钮高速FOC、机械臂

选型建议:如果你的应用对角度更新率要求不高(低于1kHz),AS5600完全够用,而且接线简单、代码量少。如果需要高速读取或者多设备组网,直接上AS5047P,省去后面升级的麻烦。

6.4 温度漂移与长期稳定性

磁编码器的角度输出会受温度影响,主要来源是磁铁的剩磁随温度变化。钕铁硼磁铁的剩磁温度系数大约是-0.12%/°C,也就是说温度每升高1度,磁场强度下降0.12%。AS5600内部的AGC会自动补偿一部分,但在温度变化剧烈的场景下,角度输出还是会有漂移。

如果你的应用对温度稳定性要求高,两个办法:一是选用钐钴磁铁,它的温度系数是-0.03%/°C,比钕铁硼好很多,但价格更贵;二是在软件里做温度补偿,用一颗温度传感器监测环境温度,根据温度值对角度做修正。修正系数需要你实际标定,不同磁铁、不同气隙的系数都不一样。

我在一个户外云台项目里遇到过温度漂移问题,夏天中午和晚上读到的零位差了大约0.5度。后来换了钐钴磁铁,漂移降到0.1度以内,满足了项目要求。

7. 我的实操体会

AS5600这颗芯片,硬件设计简单,软件配置也不复杂,但真正用好它,功夫在细节上。磁铁的选型和安装、IIC总线的上拉和走线、电源的去耦、数据的滤波,每一个环节都影响最终的角度质量。

我自己的习惯是,拿到新的AS5600模块之后,先不急着写代码,而是用USB转IIC工具接上电脑,用上位机软件把RAW_ANGLE、AGC、STATUS这几个寄存器都读出来看一遍。确认磁铁安装没问题、AGC值在合理范围、STATUS没有报错,再开始写单片机代码。这个前置检查花不了十分钟,但能帮你排除掉大部分硬件问题。

另外,如果你在做闭环控制,建议在代码里加一个角度数据有效性的判断。每次读取角度之前先读STATUS寄存器,如果MD位为0或者ML/MH位为1,就把这次数据丢弃,用上一次的有效值代替。这个简单的保护逻辑可以避免磁铁松动或者干扰导致的控制异常。

最后分享一个小技巧:AS5600的OUT引脚可以配置成PWM输出,如果你不想用IIC,也可以用PWM读取角度。虽然精度和速率都不如IIC,但在某些IIC资源紧张的场景下,这是一个可用的备选方案。配置方法是通过IIC写CONF寄存器,把OUT引脚的功能从模拟输出改成PWM输出,然后就可以用定时器捕获PWM占空比来换算角度了。

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

555定时器经典电路全解析:方波、单稳态、施密特、PWM与锯齿波

555这颗芯片&#xff0c;年纪比很多电子工程师都大&#xff0c;但直到今天&#xff0c;你拆开任何一个带调光功能的台灯、一个廉价方波信号源、一个LED闪烁电路&#xff0c;大概率还能看到它的身影。原因很简单&#xff1a;它便宜、皮实、外围器件少&#xff0c;而且从单稳态到…

作者头像 李华
网站建设 2026/10/7 6:46:13

Agent-Reach:用CLI为AI Agent打造可审计的执行层

1. 从命令行到智能体&#xff1a;Agent-Reach 到底在解决什么问题第一次看到 Agent-Reach 这个名字&#xff0c;我下意识把它和市面上那些“AI Agent 框架”归到了一类。但翻了一圈热词和社区讨论之后&#xff0c;我发现它真正想做的事情&#xff0c;比“再做一个 Agent 框架”…

作者头像 李华
网站建设 2026/10/7 6:46:13

VAAPI硬件加速实战:Intel核显与NVIDIA卡的FFmpeg转码配置指南

做视频转码的&#xff0c;迟早要被CPU转码的速度逼疯。我第一次拿一台双路服务器跑H.264转HEVC&#xff0c;一个多小时的视频折腾了将近四个小时&#xff0c;从那以后&#xff0c;我认真研究了一遍FFmpeg的硬件加速。今天这篇专门聊VAAPI&#xff0c;Linux下最通用的视频加速接…

作者头像 李华
网站建设 2026/10/7 6:46:10

AI日报:多AI协作、接口细节与内容生产的工程实践

周六的AI圈通常不会太安静&#xff0c;今天也一样。飞书群里有人在传一份“一站式AI产品经理入门指南”&#xff0c;另一拨人在讨论Codex新付费档位到底值不值&#xff0c;还有人被一个看着很简单的问题卡住了&#xff1a;豆包的API里&#xff0c;为什么请求字段是input而不是m…

作者头像 李华
网站建设 2026/10/7 6:45:55

AI实时日志分析+源码上下文:移动端崩溃定位提效实战

做客户端开发这几年&#xff0c;最让我头疼的事就是靠人眼翻 App 实时日志来定位问题。几万行流水账里&#xff0c;真正有价值的信息可能只有两三行&#xff0c;而 AI 恰好擅长在噪音里找关联。最近我把整个排查流程改了&#xff1a;让 AI 实时读取 App 日志&#xff0c;遇到异…

作者头像 李华
网站建设 2026/10/7 6:45:43

QuickBlue AI应用底座:基于微服务与Spring Cloud的工程化落地实践

1. 从一个尴尬的现场说起&#xff1a;为什么“能跑的AI Demo”到了生产环境就趴窝我见过太多团队在AI落地这件事上卡在同一个地方。会议室里Demo跑得行云流水&#xff0c;老板点头、业务方鼓掌&#xff0c;大家都觉得下个月就能上线。结果真到了要接真实流量、要对接内部三五个…

作者头像 李华