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

发布时间:2026/8/27 11:11:11

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/8/26 21:12:34

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

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

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

2026/8/27 11:22:59

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

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

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

2026/8/22 19:50:23

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

CyberEdge实战教程:cyberedge-agent JSON桥接与gRPC协议契约上手

CyberEdge实战教程:cyberedge-agent JSON桥接与gRPC协议契约上手

2026/8/27 15:38:06

CyberEdge实战教程:cyberedge-agent JSON桥接与gRPC协议契约上手 【免费下载链接】CyberEdge 互联网资产综合扫描/攻击面测绘 项目地址: https://gitcode.com/gh_mirrors/cy/CyberEdge CyberEdge 是一个面向互联网资产综合扫描与攻击面测绘的 AI 原生外部攻击…

如何玩转org-roam-bibtex的Helm与Ivy补全界面:orb-helm与orb-ivy设计完全指南

如何玩转org-roam-bibtex的Helm与Ivy补全界面:orb-helm与orb-ivy设计完全指南

2026/8/27 15:38:06

如何玩转org-roam-bibtex的Helm与Ivy补全界面:orb-helm与orb-ivy设计完全指南 【免费下载链接】org-roam-bibtex Org Roam integration with bibliography management software 项目地址: https://gitcode.com/gh_mirrors/or/org-roam-bibtex 如果你在用 Em…

AI智能体记忆全解析:从RAG到读写能力的技术演进!

AI智能体记忆全解析:从RAG到读写能力的技术演进!

2026/8/27 15:38:06

在学习 AI 智能体(AI Agents)的记忆相关知识时,被各种新术语搞得不知所措。一开始是 “短期记忆” 和 “长期记忆”,后来又出现了 “程序性记忆”、“情景记忆” 和 “语义记忆”,这就更混乱了。但等等,“语…

跨境电商的解决方案是什么?2026 年跨境卖家必须搞懂的数据驱动逻辑

跨境电商的解决方案是什么?2026 年跨境卖家必须搞懂的数据驱动逻辑

2026/8/27 15:38:06

跨境电商的解决方案,这几年在跨境圈里被反复提及。很多卖家以为 “方案” 就是多买几个系统 —— 上个 ERP 管库存、上个 BI 看数据、上个广告工具调投放。结果系统越买越多,数据越管越乱,该亏的钱一分没少亏。2026 年全球跨境电商 B2C 市场规…

AI大模型新概念解析与大模型的区别!

AI大模型新概念解析与大模型的区别!

2026/8/27 15:38:06

AI大模型爆火后,各种新概念层出不穷。面对这些令人眼花缭乱的名词,很多人想了解可能无从下手无论你现在从事什么职业,我都强烈建议你了解一个关键概念:AI智能体。 就像你已经习惯用豆包、DeepSeek来解决信息检索和文案草拟等问题一…

把 Cosmic Ray 变异测试接入 CI:GitHub Actions 工作流 + cr-badge 存活率徽章完整指南

把 Cosmic Ray 变异测试接入 CI:GitHub Actions 工作流 + cr-badge 存活率徽章完整指南

2026/8/27 15:28:06

把 Cosmic Ray 变异测试接入 CI:GitHub Actions 工作流 cr-badge 存活率徽章完整指南 【免费下载链接】cosmic-ray Mutation testing for Python 项目地址: https://gitcode.com/gh_mirrors/co/cosmic-ray Cosmic Ray 是一款面向 Python 3 的**变异测试&…

[光学原理与应用-521]:对光的错误理解与纠偏

[光学原理与应用-521]:对光的错误理解与纠偏

2026/8/27 11:10:02

首先光是一种能量的载体和形态,宏观上观察到的光是由无数个微观的光量子组成的,每个光子在产生的瞬间,其在真空的空间中以确定不变的速度沿着一个初始的方向一直向前,在微观层面,每个光量子的运动轨迹是以波函数所展现…

SIP通话转接原理与REFER方法实战解析

SIP通话转接原理与REFER方法实战解析

2026/8/27 7:25:23

1. 通话转接不是“挂断再拨号”,而是SIP会话的动态重定向你有没有遇到过这样的场景:客服坐席A正在和客户通电话,突然需要把这通对话无缝转给专家坐席B,客户完全感知不到中间的断连——既没听到忙音,也没被要求重新拨号…

Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

2026/8/26 17:50:58

1. 为什么选择Kolla-ansible来部署单节点OpenStack?如果你正在寻找一种能把OpenStack从“概念”快速变成“可用的实验环境”的方法,那么Kolla-ansible几乎是当前最主流、最省心的选择。我见过太多人卡在手动编译依赖、配置服务、处理版本冲突的泥潭里&am…

Go语言构建企业级AI服务网关:统一管理英伟达等AI接口调用

Go语言构建企业级AI服务网关:统一管理英伟达等AI接口调用

2026/8/27 0:07:12

1. 项目概述:从零构建一个企业级的AI服务网关 最近在帮一个做内容审核的团队做技术架构升级,他们原来的业务里,每天有几十万张图片和短视频需要过审,最初是接了几个开源的AI模型自己部署,但效果和性能一直不太稳定。后…

LeetCode Hot100(51-60)算法精解与面试技巧

LeetCode Hot100(51-60)算法精解与面试技巧

2026/8/27 0:07:12

1. 题目背景与核心价值"hot100(51-60)"这个标题看起来像是某个编程题库或算法练习集中的一组题目编号。在技术社区中,类似命名通常指向LeetCode、牛客网等平台的热门题目集合。作为刷过300题的算法老手,我理解这类题目的核心价值在于&#xff…

CRC校验实战:从模2除法到HJ212协议排错

CRC校验实战:从模2除法到HJ212协议排错

2026/8/27 0:07:12

1. 为什么一个“校验码”能扛住工业现场90%的数据 corruption? 你有没有遇到过这样的场景:嵌入式设备通过RS-485上传温湿度数据,上位机偶尔收到一帧乱码——温度显示成-273℃,湿度跳到999%,但串口波形看起来完全正常&a…

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

2026/8/22 2:02:26

一天写完毕业论文在2026年已不再是天方夜谭。2026年最炸裂、实测能大幅提速的AI论文写作工具,覆盖选题构思、文献整理、内容生成、格式排版等核心场景,真正帮你高效搞定论文难题。 一、全流程王者:一站式搞定论文全链路(一天定稿首…

导师推荐!2026最新AI论文工具测评与实用推荐

导师推荐!2026最新AI论文工具测评与实用推荐

2026/8/26 18:07:30

2026年真正好用的AI论文工具,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。 一、…

告别游戏崩溃:XCOM 2模组管理器的智能革命

告别游戏崩溃:XCOM 2模组管理器的智能革命

2026/8/26 17:57:52

告别游戏崩溃:XCOM 2模组管理器的智能革命 【免费下载链接】xcom2-launcher The Alternative Mod Launcher (AML) is a replacement for the default game launchers from XCOM 2 and XCOM Chimera Squad. 项目地址: https://gitcode.com/gh_mirrors/xc/xcom2-lau…