STM32F107VC与PCF8591的I2C通信与信号采集实现

发布时间:2026/9/7 19:50:14

STM32F107VC与PCF8591的I2C通信与信号采集实现
1. 项目概述PCF8591与STM32F107VC的协同工作在嵌入式系统开发中模拟信号与数字信号的相互转换是基础且关键的一环。PCF8591作为一款集成了ADC模数转换器和DAC数模转换器功能的芯片通过I2C接口与主控芯片通信能够同时处理多路模拟信号的输入和输出。而STM32F107VC作为STMicroelectronics推出的高性能ARM Cortex-M3内核微控制器具备丰富的外设接口和强大的处理能力是工业控制、消费电子等领域的常用选择。将PCF8591与STM32F107VC结合使用可以实现灵活的信号采集与输出控制。这种组合特别适合需要同时进行多通道模拟信号采集和输出的应用场景比如环境监测系统同时采集温度、湿度、光照等传感器信号、工业控制系统同时监控多个模拟量并输出控制信号等。PCF8591的I2C接口设计使得硬件连接简单只需要两根信号线SDA和SCL即可实现通信大大简化了系统布线。2. 硬件设计与连接2.1 PCF8591模块介绍PCF8591是一款单芯片、单电源、低功耗的8位CMOS数据采集器件具有4路模拟输入可配置为单端或差分输入、1路模拟输出和一个串行I2C总线接口。其主要特性包括工作电压范围2.5V至6V4路模拟输入通道可编程为单端或差分输入1路模拟输出DAC片上跟踪保持功能8位逐次逼近型A/D转换器通过I2C总线串行输入/输出3个硬件地址引脚允许最多8个器件连接到同一I2C总线采样率取决于I2C总线速度PCF8591模块通常包含必要的去耦电容和I2C上拉电阻方便直接与微控制器连接。模块上的排针接口一般包括SDAI2C数据线SCLI2C时钟线VCC电源正极2.5-6VGND地线AIN0-AIN34路模拟输入AOUT模拟输出2.2 STM32F107VC的I2C接口配置STM32F107VC微控制器内置了多个I2C接口我们需要根据硬件设计选择合适的I2C端口进行配置。以下是配置步骤在STM32CubeMX中启用I2C外设打开Clock Configuration确保I2C时钟源已启用在Pinout Configuration选项卡中找到I2C模块选择I2C模式为I2C配置SCL和SDA引脚如PB6和PB7对应I2C1配置I2C参数时钟速度标准模式100kHz或快速模式400kHz时钟拉伸根据需要启用主模式7位地址模式自己的I2C地址可设置为0作为主设备时通常不需要生成代码后在工程中添加以下初始化代码hi2c1.Instance I2C1; hi2c1.Init.ClockSpeed 100000; hi2c1.Init.DutyCycle I2C_DUTYCYCLE_2; hi2c1.Init.OwnAddress1 0; hi2c1.Init.AddressingMode I2C_ADDRESSINGMODE_7BIT; hi2c1.Init.DualAddressMode I2C_DUALADDRESS_DISABLE; hi2c1.Init.OwnAddress2 0; hi2c1.Init.GeneralCallMode I2C_GENERALCALL_DISABLE; hi2c1.Init.NoStretchMode I2C_NOSTRETCH_DISABLE; if (HAL_I2C_Init(hi2c1) ! HAL_OK) { Error_Handler(); }2.3 硬件连接示意图将PCF8591模块与STM32F107VC开发板连接时需要确保以下连接正确PCF8591引脚STM32F107VC引脚备注VCC3.3V或5V根据模块要求选择电压GNDGND共地非常重要SDAPB7 (I2C1_SDA)数据线SCLPB6 (I2C1_SCL)时钟线AIN0-AIN3传感器输出模拟输入通道AOUT负载设备模拟输出注意如果PCF8591模块上没有集成上拉电阻需要在SDA和SCL线上各添加一个4.7kΩ的上拉电阻到VCC。3. 软件驱动开发3.1 PCF8591的寄存器配置PCF8591通过I2C接口进行配置和数据传输其控制寄存器定义如下位名称功能描述7:6模拟输入模式00四路单端输入01三路差分输入10单端与差分混合11两路差分输入5:4自动增量标志00禁止自动增量01通道0自动增量10通道1自动增量11通道2自动增量3模拟输出使能0禁止模拟输出1使能模拟输出2:0通道选择000通道0001通道1010通道2011通道3在STM32上我们可以编写以下函数来配置PCF8591#define PCF8591_ADDRESS 0x48 // 默认地址可通过A0-A2引脚修改 void PCF8591_Init(I2C_HandleTypeDef *hi2c, uint8_t config) { uint8_t tx_data[2] {0x40, config}; // 0x40是控制字节config是配置参数 HAL_I2C_Master_Transmit(hi2c, PCF8591_ADDRESS 1, tx_data, 2, HAL_MAX_DELAY); }3.2 ADC数据采集实现PCF8591的ADC转换是8位精度的转换结果通过I2C接口读取。以下是读取ADC值的函数实现uint8_t PCF8591_ReadADC(I2C_HandleTypeDef *hi2c, uint8_t channel) { uint8_t config 0x40 | (channel 0x03); // 设置通道并保持模拟输出使能 uint8_t rx_data[2] {0}; // 先写入配置寄存器 HAL_I2C_Master_Transmit(hi2c, PCF8591_ADDRESS 1, config, 1, HAL_MAX_DELAY); // 读取转换结果第一个字节是前一次转换的值 HAL_I2C_Master_Receive(hi2c, PCF8591_ADDRESS 1, rx_data, 2, HAL_MAX_DELAY); return rx_data[1]; // 返回最新的转换值 }为了提高采样精度可以添加多次采样取平均的功能uint8_t PCF8591_ReadADC_Average(I2C_HandleTypeDef *hi2c, uint8_t channel, uint8_t samples) { uint32_t sum 0; for(uint8_t i0; isamples; i) { sum PCF8591_ReadADC(hi2c, channel); HAL_Delay(1); // 适当延时 } return (uint8_t)(sum / samples); }3.3 DAC输出实现PCF8591的DAC输出也是8位精度的输出电压范围为0到Vref通常为VCC。以下是设置DAC输出的函数void PCF8591_WriteDAC(I2C_HandleTypeDef *hi2c, uint8_t value) { uint8_t tx_data[2] {0x40, value}; // 0x40表示使能模拟输出 HAL_I2C_Master_Transmit(hi2c, PCF8591_ADDRESS 1, tx_data, 2, HAL_MAX_DELAY); }如果需要输出特定电压可以编写以下辅助函数void PCF8591_SetVoltage(I2C_HandleTypeDef *hi2c, float voltage, float vref) { if(voltage vref) voltage vref; if(voltage 0) voltage 0; uint8_t dac_value (uint8_t)((voltage / vref) * 255); PCF8591_WriteDAC(hi2c, dac_value); }4. 系统集成与优化4.1 多通道采样策略当需要同时采集多个通道的模拟信号时可以采用以下策略轮询方式依次读取每个通道的值void ReadAllChannels(I2C_HandleTypeDef *hi2c, uint8_t *results) { for(uint8_t ch0; ch4; ch) { results[ch] PCF8591_ReadADC(hi2c, ch); HAL_Delay(10); // 通道间适当延时 } }自动增量模式利用PCF8591的自动增量功能连续读取多个通道void ReadAllChannels_AutoIncrement(I2C_HandleTypeDef *hi2c, uint8_t *results) { uint8_t config 0x44; // 使能自动增量从通道0开始 uint8_t rx_data[5] {0}; // 写入配置 HAL_I2C_Master_Transmit(hi2c, PCF8591_ADDRESS 1, config, 1, HAL_MAX_DELAY); // 读取4个通道的值第一个字节是无效数据 HAL_I2C_Master_Receive(hi2c, PCF8591_ADDRESS 1, rx_data, 5, HAL_MAX_DELAY); // 提取有效数据 for(uint8_t i0; i4; i) { results[i] rx_data[i1]; } }4.2 采样速率优化PCF8591的采样速率主要受限于I2C总线速度。在标准模式(100kHz)下完成一次转换大约需要启动信号约5μs发送设备地址写9个时钟周期约90μs发送控制字节9个时钟周期约90μs重复启动信号约5μs发送设备地址读9个时钟周期约90μs读取数据18个时钟周期2字节约180μs停止信号约5μs 总计约465μs即最大采样率约2.15kHz。如果将I2C设置为快速模式(400kHz)理论上可以将采样率提高到约8.6kHz。但需要注意PCF8591支持的最高I2C速度为100kHz超过可能导致通信失败实际采样率还受STM32处理速度、中断延迟等因素影响4.3 噪声抑制与滤波在实际应用中模拟信号容易受到噪声干扰可以采取以下措施提高信号质量硬件滤波在每个模拟输入通道添加RC低通滤波器如1kΩ电阻和0.1μF电容确保电源稳定添加适当的去耦电容10μF电解电容并联0.1μF陶瓷电容使用屏蔽线连接敏感信号源软件滤波移动平均滤波#define FILTER_SIZE 8 typedef struct { uint8_t buffer[FILTER_SIZE]; uint8_t index; uint16_t sum; } MovingAverageFilter; uint8_t UpdateFilter(MovingAverageFilter *filter, uint8_t new_value) { filter-sum - filter-buffer[filter-index]; filter-sum new_value; filter-buffer[filter-index] new_value; filter-index (filter-index 1) % FILTER_SIZE; return (uint8_t)(filter-sum / FILTER_SIZE); }中值滤波uint8_t MedianFilter(uint8_t *buffer, uint8_t size) { // 简单的冒泡排序 for(uint8_t i0; isize-1; i) { for(uint8_t ji1; jsize; j) { if(buffer[j] buffer[i]) { uint8_t temp buffer[i]; buffer[i] buffer[j]; buffer[j] temp; } } } return buffer[size/2]; }4.4 实际应用示例环境监测系统结合PCF8591和STM32F107VC我们可以构建一个简单的环境监测系统同时采集温度、湿度、光照和空气质量数据并通过DAC输出控制信号void EnvironmentMonitoringTask(void) { uint8_t adc_values[4]; float temperature, humidity, light, air_quality; // 读取所有通道 ReadAllChannels_AutoIncrement(hi2c1, adc_values); // 转换为实际物理量假设传感器特性 temperature adc_values[0] * 0.5f; // 假设50℃满量程 humidity adc_values[1] * 0.4f; // 假设40%RH满量程 light adc_values[2] / 2.55f; // 转换为百分比 air_quality adc_values[3] * 0.2f; // 假设空气质量指数 // 根据环境条件控制输出 if(temperature 30.0f || humidity 70.0f) { PCF8591_WriteDAC(hi2c1, 255); // 全开通风 } else { PCF8591_WriteDAC(hi2c1, 0); // 关闭通风 } // 可以通过串口输出监测数据 printf(Temp: %.1fC, Humi: %.1f%%, Light: %.1f%%, Air: %.1f\r\n, temperature, humidity, light, air_quality); }5. 常见问题与调试技巧5.1 I2C通信失败排查当PCF8591与STM32通信失败时可以按照以下步骤排查检查硬件连接确认VCC和GND连接正确检查SDA和SCL线是否接反确认上拉电阻通常4.7kΩ已正确连接检查I2C地址使用I2C扫描工具确认PCF8591的地址默认地址是0x48A0A1A20可通过硬件引脚修改检查时序确保I2C时钟速度不超过PCF8591支持的100kHz在关键位置添加调试输出确认程序执行流程使用逻辑分析仪捕获I2C总线波形检查起始条件、地址、ACK等信号确认数据是否符合预期5.2 ADC读数不稳定问题如果ADC读数波动较大可以尝试以下解决方法检查电源质量测量VCC电压是否稳定在VCC和GND之间添加更大的去耦电容优化PCB布局缩短模拟信号走线长度避免模拟信号线与数字信号线平行走线软件优化增加采样次数并取平均添加软件滤波算法如前面介绍的移动平均或中值滤波检查信号源确认传感器输出是否稳定必要时在信号源端添加缓冲放大器5.3 DAC输出精度问题当DAC输出不符合预期时可以检查参考电压PCF8591的DAC输出范围是0到VCC确保VCC稳定如果需要更高精度可以使用外部精密参考电压负载阻抗DAC输出驱动能力有限典型值1mA确保负载阻抗足够大对于低阻抗负载添加运算放大器缓冲线性度测试输出从0到255的代码测量实际电压检查是否存在明显的非线性5.4 多设备I2C总线管理当系统中存在多个I2C设备时包括多个PCF8591需要注意地址分配利用PCF8591的A0/A1/A2引脚设置不同地址确保每个设备有唯一地址总线负载总线电容不超过400pF标准模式或100pF快速模式必要时使用I2C缓冲器如PCA9515错误处理添加I2C通信超时机制实现总线恢复功能如时钟拉伸超时后重新初始化// I2C总线恢复函数示例 void I2C_Recovery(I2C_HandleTypeDef *hi2c) { GPIO_InitTypeDef GPIO_InitStruct {0}; // 1. 将SDA和SCL配置为GPIO输出 GPIO_InitStruct.Pin GPIO_PIN_6|GPIO_PIN_7; // 假设使用PB6(SCL)和PB7(SDA) GPIO_InitStruct.Mode GPIO_MODE_OUTPUT_OD; GPIO_InitStruct.Pull GPIO_NOPULL; GPIO_InitStruct.Speed GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOB, GPIO_InitStruct); // 2. 发送9个时钟脉冲 for(uint8_t i0; i9; i) { HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET); // SCL低 HAL_Delay(1); HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET); // SCL高 HAL_Delay(1); } // 3. 发送停止条件 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_RESET); // SDA低 HAL_Delay(1); HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET); // SCL高 HAL_Delay(1); HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_SET); // SDA高 HAL_Delay(1); // 4. 重新配置为I2C MX_I2C1_Init(); // 重新初始化I2C }

相关新闻

PCF8591与PIC18F4610在工业数据采集中的应用

PCF8591与PIC18F4610在工业数据采集中的应用

2026/9/7 16:35:54

1. 项目背景与核心器件选型在嵌入式系统开发中,模拟信号与数字信号的相互转换是最基础也最关键的环节之一。我最近完成了一个工业传感器数据采集项目,需要同时处理多路模拟信号输入和输出控制,最终选择了PCF8591 ADC/DAC转换芯片与PIC18F4610…

用 GPT Researcher 前,先验证“资料来源合同”

用 GPT Researcher 前,先验证“资料来源合同”

2026/8/30 5:28:28

GPT Researcher 不应该被当成一个更会写的搜索框。更准确的用法是把它看成研究流水线:从一个 query 出发,拆子问题,调用 retriever 找候选来源,抓取网页或文档,整理上下文,再写出带引用的长报告。 这条流水…

TPS65263三路降压转换器与PIC18F25K42的电源管理方案

TPS65263三路降压转换器与PIC18F25K42的电源管理方案

2026/8/27 16:57:23

1. 项目背景与核心器件选型在嵌入式系统设计中,电源管理模块往往决定了整个系统的稳定性和能效表现。传统单路降压方案已无法满足现代多核处理器、传感器阵列和通信模块的复杂供电需求。TPS65263作为德州仪器推出的三路同步降压转换器,配合PIC18F25K42微…

NearLink技术解析:智能汽车无线通信的新选择,对比蓝牙与Wi-Fi的优势

NearLink技术解析:智能汽车无线通信的新选择,对比蓝牙与Wi-Fi的优势

2026/9/7 19:42:18

1. 为什么智能汽车需要一门新的无线技术:从手机耳机到座舱域控聊到智能汽车里的无线连接,很多人第一反应是蓝牙、Wi-Fi、UWB这些老面孔。确实,从车钥匙到车载蓝牙电话再到手机互联,这几项技术撑起了过去十年的智能座舱体验。但这两…

微信小程序书院预约系统:从数据模型到答辩实战

微信小程序书院预约系统:从数据模型到答辩实战

2026/9/7 19:42:18

每年毕业季,我都会收到一批“小程序预约”方向的求助,其中“基于微信小程序的书院预约系统”出镜率相当高。这个题目看起来特别友好:界面在手机上展示效果好,后端逻辑不算复杂,又是高校里真实存在的场景。但恰恰因为“…

MySQL索引失效与慢SQL优化实战:从EXPLAIN到联合索引设计

MySQL索引失效与慢SQL优化实战:从EXPLAIN到联合索引设计

2026/9/7 19:42:17

1. 索引失效的底层逻辑:优化器的选择困境1.1 为什么明明建了索引,查询却还是慢做SQL优化这几年,我见过太多开发者栽在同一道坎上:表里明明建了索引,EXPLAIN一看却是ALL全表扫描,慢查询日志里整天躺着那条“…

信创OA部署实战指南:从环境选型到上线避坑

信创OA部署实战指南:从环境选型到上线避坑

2026/9/7 19:42:17

第一次给某集团做信创OA部署的时候,我拿到手的是一台ARM架构服务器、一张麒麟V10的安装盘,还有一页写得不算详细的部署文档。当时团队几个人刚结束传统x86环境上的OA项目,谁都没想到后面两周踩的坑能排满三页纸。信创OA部署这件事&#xff0c…

数组全解析:从内存寻址到算法应用的完整指南

数组全解析:从内存寻址到算法应用的完整指南

2026/9/7 19:42:17

1. 数组到底是什么:从“一排储物柜”说起我第一次上《数据结构》课的时候,老师问了一个问题:“你们每天都在用数组,但谁能说清楚数组为什么叫‘数组’?”当时全班沉默了。后来我自己做开发、带新人,发现绝大…

福昕PDF编辑器便携版:从部署到实战的完整指南

福昕PDF编辑器便携版:从部署到实战的完整指南

2026/9/7 19:32:17

1. 项目概述:为什么我最终留下了福昕PDF编辑器便携版 日常工作绕不开PDF,无论是合同签署、标书制作,还是论文排版、报表归档,PDF都是最终交付格式。但PDF在诞生之初,设计逻辑侧重“固定版式”而非“编辑修改”&#xf…

中国人民大学杨琳团队《Nature Communications》 | 全球潮汐湿地土壤有机碳时空格局与环境驱动:一项2009-2020年的全球评估

中国人民大学杨琳团队《Nature Communications》 | 全球潮汐湿地土壤有机碳时空格局与环境驱动:一项2009-2020年的全球评估

2026/9/6 1:19:56

本文首发于“生态学者”!从“湿地面积”到“土壤碳密度”:为什么需要重新认识潮汐湿地蓝碳变化?潮汐湿地位于陆地与海洋的交汇地带,包括红树林、盐沼和潮滩,是全球重要的蓝碳生态系统。其土壤能够长期储存大量有机碳&a…

adb抓包

adb抓包

2026/9/7 3:44:24

前言 本文介绍如何通过 tcpdump 在 Android 手机上抓取网络数据包,并在电脑端使用 Wireshark 进行分析。适用于需要排查 App 网络请求、分析接口调用或调试网络问题的开发与测试场景。1. 手机要有 root 权限2. 下载 tcpdump3. adb push C:\Users\zhangkuixun\Downlo…

大模型推理镜像极简瘦身:从 25GB 巨无霸到 3GB 精简镜像实战

大模型推理镜像极简瘦身:从 25GB 巨无霸到 3GB 精简镜像实战

2026/9/7 8:03:37

大模型推理镜像极简瘦身:从 25GB 巨无霸到 3GB 精简镜像实战 在云原生基础设施中,容器镜像体积直接决定了服务的部署速度与弹性扩容敏捷度。对于传统的 Go / Java 微服务,镜像体积通常被严格控制在 50MB 到 200MB 以内,拉取镜像只…

基于YOLOv8和PyQt5的麦穗稻穗检测识别系统设计与实现

基于YOLOv8和PyQt5的麦穗稻穗检测识别系统设计与实现

2026/9/7 0:01:24

这次我们来看一个把目标检测算法和桌面端工具结合得很典型的项目:基于 YOLOv8 PyQt5 的麦穗稻穗检测识别系统。这个项目本身不是新概念,但它的价值在于落地形态很完整。YOLOv8 负责核心的麦穗稻穗目标检测,PyQt5 负责提供可视化的桌面交互界…

UL 1642锂电池安全标准全解析:测试项目、认证流程与避坑指南

UL 1642锂电池安全标准全解析:测试项目、认证流程与避坑指南

2026/9/7 0:01:24

简介:UL 1642是锂电池安全领域的重要规范,本中文版资源适合锂电池制造商、检测机构工程师及产品认证相关人员阅读,用于理解电池在设计与制造层面的安全要求、测试方法与合规要点。资源共1个PDF文件,压缩包大小834KB,便…

BS EN 13814-1-2019游乐设施安全标准:设计与制造核心要点解析

BS EN 13814-1-2019游乐设施安全标准:设计与制造核心要点解析

2026/9/7 0:01:24

简介:BS EN 13814-1:2019是英国采纳欧洲标准EN 13814-1:2019的正式版本,由BSI标准出版,重点规定游乐设施和游乐设备在设计与制造环节的安全准则,与BS EN 13814-2:2019、BS EN 13814-3:2019共同取代旧版BS EN 13814:2004。该标准面…

远程协作的工作台整理

远程协作的工作台整理

2026/9/7 3:38:07

远程协作的工作台整理远程协作的核心不是再加一个工具,而是让交接信息足够完整。异步任务要写明目标、输入位置、完成标准和需要决策的人。 工作台的最小配置 将日程、待办、代码和沟通入口收拢到少数固定位置;通知按紧急程度分层。工作台不需要模仿办公…

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

2026/9/4 7:42:10

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

2026/9/6 23:21:51

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…