简介基于STM32硬件SPI接口驱动AD7124模数转换芯片的完整源码包面向有一定STM32基础、需要快速集成高精度ADC的嵌入式开发者适用于工业数据采集、精密测量等多通道低噪声信号链场景。代码将底层SPI通信与AD7124寄存器读写封装为清晰模块提供寄存器读取、写入及免检测读写等接口便于理解硬件SPI时序、寄存器配置流程和驱动分层思路可直接移植到Keil、IAR等工程中复用。压缩包约9KB共7个文件由4个头文件和3个C源文件组成头文件集中定义寄存器映射与对外接口C文件承担SPI初始化、通信收发和寄存器操作实现代码体量小且结构精简。资源已有673人学习适合用来对照学习STM32硬件SPI外设的驱动写法也能作为AD7124多通道高精度采集方案的参考模板帮助开发者缩短驱动调试与验证周期。1. 用 STM32 硬件 SPI 驱动 AD7124先弄懂它和普通 ADC 源码包差在哪做称重仪表或者热电偶采集的人大概率都下载过这类“基于 stm32 硬件 SPI 接口驱动 AD7124 程序源代码.zip”。AD7124 是 ADI 的 24 位 Σ-Δ 型模数转换芯片自带 PGA 可编程增益能接应变桥、热电阻、热电偶比普通 16 位逐次逼近型 ADC 精度高一个量级但代价是初始化配置非常敏感。你从压缩包里解出来的代码往往最值钱的不是 main 里那几行读数据逻辑而是寄存器初始化序列、复位时序和 DOUT/DRDY 就绪引脚的处理方式。我用硬件 SPI 而不是模拟 SPI 去驱动它就是因为 AD7124 的 SPI 帧要求 CS 低电平期间连续传完命令字节和数据字节模拟翻转一旦被中断打断整帧数据就废了。这篇就按这个源码包的常见结构从前到后拆清楚哪些能直接抄、哪些参数必须自己核对以及我调这类板子时踩过的几个真坑。2. STM32 硬件 SPI 接 AD7124CubeMX 参数、上拉和片选方案2.1 AD7124 引脚和供电先弄清参考电压与上拉AD7124 常见型号是 AD7124-4 和 AD7124-8前者 4 组差分输入后者 8 组差分输入寄存器操作完全一样只是通道数和芯片 ID 不同。驱动这块芯片第一件事不是写代码而是看供电和参考电压。AVDD 我一般接 3.3V 经过 LC 滤波后的电源DVDD 也接 3.3V模拟地数字地单点汇合不要在芯片下方直接铺成一块大铜皮。REFIN1 和 REFIN1- 接外部基准最常用的是 ADR4525 这类低噪声 2.5V 基准REFIN 两端各放一个 0.1μF 陶瓷电容靠近 REFCAP 引脚再加一个 1μF 电容。DOUT/DRDY 是复用引脚它既是 SPI 数据输出 MISO又是转换完成标志。数据准备好时这个引脚会拉低主机轮询到低电平就可以读数据寄存器。因为这个引脚在芯片上电初期可能是高阻态我习惯在 PCB 上给它加一个 10kΩ 上拉到 3.3V防止主控端误判。SDI、SCLK、CS 三个引脚不需要上拉主控直接推挽输出就行。接线表如下STM32 引脚AD7124 引脚说明SPI_SCKSCLKSPI 时钟SPI_MOSISDI主机发送从机接收SPI_MISODOUT/DRDY数据输出兼转换完成标志任意 GPIOCS片选软件控制3.3VAVDD / DVDD供电GNDAGND / DGND共地2.2 CubeMX 里 STM32 硬件 SPI 的 5 个关键参数打开 STM32CubeMX 配置 SPI 外设时我最常被问到的就是“为什么按网上配置还是读不出 ID”。其实 SPI 模式就五个参数主机模式、全双工、8 位数据、MSB 在前、禁止硬件 CRC。时钟极性 CPOL 和相位 CPHA 最容易翻车我的调试起点是 CPOLLow、CPHA1Edge也就是 SPI Mode 0SCLK 空闲为低数据在第一个边沿采样。如果读 ID 失败再切到 CPHA2Edge 试一次一次就能定位是相位问题还是复位问题。时钟分频一开始不要设太快。STM32 的 SPI 外设时钟通常是 APB 总线时钟我调试期先选 64 分频让 SCLK 落在 1MHz 上下等读写正常后再提到 8 分频。AD7124 手册标称 SCLK 上限很高但实际板子上走线、容性负载都会影响高速时序先慢后快是这类高精度 ADC 的通用调试顺序。NSS 引脚选软件管理关闭硬件片选。CubeMX 配置片段如下hspi1.Instance SPI1; hspi1.Init.Mode SPI_MODE_MASTER; hspi1.Init.Direction SPI_DIRECTION_2LINES; hspi1.Init.DataSize SPI_DATASIZE_8BIT; hspi1.Init.CLKPolarity SPI_POLARITY_LOW; hspi1.Init.CLKPhase SPI_PHASE_1EDGE; hspi1.Init.NSS SPI_NSS_SOFT; hspi1.Init.BaudRatePrescaler SPI_BAUDRATEPRESCALER_64; hspi1.Init.FirstBit SPI_FIRSTBIT_MSB; HAL_SPI_Init(hspi1);这里有一个我反复跟人强调的点不要一上来就开 SPI 的硬件 CRC。AD7124 本身支持 SPI CRC 校验但那是芯片端使能选项和 STM32 外设的 CRC 是两回事。初版代码先把两边 CRC 全部关掉等数据通路稳定了再考虑开启否则你会在排查 CRC 错误和排查时序错误之间来回浪费时间。2.3 片选用 GPIO 还是硬件 NSS这个开关别偷懒网上很多 STM32 SPI 例程喜欢用硬件 NSS 片选但驱动 AD7124 时我强烈建议改成普通 GPIO 软件片选。原因在于 AD7124 的每次访问都是一个完整帧CS 拉低发送命令字节再发送或接收数据字节最后 CS 拉高。STM32 硬件 NSS 在多字节传输时的行为不完全可控尤其是帧与帧之间的拉高时机稍有不慎就会把一次寄存器读写在中间拆成两段芯片直接忽略整条命令。GPIO 软件片选的初始化代码很简单GPIO_InitStruct.Pin ADC_CS_PIN; GPIO_InitStruct.Mode GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull GPIO_NOPULL; GPIO_InitStruct.Speed GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(ADC_CS_PORT, GPIO_InitStruct); GPIO_InitStruct.Pin ADC_DRDY_PIN; GPIO_InitStruct.Mode GPIO_MODE_INPUT; GPIO_InitStruct.Pull GPIO_PULLUP; HAL_GPIO_Init(ADC_DRDY_PORT, GPIO_InitStruct); ADC_CS_HIGH();CS 默认拉高每次操作前拉低操作完成后拉高。注意 CS 拉高后到下一次拉低之间要留一点时间也就是手册里的 t8 参数别刚拉高就立刻进行下一次访问。这个延时在低速 SCLK 下可以忽略但把 SCLK 提到 10MHz 以上后必须显式加几微秒等待。很多从 zip 里直接抄来的代码没有这个细节批量生产时偶发读写失败根源就在这里。3. 寄存器读写底座复位序列、读 ID 校验和 32 位数据拼装3.1 用悬空读 ID 验证 SPI 通路的 5 行命令拿到一个新的 AD7124 板子我第一步不是配通道而是复位然后读 ID 寄存器。这一步能同时验证 SPI 时序、引脚映射、供电是否正常相当于整个驱动的地基。AD7124 的 ID 寄存器地址是 0x06读回的 32 位数据低字节是芯片 ID不同型号的值不一样以手册 Device ID Table 为准。如果读 ID 返回 0xFF说明 SPI 上根本没读到数据要么 MOSI/MISO 接反要么时钟相位不对要么芯片没复位成功。如果返回 0x00先查 CS 是否一直没拉低或者 AD7124 的 DVDD 没供上。如果读到的值看起来像 ID 但又不对多半是寄存器地址命令字节写错了注意读命令最高位必须是 1。uint8_t ad7124_check_id(void) { uint32_t raw ad7124_read_reg(0x06); /* 0x06 ID 寄存器 */ return (uint8_t)(raw 0xFF); }这段代码逻辑上只有一个动作发读命令读 4 字节取最低字节。但它背后的含义是整条 SPI 通路已经打通。我会在初始化函数里这样用如果读 ID 回来不是预期值直接 return不继续配置后面的寄存器免得在一堆假数据里找问题。3.2 通用寄存器读写函数命令字节与字节序AD7124 的 SPI 访问分两步。第一步通过通信寄存器发一个 8 位命令字节指定接下来要访问哪个寄存器、是读还是写。第二步才是真正的数据交换寄存器数据都是 32 位MSB 在前。命令字节的 bit7 是读写标志1 为读0 为写bit6 到 bit0 是寄存器地址。所以写寄存器就是把命令字节和数据字节放在同一个 CS 低电平窗口内发出去。读写函数的 HAL 实现如下uint8_t ad7124_make_cmd(uint8_t reg, uint8_t rw) { return (uint8_t)((rw ? 0x80 : 0x00) | (reg 0x7F)); } void ad7124_write_reg(uint8_t reg, uint32_t val) { uint8_t cmd ad7124_make_cmd(reg, 0); uint8_t buf[4]; buf[0] (uint8_t)((val 24) 0xFF); buf[1] (uint8_t)((val 16) 0xFF); buf[2] (uint8_t)((val 8) 0xFF); buf[3] (uint8_t)(val 0xFF); ADC_CS_LOW(); HAL_SPI_Transmit(hspi1, cmd, 1, 10); HAL_SPI_Transmit(hspi1, buf, 4, 10); ADC_CS_HIGH(); } uint32_t ad7124_read_reg(uint8_t reg) { uint8_t cmd ad7124_make_cmd(reg, 1); uint8_t buf[4] {0}; ADC_CS_LOW(); HAL_SPI_Transmit(hspi1, cmd, 1, 10); HAL_SPI_Receive(hspi1, buf, 4, 10); ADC_CS_HIGH(); return ((uint32_t)buf[0] 24) | ((uint32_t)buf[1] 16) | ((uint32_t)buf[2] 8) | (uint32_t)buf[3]; }这里有个 SPI 全双工的特点需要记住读操作时STM32 发命令字节的同时 MISO 上也会收到字节那个字节是无效数据丢掉即可。真正读数据时主机必须一直提供 SCLK所以HAL_SPI_Receive底层其实也在发送只是发送的内容我们不在乎。我也见过有人为了省事把读命令和读数据放在两个 CS 窗口里结果读出来永远是 0因为 AD7124 的命令字节只对当前这次 CS 低电平窗口有效CS 一拉高刚才指定的寄存器就失效了。3.3 复位序列上电后的第一件事AD7124 的复位有两种常见做法一种是向复位寄存器写数据另一种是手册里的长帧复位序列。我实际项目里用的是后者稳定且不需要查寄存器具体值CS 拉低连续发送 64 个 0xFF然后 CS 拉高。芯片收到一长串连续 1 后自动复位所有寄存器恢复默认值。void ad7124_reset(void) { uint8_t ff 0xFF; int i; ADC_CS_LOW(); for (i 0; i 64; i) { HAL_SPI_Transmit(hspi1, ff, 1, 10); } ADC_CS_HIGH(); HAL_Delay(10); }这个复位序列最容易被忽略的是 CS 保持问题。有些人会把 CS 拉低、发一个字节、拉高再拉低、发下一个字节这样发满 64 个 0xFF芯片是永远收不到完整复位序列的。CS 必须在整个复位序列期间保持低电平。复位完成后要延时至少 10ms等待芯片内部上电复位完成再开始读 ID。10ms 这个值我一般只增不减电源启动慢的板子甚至要 50ms。另一个细节复位之后再读 ID如果还是 0xFF不要急着怀疑芯片坏了。先用示波器或逻辑分析仪抓一下 SCLK、MOSI、CS 三根线确认波形确实发出去了再检查 MISO 上有没有波形。我遇到过 SCLK 和 MOSI 都正常但 MISO 始终为高的板子最后发现是 DOUT/DRDY 引脚虚焊重新拖焊后立刻读到正确 ID。这种硬件问题靠改代码是解决不了的尽早抓波形比反复调软件省时间。4. AD7124 初始化转换模式、通道使能、PGA 与滤波字怎么配4.1 转换模式选连续还是单次先关掉内部校准AD7124 的 ADC 控制寄存器里有一个 Mode 字段决定芯片工作在连续转换还是单次转换。连续转换模式下芯片不停采样DOUT/DRDY 每次转换完成都会拉低适合称重这种需要持续输出数据的场景。单次转换模式是写一次开始指令转一次适合低功耗设备转完就睡。我第一版驱动通常先用连续模式跑通因为逻辑简单等数据稳定后再按功耗需求切单次。这里有一个新手很容易犯的错误芯片出厂默认状态可能带着内部校准使能位或者上一手代码把校准模式写进了寄存器。校准模式不是普通转换模式它的输出不是测量结果而是校准系数。如果发现读到的数据像噪声一样乱跳先回头读一遍 ADC 控制寄存器确认 Mode 字段真的是连续转换或单次转换而不是校准。uint32_t ad7124_adc_ctrl_value(uint32_t mode, uint32_t power) { uint32_t reg 0; /* Mode 字段0连续转换1单次转换 */ reg | (mode 0x7) 0; /* Power 字段0低功耗1中等功耗2全功耗 */ reg | (power 0x3) 4; return reg; }注意我这里刻意没有把所有字段的位号写满因为 AD7124 手册不同版本的位号描述有细节差异直接从网上抄一个整字魔法数最容易翻车。正确做法是打开手册 ADC Control Register 一节把 Mode、Power Mode、时钟源这几个字段按你的板子填好再拼成整字写入。全功耗模式响应最快但功耗也最高电池供电设备就用低功耗模式代价是输出数据速率上限降低。4.2 通道寄存器与配置寄存器AINP/AINN 和 SETUP 的对应关系AD7124 的初始化流程里最容易绕晕的是通道寄存器、配置寄存器、滤波寄存器三者之间的关系。通道寄存器 0x09 到 0x18 负责选输入引脚和使能通道配置寄存器 0x19 到 0x20 负责设置 PGA 增益、基准、单双极性滤波寄存器 0x21 到 0x28 负责设置输出数据速率和滤波器类型。一个通道必须指定它使用哪个配置组也就是 SETUP 字段。我习惯把通道 0 绑到 SETUP 0通道 1 绑到 SETUP 1一一对应方便排查。/* CH0AIN0 接正端AIN1 接负端使能绑定 SETUP 0 */ ad7124_write_reg(0x09, 0x00000083);这个 0x00000083 是怎么来的最低位 1 表示通道使能高位的 AINP 和 AINN 字段分别选了 AIN0 和 AIN1中间 SETUP 字段是 0。不同输入引脚的组合对应不同数值我强烈建议打开手册 Channel Register 表格按位填写不要直接套我这个数。因为 AINP 编码从 0 到 15AINN 也一样稍微写错一位采到的就不是你想接的那根引脚。配置组里的 PGA 增益是 AD7124 的精髓。增益从 1 到 128 分档每档对应不同编码配置寄存器里 PGA 字段写 000 到 111。增益越高能测的信号越微弱但噪声也被放大等效到输入端的噪声并不是一直改善的。热电偶信号通常只有几十微伏必须开 64 或 128 倍增益称重桥路输出几十毫伏开 8 到 32 倍就够。我用 128 倍增益时遇到过电源纹波直接体现在输出里的问题后来把 AVDD 换成低噪声 LDO 才解决。4.3 输出数据速率与 SINC 滤波25 SPS 与 128 倍 PGA 的搭配滤波寄存器里最核心的是滤波字 FS 和 SINC 滤波器类型。AD7124 内置 SINC3 和 SINC4 两种数字滤波器SINC4 对带外干扰抑制更好SINC3 建立时间更快。对高精度测量我默认用 SINC3输出数据速率设在 25 SPS。这个速率下 50Hz 工频干扰能获得较好的抑制尤其配合 128 倍 PGA 时噪声指标比高速率模式好很多。如果只是测缓慢变化的温度甚至可以降到 9.375 SPS。滤波字和输出数据速率的关系受主时钟频率影响同一滤波字在不同时钟下对应不同速率。网上很多源码包里的滤波寄存器整数比如 0x060180是基于 614.4kHz 主时钟、SINC3、25 SPS 算出来的。你如果换了外部晶振或者芯片工作在内部时钟模式但时钟频率不同这个值就不能直接用。我一般会先把主时钟确认清楚再按手册公式算一遍滤波字而不是盲目信任源码里的魔法数。/* 滤波寄存器0x06 段选 SINC30x0180 是滤波字614.4kHz 下约 25SPS */ ad7124_write_reg(0x21, 0x060180);这段代码能跑但它依赖一个前提你的主时钟确实是 614.4kHz且滤波器配置字段的位号和手册一致。验证方法很简单配置完滤波寄存器后回读一次确认写入值一致再看实际输出数据速率是否符合预期。如果两个板子一个用内部时钟一个用外部时钟同样的初始化序列会导致完全不同的输出速率这属于硬件设计层面就要定好的事改软件救不回来。4.4 读取转换结果轮询 DRDY 还是外部中断数据准备好后DOUT/DRDY 引脚拉低。读取方式两种轮询或外部中断。我在第一版驱动里永远用轮询因为逻辑简单不依赖中断优先级配置排查问题容易。主循环里等待 DRDY 变低然后读数据寄存器读完后 DOUT/DRDY 会自动回高。如果长时间等不到拉低大概率是通道没使能或者转换模式配错了。int32_t ad7124_read_result(void) { uint32_t raw; while (ADC_DRDY_READ() ! GPIO_PIN_RESET) { /* 等待转换完成可加超时保护 */ } raw ad7124_read_reg(0x03); /* 0x03 DATA 寄存器 */ raw 8; /* 高 24 位是转换结果 */ if (raw 0x800000) { raw | 0xFF000000; /* 24 位有符号数扩展为 32 位 */ } return (int32_t)raw; }这段代码里有两个关键点。第一温度寄存器读回的是 32 位但有效转换结果只占高 24 位低 8 位是状态或保留位必须先右移 8 位。第二AD7124 的转换结果是二进制补码格式24 位有符号数的最高位是符号位右移后需要手动扩展到 32 位否则负数会变成一个很大的正数。如果发现零输入时读数飘在 0 附近但温度负向变化时读数变成 0xFFFFFF基本就是符号扩展没做。数据读取也可以换外部中断方式把 DOUT/DRDY 接到 STM32 的 EXTI 引脚下降沿触发中断在中断服务函数里读数据。这种方式响应快CPU 不用死等但要注意中断服务函数里不能做耗时的寄存器回读验证否则会影响 SPI 时序。我更推荐用 DMA 配合方式后面单独说。等轮询方式完全跑通后再优化成中断或 DMA这样每一步出问题都知道改了什么。5. 硬件 SPI 驱动 AD7124 的 5 个避坑记录从读 ID 失败到噪声超标5.1 读 ID 永远返回 0xFF先查极性再查复位现象是新建工程后调用ad7124_check_id()返回值永远是 0xFF根本不是我预期的型号 ID。这个坑我进了两次第一次是 SPI 时钟相位配置错第二次是复位序列 CS 时序不对。原因是 AD7124 的 MISO 在空闲时是高电平读不到有效数据时 MISO 一直保持高拼出来的 32 位数据自然全是 1。解决方法是先抓 SCLK 和 MISO 波形确认 MISO 上有没有数据翻转然后把 CubeMX 里的 CLKPhase 从 1Edge 改成 2Edge 再试一次最后检查复位时 CS 是不是在整个 64 字节期间保持低。这三步做完ID 基本就出来了。5.2 数据始终为 0通道没使能或 AINP/AINN 选错现象是 ID 读正常配置也写了但读回来的数据一直是 0 附近纹丝不动。第一次遇到时我怀疑芯片坏了换了一片还是 0最后才发现通道寄存器里使能位没写。AD7124 的通道默认是禁用的你配置了 SETUP 和滤波器还不够必须先把对应通道的 EN 位置 1并且 AINP、AINN 要选到你实际接线的引脚。解决的方法是回读通道寄存器确认写进去的值和预期一致再确认你配的通道号和后面读数据时使能的通道是同一个别配了 CH0 去读 CH1 的数据。这种问题最好在初始化后加一个寄存器回读校验函数所有关键寄存器写进去后立即读出来比对。5.3 硬件片选导致的偶发读写失败换成 GPIO 软件片选现象是程序运行几分钟或几小时后突然出现一次读数错误复位后恢复正常。查了很久SPI 波形和电源都正常最后定位到 STM32 硬件 NSS 自动片选上。硬件 NSS 在 SPI 模块认为传输完成时会自动拉高 CS但这个时机和 AD7124 期望的帧边界不匹配尤其是 DMA 模式或多字节传输时有细微差别。解决方式很简单CubeMX 里 NSS 选 SoftwareCS 用普通 GPIO 手动拉低拉高确保命令字节和数据字节在同一个 CS 低窗口中。这是个架构层面的选择不建议为了节省一个 GPIO 去用硬件 NSS。5.4 读数据字节错位CS 拉高太快或命令帧被截断现象是能读到数据但数值完全不对连续读两次结果完全不一样像是对齐出了问题。原因是 CS 在最后一次 SPI 传输完成后立刻拉高而芯片内部还在把最后一位数据移入移位寄存器你提前结束帧最后一次传输的数据丢失了。解决方法是 CS 拉高前加一个极短延时等 SPI 总线完全空闲或者用HAL_SPI_TransmitReceive一次完成命令字节发送和数据接收避免中间有额外延时。这类问题在 SCLK 高时特别明显把 SCLK 降到 1MHz 再试如果正常了就说明是时序裕量不够。5.5 128 倍增益时噪声大得离谱供电和退耦先背锅现象是 PGA 增益开到 64 或 128 时输出噪声峰峰值达到几十微伏完全达不到手册标称水平。最开始我怀疑是芯片质量问题后来用示波器量 AVDD发现有高频纹波RC 滤波没起作用。原因是高增益下输入信号只有微伏级别电源上任何纹波都会被放大。解决方法是把 AVDD 的 LC 滤波改为低噪声 LDO 供电REFIN 引脚加去耦电容并且 ADC 模拟地和数字地在芯片下方以单点连接。另一个容易被忽略的因素是 SCLK 信号串扰到模拟输入线上SPI 线尽量远离 AIN 走线必要时 AIN 周围加地保护。这个坑解决后噪声从几十微伏降到 1 微伏以内属于整个驱动里收益最大的一次排查。6. 验证 AD7124 链路用短路输入和内部基准检查噪声与增益6.1 短路输入的噪声峰峰值是一切精度的前提驱动跑通后先别急着接传感器把 AIN0 和 AIN1 直接短接连续采样 100 次计算最大值和最小值的差这个差值就是当前配置下的本底噪声峰峰值。如果这个值远大于手册上的典型值后面的传感器标定都没意义。短接输入测试还能验证符号扩展代码有没有问题理想情况下短接输入读数应该是 0 附近如果读到满量程说明双极性配置或基准选择写错了。int32_t sample[100]; uint32_t i; int32_t vmax -0x7FFFFFFF; int32_t vmin 0x7FFFFFFF; for (i 0; i 100; i) { sample[i] ad7124_read_result(); if (sample[i] vmax) vmax sample[i]; if (sample[i] vmin) vmin sample[i]; } printf(p-p: %d LSB\r\n, (int)(vmax - vmin));这个测试里增益和滤波字都已经配置成你最终应用的参数。如果增益 1 时噪声几个 LSB增益 128 时噪声几十个 LSB是正常现象但增益 1 时噪声上千 LSB先回头查供电和布板。看到输出峰峰值符合预期后再做满量程校准才有意义。6.2 内部基准验证增益校准寄存器写入顺序不能乱AD7124 内置基准电压但外部基准更稳。为了验证增益配置正确我常把基准选择临时切到内部基准然后在输入端接入一个从基准电阻分压得到的已知电压计算换算结果。电压换算公式很简单输入电压等于转换结果除以 2 的 23 次方再乘以 PGA 增益分压后的满量程电压。比如 2.5V 基准、PGA 增益 1 时满量程是 2.5V一个 LSB 约等于 0.3 微伏。真正做系统校准时寄存器操作顺序不能乱先把 ADC 控制寄存器设为内部零刻度校准模式等待 DOUT/DRDY 拉低表示校准完成再设为内部满量程校准模式再等待完成。如果温度变化大或者换增益档位我喜欢在每次换量程后重新校准一次。校准结果会写入偏移寄存器和增益寄存器回读确认写入成功再开始正常转换。我自己的习惯是把校准封装成一个独立函数放到量程切换的公共流程里这样不会漏。希望帮到你。本文还有配套的精品资源点击获取