1. 项目概述多通道信号采集的硬件方案在嵌入式开发中经常需要同时采集多个模拟信号。传统做法是使用STM32内置ADC轮流采样但这会面临通道切换延迟、采样率受限等问题。PCF8591这款8位ADC转换芯片提供了4路模拟输入通道通过I2C接口与主控通信正好可以弥补单片机内置ADC的不足。我最近在一个工业传感器项目中就用STM32F765ZI搭配PCF8591实现了四路温度、压力信号的同步采集。实测发现这种组合不仅成本低廉PCF8591单价不到5元而且能稳定工作在复杂的电磁环境中。下面分享具体实现方法和踩过的一些坑。2. 硬件连接与电路设计2.1 PCF8591引脚功能解析这个8脚芯片的引脚布局非常精简AIN0-AIN34路模拟输入可配置为单端或差分模式A0-A2硬件地址引脚允许最多8个器件并联SDA/SCL标准的I2C通信接口VREF基准电压输入建议接3.3V与STM32一致AGND/DGND模拟/数字地建议通过0Ω电阻单点连接特别注意PCF8591是5V tolerant的但STM32F7的I2C引脚不是。如果系统中有其他5V设备必须加电平转换电路。2.2 STM32F765ZI的硬件配置以Nucleo-F765ZI开发板为例使用I2C1接口PB8/PB9在CubeMX中配置为Fast Mode400kHz开启DMA传输以减少CPU占用注意上拉电阻取值通常4.7kΩ实际接线示意图PCF8591 STM32F765ZI VCC ---- 3.3V GND ---- GND SDA ---- PB9 SCL ---- PB8 A0-A2 ---- GND默认地址0x483. 软件驱动开发3.1 I2C通信协议实现PCF8591的控制字节格式如下[7:6] 模拟输入模式选择00四路单端输入 [5:4] 自动增量标志11启用通道自动切换 [3] 模拟输出使能1启用DAC [2:0] 当前通道选择初始化代码示例HAL库uint8_t config 0x4C; // 单端输入自动增量 HAL_I2C_Mem_Write(hi2c1, 0x481, 0x40, 1, config, 1, 100);3.2 多通道数据采集流程发送控制字节启动转换通过DMA连续读取4字节每个通道1字节数据就绪后触发回调函数电压值换算Vout (ADC_value × VREF) / 255中断处理代码片段void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c) { temp_ch1 buffer[0] * 3.3 / 255; pressure buffer[1] * 3.3 / 255 * 100; // 假设传感器量程0-100kPa //...其他通道处理 }4. 实测性能优化技巧4.1 采样速率提升方案将I2C时钟提升到1MHz需缩短走线长度使用轮询模式替代中断牺牲实时性批量读取多个采样周期数据实测数据对比配置方式最大采样率中断模式400kHz800S/sDMA模式1MHz2.4kS/s4.2 精度改善措施外接精密基准电压源如REF3030在AIN引脚添加RC低通滤波截止频率10倍信号带宽软件上采用滑动平均滤波算法滤波算法实现示例#define FILTER_LEN 8 uint8_t filter_buf[FILTER_LEN]; uint8_t filter_index 0; uint8_t moving_avg(uint8_t new_val) { filter_buf[filter_index] new_val; if(filter_index FILTER_LEN) filter_index 0; uint16_t sum 0; for(int i0; iFILTER_LEN; i) sum filter_buf[i]; return sum / FILTER_LEN; }5. 典型问题排查指南5.1 I2C通信失败排查用逻辑分析仪抓取波形确认起始/停止条件是否正常从机地址是否正确默认0x48ACK/NACK响应状态检查硬件上拉电阻是否接好建议4.7kΩ电源是否存在毛刺线路长度是否超限I2C建议30cm5.2 数据跳变严重可能原因及对策电源噪声在VCC与GND间加100nF10μF电容信号干扰采用屏蔽线连接传感器接地环路改为星型接地拓扑基准电压不稳改用外部基准源6. 进阶应用与STM32内置ADC协同工作通过合理配置可以让PCF8591和STM32内置ADC协同采样用TIM触发内置ADC采样在ADC中断中启动PCF8591转换通过DMA统一收集数据这种架构特别适合需要同时采集快变信号用内置ADC和慢变信号用PCF8591的场景。我在一个电机控制项目中就用内置ADC采集电流10kS/s用PCF8591采集温度100S/s两者通过双缓冲机制实现数据同步。