MCP4728四通道12位DAC芯片:I2C接口、EEPROM存储与嵌入式应用实战

发布时间:2026/6/19 3:44:39

MCP4728四通道12位DAC芯片:I2C接口、EEPROM存储与嵌入式应用实战 1. 项目概述为什么是MCP4728在嵌入式开发里模拟信号输出是个绕不开的活儿。无论是驱动一个可变亮度的LED控制一个电机的转速还是生成一个音频波形你都需要一个能把数字世界里的“0”和“1”转换成真实世界连续电压的桥梁——这就是数模转换器DAC。市面上DAC芯片很多但当你需要在一个空间有限、布线复杂的板子上实现多路高精度、可独立配置的模拟输出时选择就变得挑剔起来。Microchip的MCP4728这颗四通道、12位分辨率、自带I2C接口和EEPROM的DAC芯片就成了很多工程师项目里的“老朋友”。它不像那些动辄16位、24位的音频DAC追求极致的动态范围也不像一些高速DAC专注于波形生成的刷新率。MCP4728的核心价值在于它在一个非常合理的成本和复杂度下提供了一个极其稳定、可靠且“省心”的多通道模拟输出解决方案。特别是它内部集成的非易失性存储器EEPROM能让芯片在上电瞬间就恢复到预设的工作状态这个特性对于工业控制、仪器仪表等需要确定性和一致性的场景来说简直是“雪中送炭”。今天我们就来彻底拆解这颗芯片从I2C通信的每一个字节到EEPROM存储的每一个比特再到几个典型的实战应用让你不仅能看懂数据手册更能把它用得得心应手。2. 核心特性与内部架构深度剖析MCP4728的魅力源于其精巧的内部设计。它绝不是简单地把四个DAC模块塞进一个封装而是通过一系列智能设计实现了功能、性能和易用性的平衡。2.1 四通道独立12位DAC精度与灵活性的基石MCP4728内部集成了四个完全独立的12位电压输出型DAC。这里的“12位”分辨率意味着每个通道的输出电压可以被划分为 2^12 4096 个不同的等级。如果参考电压VREF是3.3V那么理论上它能控制的最小电压变化量即1 LSB就是 3.3V / 4096 ≈ 0.806 mV。这个精度对于绝大多数需要模拟设定的应用如偏置电压设置、传感器激励、可变增益控制已经绰绰有余。每个DAC通道都包含一个电阻串型DAC架构这是实现高精度和良好单调性的经典结构。其输出由一个轨到轨Rail-to-Rail的输出放大器缓冲这意味着输出电压可以非常接近电源电压VDD和地GND极大地扩展了输出电压的动态范围。例如在VDD5VVREFVDD的情况下输出范围几乎是0V到5V。每个通道的输出电压由公式决定VOUT (VREF * Dn) / 4096其中Dn是该通道12位输入码值0到4095。关键设计考量为什么是12位而不是8位或16位对于通用控制场景8位256级的精度有时显得粗糙特别是在控制线性器件时阶跃感明显。而16位65536级虽然精度极高但成本、对参考电压稳定性的要求、以及对PCB布局布线的敏感性都呈指数级上升。12位是一个在成本、精度和系统复杂度之间的“甜蜜点”。MCP4728的四个通道可以独立更新也可以同步更新通过LDAC引脚或I2C广播命令这为需要多路信号严格同步的应用如正交信号生成提供了可能。2.2 I2C接口简洁背后的复杂握手MCP4728通过标准的I2C总线与主控制器如STM32、GD32、ESP32等MCU通信。它支持标准模式100 kHz和快速模式400 kHz并且兼容I2C的广播呼叫General Call功能。其I2C从机地址是7位的格式为1100 A2 A1 A0其中A2, A1, A0由芯片的对应引脚电平决定这允许在同一总线上挂载最多8颗MCP4728实现多达32路的模拟输出扩展这对于需要大量模拟控制点的系统非常有用。与MCP4728的通信主要有两类操作写入DAC寄存器和写入EEPROM。写入DAC寄存器Volatile这种操作只改变DAC的输出电压掉电后丢失。其I2C数据帧通常包含命令字节和数据字节。命令字节里指定了要更新的通道A, B, C, D或全部、是否同时更新输出通过LDAC位、以及参考电压选择VDD或内部2.048V。数据字节则包含12位的DAC输入码。这是最常用、最快速的操作。写入EEPROMNon-Volatile这种操作将DAC的输入码、配置位如参考电压选择、增益保存到芯片内部的EEPROM中。此后每次芯片上电都会自动从EEPROM加载这些值到DAC寄存器并立即输出对应的电压。这是MCP4728的核心优势之一。但需要注意的是EEPROM的写入次数是有限的典型值100万次且写入时间较长约25ms。因此在程序设计中应避免频繁写入EEPROM通常只在需要保存最终“配方”或“校准参数”时才执行此操作。实操心得很多新手会困惑于I2C通信失败。除了检查地址、上拉电阻、时序这些基础项对于MCP4728要特别注意在进行EEPROM写入操作后必须等待足够的时间建议50ms以上再进行下一次I2C通信因为芯片在内部编程期间会“忙”不响应总线。用逻辑分析仪或示波器抓取I2C波形是排查这类问题最直接的手段。2.3 内部EEPROM赋予芯片“记忆”的灵魂这颗EEPROM是MCP4728区别于许多廉价DAC的关键。它并非一块独立的存储区而是与每个DAC通道的配置寄存器映射在一起。存储的内容包括DAC输入码12位数据决定上电后的输出电压。参考电压选择位选择使用VDD还是内部2.048V基准作为VREF。增益设置位当使用内部2.048V基准时可选择1倍或2倍增益从而获得2.048V或4.096V的满量程输出。掉电模式位可以设置DAC上电后进入低功耗模式。这些数据一旦存入EEPROM就成为了芯片的“默认人格”。想象一个工业控制板卡出厂前将每路DAC的校准值、默认工作点写入EEPROM。无论这块板卡被断电重启多少次甚至被更换到另一个系统只要一上电它就能输出准确、一致的电压无需主控MCU进行任何初始化配置。这极大地提高了系统的可靠性和可维护性。内部参考电压的妙用MCP4728提供了一个精度为±0.2%的内部2.048V基准源。使用内部基准而非VDD作为参考可以显著提高输出精度因为它不受电源电压波动的影响。这对于由电池供电或电源质量不佳的系统尤为重要。通过配置增益位你还可以得到4.096V的满量程这在许多传感器信号调理电路中非常实用。3. 硬件设计要点与电路连接实战把一颗芯片用对一半的功夫在硬件设计上。MCP4728虽然接口简单但细节决定成败。3.1 电源与去耦稳定输出的第一道防线MCP4728的工作电压范围是2.7V到5.5V。电源设计的首要原则是干净和稳定。主电源VDD建议使用一个低噪声的LDO低压差线性稳压器为其供电。如果与数字MCU共用电源务必在靠近MCP4728的VDD和GND引脚处放置一个10μF的钽电容或电解电容再并联一个0.1μF的陶瓷电容。大电容应对低频噪声和电流突变小电容应对高频噪声。参考电压VREF如果使用内部基准2.048V该引脚应通过一个0.1μF电容接地以滤除基准源本身的噪声。如果选择外部基准那么对外部基准源的要求温漂、噪声就直接决定了整个DAC的输出精度。输出引脚VOUTxDAC输出是电压型的驱动能力有限典型值25mA。如果需要驱动低阻抗负载必须外加运算放大器进行缓冲。直接在输出端接一个到大电容可能会引起稳定性问题如果需要滤波建议采用RC滤波如1kΩ 0.1μF而不是单纯的大电容。3.2 I2C总线布局确保通信畅通无阻I2C是开源集电极总线正确的上拉是关键。上拉电阻Rp的阻值需要根据总线电容Cb和通信速度计算。公式为Rp (VDD - 0.4) / (3mA)用于标准模式但更实用的是根据经验3.3V系统常用4.7kΩ。5V系统常用2.2kΩ或4.7kΩ。 如果总线上设备多、走线长总线电容大上拉电阻应减小如2.2kΩ以提供更强的上拉电流保证上升沿速度。但电阻过小会增加功耗。一个常见的错误是忘记接上拉电阻导致SCL和SDA线永远为低通信失败。地址引脚A0/A1/A2必须通过电阻上拉或下拉到VDD或GND以设定固定的I2C地址。严禁悬空悬空的引脚会引入噪声导致地址识别错误。LDAC引脚这是实现多通道同步更新的硬件手段。当LDAC为高电平时DAC寄存器更新不会立即反映到输出当LDAC被拉低时所有通道的DAC寄存器值会同时锁存到输出级实现同步更新。如果不需要此功能可以将LDAC引脚永久接地。3.3 典型应用电路连接图解析下面是一个MCP4728与STM32F103 MCU连接的典型原理图片段及解析STM32F103 MCP4728 (3.3V System) (SOIC-10) ------------- ------------- | | | | | PA9 |-------------------| SCL (Pin 3) | | | | | | PA10 |-------------------| SDA (Pin 4) | | | 4.7kΩ | | | | VDD VDD | | | | | | | | | | ----/\/\--- A0 (Pin 5) | | | | 4.7kΩ | | | | | | A1 (Pin 6) |--[GND] | | | | | | GND |------------------| A2 (Pin 7) |--[GND] | | | | | VCC |------------------| VDD (Pin 1) | | (3.3V) | | 10μF0.1μF| | | | ----- ----- | VSS (Pin 2) |--- GND | | GND GND | | | | | | | PA8 |-------------------| LDAC(Pin 10)|--[GND] (永久接地) | | | | | | | VOUTA(Pin 9)|--- To Load/Filter | | | VOUTB(Pin 8)|--- To Load/Filter ------------- -------------电路解读与要点I2C线路SCL和SDA均通过4.7kΩ电阻上拉到3.3V。这是3.3V系统下的典型值。地址配置A0通过电阻上拉到VDD逻辑‘1’A1和A2直接接地逻辑‘0’。因此该芯片的7位I2C地址为1100 1 0 0(二进制)即0x62(写地址) /0x63(读地址)。电源去耦VDD引脚处有10μF钽电容和0.1μF陶瓷电容并联到地这是保证电源质量的标准做法。LDAC处理本例中LDAC引脚接地意味着DAC寄存器一旦更新输出立即改变无需软件同步控制。如果需要同步可将此引脚连接到MCU的一个GPIO。输出VOUTA和VOUTB直接连接到负载。对于阻性负载或需要滤波可以串联一个小电阻如100Ω并接一个对地电容如0.1μF形成低通滤波。4. 软件驱动与通信协议实现详解硬件搭好接下来就是让芯片“动”起来。我们以STM32的HAL库为例讲解如何编写稳健的MCP4728驱动。4.1 I2C初始化与基础读写函数首先使用STM32CubeMX配置I2C外设例如I2C1设置为标准模式或快速模式并生成代码。// mcp4728.h #define MCP4728_I2C_ADDR_WRITE 0x62 // 假设A01, A10, A20 #define MCP4728_I2C_ADDR_READ 0x63 // 命令字节定义 #define MCP4728_CMD_WRITE_DAC_REG 0x40 // 快速写入DAC寄存器不保存EEPROM #define MCP4728_CMD_WRITE_DAC_REG_EEPROM 0x60 // 写入DAC寄存器并保存到EEPROM // 在命令字节中还可包含通道选择位、参考电压选择位等需按数据手册组合 typedef enum { MCP4728_CH_A 0, MCP4728_CH_B, MCP4728_CH_C, MCP4728_CH_D, MCP4728_CH_ALL } MCP4728_Channel_t; typedef enum { MCP4728_VREF_VDD 0, MCP4728_VREF_INTERNAL_2V 1 } MCP4728_Vref_t; // mcp4728.c extern I2C_HandleTypeDef hi2c1; // 假设使用I2C1 /** * brief 向MCP4728发送数据 * param pData: 指向发送数据缓冲区的指针 * param size: 数据大小 * retval HAL status */ static HAL_StatusTypeDef MCP4728_Write(uint8_t *pData, uint16_t size) { return HAL_I2C_Master_Transmit(hi2c1, MCP4728_I2C_ADDR_WRITE, pData, size, HAL_MAX_DELAY); } /** * brief 从MCP4728读取数据 * param pData: 指向接收数据缓冲区的指针 * param size: 数据大小 * retval HAL status */ static HAL_StatusTypeDef MCP4728_Read(uint8_t *pData, uint16_t size) { return HAL_I2C_Master_Receive(hi2c1, MCP4728_I2C_ADDR_READ, pData, size, HAL_MAX_DELAY); }4.2 单通道与多通道输出电压控制这是最核心的功能。我们需要根据目标电压值计算出12位的DAC码并组装正确的I2C数据帧。/** * brief 设置单个DAC通道输出电压不保存到EEPROM * param channel: 通道选择 * param vref: 参考电压选择 * param voltage_mV: 目标电压单位毫伏 * note 假设使用VDD或内部2.048V基准且增益为1。需根据实际VREF计算满量程。 * retval HAL status */ HAL_StatusTypeDef MCP4728_SetVoltage(MCP4728_Channel_t channel, MCP4728_Vref_t vref, uint16_t voltage_mV) { uint8_t data[3]; uint16_t dac_code; uint16_t full_scale_mV; // 1. 计算满量程电压 if (vref MCP4728_VREF_VDD) { // 假设VDD3300mV。实际应用中最好测量或使用精确的基准。 full_scale_mV 3300; } else { // 内部2.048V基准增益1 full_scale_mV 2048; } // 2. 计算12位DAC码值并做饱和处理 // 公式DAC_CODE (voltage_mV * 4096) / full_scale_mV dac_code (uint32_t)voltage_mV * 4096 / full_scale_mV; if (dac_code 4095) dac_code 4095; // 3. 组装I2C数据帧 // 字节1: 命令字节。示例快速写入更新指定通道使用指定VREF。 // 位7-5: 命令(010)位4: VREF位3: PDx(0)位2-1: 通道选择位0: 保留(0) data[0] MCP4728_CMD_WRITE_DAC_REG | (vref 4) | (channel 1); // 字节2: DAC数据高8位 (D11-D4) data[1] (dac_code 4) 0xFF; // 字节3: DAC数据低4位左移4位 (D3-D0 4) data[2] (dac_code 4) 0xF0; // 4. 发送数据 return MCP4728_Write(data, 3); } /** * brief 快速设置四个通道的电压单次I2C传输 * param voltages_mV: 包含四个通道目标电压毫伏的数组 * param vref: 参考电压选择此处假设所有通道相同 * retval HAL status * note 此函数使用“多写”命令一次性更新所有通道的DAC寄存器输出不同步除非LDAC接地。 */ HAL_StatusTypeDef MCP4728_SetAllVoltages(uint16_t voltages_mV[4], MCP4728_Vref_t vref) { uint8_t data[9]; // 1字节命令 4通道 * 2字节数据 uint16_t dac_codes[4]; uint16_t full_scale_mV (vref MCP4728_VREF_VDD) ? 3300 : 2048; data[0] 0x40; // 快速写入命令后续跟多通道数据 for (int i 0; i 4; i) { // 计算每个通道的码值 dac_codes[i] (uint32_t)voltages_mV[i] * 4096 / full_scale_mV; if (dac_codes[i] 4095) dac_codes[i] 4095; // 填充数据每个通道占2字节高字节在前低4位在低字节的高4位 data[1 i*2] (dac_codes[i] 4) 0xFF; // 高8位 data[2 i*2] (dac_codes[i] 4) 0xF0; // 低4位左移 // 注意低字节的低4位用于配置增益、PD模式此处默认为0正常模式增益1 } return MCP4728_Write(data, 9); }4.3 EEPROM读写操作与上电加载配置写入EEPROM是关键操作需要特别注意时序和寿命。/** * brief 将当前所有DAC通道的配置和码值保存到EEPROM * param vref: 要保存的参考电压配置所有通道共用 * note 此操作耗时较长~25ms期间芯片不响应I2C。需延迟等待。 * retval HAL status */ HAL_StatusTypeDef MCP4728_SaveToEEPROM(MCP4728_Vref_t vref) { uint8_t data[3]; // 假设我们保存通道A的当前码值例如0x800到EEPROM并连带配置 uint16_t dac_code_to_save 0x800; // 示例值 // 组装写入EEPROM的命令和数据 // 命令字节0x60 | (vref 4) | (channel 1)。这里以通道A为例。 data[0] MCP4728_CMD_WRITE_DAC_REG_EEPROM | (vref 4) | (MCP4728_CH_A 1); data[1] (dac_code_to_save 4) 0xFF; data[2] (dac_code_to_save 4) 0xF0; HAL_StatusTypeDef status MCP4728_Write(data, 3); if (status ! HAL_OK) { return status; } // *** 关键必须等待EEPROM写入完成 *** HAL_Delay(50); // 等待时间建议大于数据手册标注的25ms最大值确保可靠。 return HAL_OK; } /** * brief 从上电状态读取当前配置可选 * param pConfigData: 指向存储读取数据的缓冲区通常为24字节 * retval HAL status * note 读取操作可以获取所有通道的当前DAC寄存器值和EEPROM值。 */ HAL_StatusTypeDef MCP4728_ReadStatus(uint8_t *pConfigData) { // 发送读命令连续读取多个字节 // MCP4728的读操作比较简单直接启动读取即可芯片会连续输出状态数据 return MCP4728_Read(pConfigData, 24); // 根据数据手册最多可读24字节 }注意事项MCP4728_SaveToEEPROM函数中的HAL_Delay(50)是一个阻塞延迟在实际产品代码中尤其是在实时操作系统中这是一个糟糕的做法。它会占用CPU资源可能导致其他任务饿死。正确的做法是启动EEPROM写入后启动一个硬件定时器。在定时器中断或任务中检查是否已超过25ms。或者更优雅的方式是在写入后发送一个I2C通用呼叫复位命令0x06如果芯片响应说明EEPROM写入完成。但最简单可靠的方法还是使用非阻塞的软件定时器或RTOS的延时函数如vTaskDelay。5. 典型应用场景与实战案例理解了原理和驱动我们来看看MCP4728能在哪些地方大显身手。5.1 场景一可编程线性电源的基准电压设定在一个由MCU控制的线性稳压电源中输出电压通常由运算放大器和反馈电阻网络决定而基准电压Vref的精度和稳定性直接决定了输出电源的质量。使用MCP4728的一路通道配合内部2.048V基准可以生成一个高精度、可由软件动态设定的基准电压。实现思路将MCP4728的VOUTA连接到运放的正相输入端。运放接成电压跟随器或同相放大电路为后续的调整管如MOSFET提供基准。MCU通过I2C根据需要的输出电压计算出对应的DAC码值发送给MCP4728。MCP4728输出精确的模拟电压从而控制整个电源的输出。优势数字化控制输出电压可通过软件或通信接口如UART、CAN远程设置。高精度利用内部2.048V基准精度优于直接使用MCU的PWM加滤波。非易失性可将常用的电压值如3.3V 5.0V存入EEPROM实现上电即用。5.2 场景二多路传感器信号调理与激励在数据采集系统中经常需要为不同的传感器提供可调的激励电压或偏置电压。例如一个桥式压力传感器需要稳定的激励电压如5V同时其输出差分信号需要被偏置到ADC的共模电压范围内如1.65V。实现思路使用MCP4728的通道A输出稳定的5V在VDD5V时码值设为4095作为传感器激励。使用通道B输出1.65V作为仪表放大器的参考电压偏置电压。另外两个通道C和D可以预留用于其他传感器的偏置或增益调节。优势四通道独立一路给激励一路给偏置互不干扰。同步性如果需要多路传感器同步上电激励可以利用LDAC引脚实现硬件同步。简化设计无需多个基准源和电位器电路简洁易于校准。5.3 场景三生成简易音频或波形信号虽然MCP4728的建立时间典型值6μs和更新速率受限于I2C总线速度不适合生成高频复杂波形但对于生成低频信号、提示音或简单的函数波形正弦波、三角波还是可行的。实现思路以生成1kHz正弦波为例在MCU中预先计算好一个周期正弦波的4096个采样点12位精度存储为数组。配置一个硬件定时器中断频率为1kHz * 每个周期的点数例如100Hz波形100个点则定时器频率为10kHz。在定时器中断服务程序中通过I2C将下一个采样点的DAC码值写入MCP4728。使用快速模式I2C400kHz理论上最大更新率约为 400kbps / (8 bits/byte * 3 bytes) ≈ 16.7 kHz。这对于生成几百赫兹的波形是足够的。代码片段示例// 预计算正弦波表100个点12位偏置在2048左右 uint16_t sine_wave_table[100]; void GenerateSineTable() { for (int i 0; i 100; i) { sine_wave_table[i] (uint16_t)(2048.0 2047.0 * sin(2 * 3.14159 * i / 100.0)); } } // 定时器中断服务程序 void TIMx_IRQHandler(void) { if (__HAL_TIM_GET_FLAG(htimx, TIM_FLAG_UPDATE) ! RESET) { __HAL_TIM_CLEAR_FLAG(htimx, TIM_FLAG_UPDATE); static uint8_t index 0; MCP4728_SetVoltage(MCP4728_CH_A, MCP4728_VREF_VDD, sine_wave_table[index]); // 注意这里电压参数是码值需调整函数 index (index 1) % 100; } }局限性由于I2C通信开销和MCP4728自身的建立时间这种方法生成的波形频率上限较低且会占用大量CPU中断资源。对于真正的音频应用应选用带有DMA支持的高速DAC或专用音频编解码器。6. 调试技巧、常见问题与避坑指南即使按照手册设计实际调试中也可能遇到各种问题。这里分享一些实战中积累的经验。6.1 I2C通信失败排查清单这是最常见的问题。请按以下顺序排查物理连接确认SCL、SDA、VDD、GND连接正确且牢固。用万用表测量VDD电压是否正常。上拉电阻确认SCL和SDA线上有上拉电阻通常4.7kΩ且电阻值合适。绝对不要忘记地址引脚确认A0/A1/A2引脚被明确上拉或下拉绝不能悬空。用万用表测量其电压是否符合预期。I2C初始化确认MCU的I2C外设已正确初始化时钟、引脚复用。尝试用该I2C接口读写一个已知好的设备如AT24C02 EEPROM来验证MCU端配置。逻辑分析仪/示波器这是终极武器。抓取SCL和SDA的波形。看起始条件SDA在SCL高电平时拉低。看地址字节发送的7位地址读写位是否正确从机是否回复了ACK第9个时钟周期SDA被拉低看数据后续的数据字节和ACK是否正常看停止条件SDA在SCL高电平时拉高。电源噪声如果电源噪声大可能导致I2C时序错乱。确保电源去耦电容已焊接且靠近芯片引脚。总线冲突总线上是否有其他设备地址冲突尝试单独连接MCP4728测试。6.2 输出噪声大、不稳定怎么办DAC输出有噪声或毛刺通常源于电源或数字干扰。加强电源滤波在MCP4728的VDD引脚增加一个磁珠如600Ω100MHz串联再配合10μF和0.1μF电容可以有效隔离来自数字电路的噪声。输出端加RC滤波在VOUT引脚串联一个10Ω-100Ω的电阻再对地接一个0.1μF的陶瓷电容构成一个低通滤波器可以滤除高频噪声。截止频率 f_c 1/(2πRC)。例如R100Ω C0.1μF f_c ≈ 16kHz。优化PCB布局将模拟部分MCP4728及其滤波电路与数字部分MCU、晶振分开布局。为模拟部分提供独立的电源走线并在一点接入电源平面。VDD和GND的走线尽量粗短。避免数字信号线特别是时钟线、PWM线靠近MCP4728的模拟走线或从其下方穿过。6.3 EEPROM写入失败或数据丢失写入时间不足这是最主要的原因。写入EEPROM后必须等待足够长的时间至少50ms才能进行下一次I2C操作。使用阻塞延时HAL_Delay(50)是最简单的方法但在实时系统中需优化。写入次数超限EEPROM有擦写寿命约100万次。如果应用程序频繁保存数据很快就会耗尽。务必避免在循环或高频中断中调用EEPROM写入函数。只在必要的时候如用户保存设置、设备校准后才写入。电源跌落在写入EEPROM过程中如果电源电压跌落过大可能导致写入失败或数据错误。确保电源稳定或在写入期间禁止可能引起大电流突变的操作。6.4 精度达不到预期如何校准即使使用内部基准不同芯片之间也存在增益误差和偏移误差。对于要求高的应用可以进行两点校准。准备一个高精度的数字万用表至少4位半。测量设置DAC输出码值为00x000测量实际输出电压V0偏移误差。设置DAC输出码值为满量程0xFFF测量实际输出电压Vfs增益误差。计算理想的传输函数是Vout_ideal (Vref * Code) / 4096。实际函数近似为Vout_real Gain * Code Offset。Offset V0Gain (Vfs - V0) / 4095补偿在软件中当你需要输出一个目标电压Vtarget时反向计算所需的CodeCode_calibrated (Vtarget - Offset) / Gain将计算出的浮点数Code_calibrated四舍五入到最接近的整数再发送给DAC。存储将计算出的Offset和Gain系数存入MCU的Flash或MCP4728的EEPROM如果空间允许可以存校准后的查找表。通过这样的软件校准可以显著提高系统的绝对精度。MCP4728的12位分辨率为你提供了进行精细校准的足够空间。

相关新闻