尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

STM32引脚不够用?试试用PCF8574芯片扩展IO口(附完整I2C驱动代码)

STM32引脚不够用?试试用PCF8574芯片扩展IO口(附完整I2C驱动代码)
📅 发布时间:2026/7/1 9:29:13

STM32引脚不够用?试试用PCF8574芯片扩展IO口(附完整I2C驱动代码)

在STM32开发过程中,IO口资源不足是许多开发者都会遇到的痛点。无论是智能家居项目中的多路传感器采集,还是工业控制中的复杂设备联动,有限的MCU引脚往往成为制约项目扩展的瓶颈。本文将详细介绍如何利用PCF8574这款经典的I2C接口IO扩展芯片,轻松为STM32增加8个可编程IO口,并提供可直接复用的驱动代码和硬件连接方案。

1. PCF8574芯片核心特性与应用场景

PCF8574是NXP推出的一款I2C总线接口的8位IO扩展芯片,它通过简单的2线制I2C接口,就能为微控制器扩展出8个准双向IO口。这款芯片特别适合以下应用场景:

  • LED矩阵控制:驱动多个LED指示灯或数码管
  • 按键扫描:扩展矩阵键盘输入接口
  • 传感器集群:连接多个数字传感器(如温湿度、光照等)
  • 继电器控制:管理多路继电器开关

PCF8574的主要技术参数:

特性参数值
工作电压2.5V-6V
最大输出电流25mA/引脚
I2C时钟频率最高400kHz
待机电流<10μA
可寻址设备数8个(通过A0-A2引脚)

提示:PCF8574的准双向IO口设计意味着它不需要额外配置输入/输出方向,简化了编程接口。

2. 硬件连接与电路设计

2.1 基本连接原理图

PCF8574与STM32的连接非常简单,只需要4根线:

  1. I2C时钟线(SCL):连接STM32的I2C时钟引脚(如PB6)
  2. I2C数据线(SDA):连接STM32的I2C数据引脚(如PB7)
  3. 中断线(INT):可选,连接STM32的外部中断引脚
  4. 电源线(VCC/GND):连接3.3V或5V电源

典型连接电路如下:

+---------------+ | STM32 | | | | PB6----SCL | | PB7----SDA | | PA0----INT | +-------|-------+ | +-------|-------+ | PCF8574 | | A0-A2=GND | | P0-P7--LEDs | +---------------+

2.2 地址配置技巧

PCF8574通过A0-A2引脚可以设置不同的设备地址,允许在同一条I2C总线上挂载最多8个芯片:

// PCF8574基础地址为0x40,A0-A2接地时: #define PCF8574_ADDR 0x40 // 若A0接VCC,A1-A2接地: #define PCF8574_ADDR 0x42

3. 完整驱动代码实现

3.1 初始化与基本读写

首先需要实现I2C底层驱动,以下是基于HAL库的PCF8574驱动代码:

// pcf8574.h #ifndef __PCF8574_H #define __PCF8574_H #include "stm32f1xx_hal.h" #define PCF8574_ADDR 0x40 uint8_t PCF8574_Init(void); uint8_t PCF8574_ReadOneByte(void); void PCF8574_WriteOneByte(uint8_t Data); void PCF8574_WriteBit(uint8_t bit, uint8_t sta); uint8_t PCF8574_ReadBit(uint8_t bit); #endif
// pcf8574.c #include "pcf8574.h" #include "i2c.h" uint8_t PCF8574_Init(void) { uint8_t temp = 0; HAL_Delay(100); // 尝试读取设备是否响应 if(HAL_I2C_IsDeviceReady(&hi2c1, PCF8574_ADDR<<1, 3, 100) != HAL_OK) { return 1; // 设备未响应 } // 初始状态所有IO输出高电平 PCF8574_WriteOneByte(0xFF); return 0; } uint8_t PCF8574_ReadOneByte(void) { uint8_t temp; HAL_I2C_Master_Receive(&hi2c1, (PCF8574_ADDR<<1)|0x01, &temp, 1, 100); return temp; } void PCF8574_WriteOneByte(uint8_t Data) { HAL_I2C_Master_Transmit(&hi2c1, PCF8574_ADDR<<1, &Data, 1, 100); } void PCF8574_WriteBit(uint8_t bit, uint8_t sta) { uint8_t data = PCF8574_ReadOneByte(); if(sta) data |= (1<<bit); else data &= ~(1<<bit); PCF8574_WriteOneByte(data); } uint8_t PCF8574_ReadBit(uint8_t bit) { return (PCF8574_ReadOneByte() & (1<<bit)) ? 1 : 0; }

3.2 中断功能实现

PCF8574的中断功能可以大幅降低MCU的轮询开销:

// 配置中断引脚(以PA0为例) void PCF8574_INT_Init(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; __HAL_RCC_GPIOA_CLK_ENABLE(); GPIO_InitStruct.Pin = GPIO_PIN_0; GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING; GPIO_InitStruct.Pull = GPIO_PULLUP; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); HAL_NVIC_SetPriority(EXTI0_IRQn, 0, 0); HAL_NVIC_EnableIRQ(EXTI0_IRQn); } // 中断服务例程 void EXTI0_IRQHandler(void) { if(__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_0) != RESET) { uint8_t io_state = PCF8574_ReadOneByte(); // 读取会清除中断 // 处理IO状态变化 __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_0); } }

4. 实战应用案例

4.1 多路LED控制

假设我们需要控制8个LED指示灯,但STM32的IO口已经所剩无几:

// 定义LED连接位置 #define LED0 0 #define LED1 1 // ... 其他LED定义 void LED_Test(void) { PCF8574_Init(); while(1) { for(int i=0; i<8; i++) { PCF8574_WriteBit(i, 1); // LED亮 HAL_Delay(200); PCF8574_WriteBit(i, 0); // LED灭 } } }

4.2 矩阵键盘扫描

利用PCF8574实现4x4矩阵键盘:

uint8_t Key_Scan(void) { static const uint8_t row_pins[] = {0,1,2,3}; static const uint8_t col_pins[] = {4,5,6,7}; uint8_t key = 0xFF; // 设置列为输出,行为输入 for(int c=0; c<4; c++) { PCF8574_WriteOneByte(~(1<<col_pins[c])); for(int r=0; r<4; r++) { if(PCF8574_ReadBit(row_pins[r]) == 0) { key = r*4 + c; while(PCF8574_ReadBit(row_pins[r]) == 0); // 等待释放 break; } } PCF8574_WriteOneByte(0xFF); // 所有列高 if(key != 0xFF) break; } return key; }

5. 性能优化与常见问题

5.1 I2C通信速率优化

默认情况下,STM32的I2C工作在标准模式(100kHz),我们可以提升到快速模式(400kHz):

// 在I2C初始化代码中修改时钟配置 hi2c1.Instance = I2C1; hi2c1.Init.ClockSpeed = 400000; // 400kHz hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;

5.2 典型问题排查

  1. 设备无响应:

    • 检查I2C地址是否正确(用逻辑分析仪抓取波形)
    • 确认上拉电阻已连接(通常4.7kΩ)
    • 验证电源电压是否在2.5-6V范围内
  2. 中断不触发:

    • 确保INT引脚已正确配置为下降沿触发
    • 每次中断后必须进行读/写操作才能清除中断
  3. 输出驱动能力不足:

    • PCF8574每个引脚最大驱动电流25mA
    • 驱动大电流负载时建议增加晶体管或MOSFET

注意:多个PCF8574共用I2C总线时,总电容不能超过400pF,长距离传输时需要降低时钟频率。

在实际项目中,我发现合理利用PCF8574的中断功能可以大幅降低系统功耗。例如在电池供电的传感器节点中,可以让STM32进入低功耗模式,仅通过PCF8574的中断唤醒,这种设计可使平均电流降至微安级别。

相关新闻

  • YOLOv5模型瘦身实战:用torch_pruning 0.2.7给模型‘减肥’,附完整代码与避坑指南
  • 桌面分区管理神器:NoFences让你的Windows桌面告别混乱时代
  • 3个步骤让Windows电脑变身安卓应用中心:APK安装器使用指南

最新新闻

  • ComfyUI-Impact-Pack完整指南:AI绘画细节增强的终极解决方案
  • 抖音无水印下载终极指南:三步免费获取高清视频的完整解决方案
  • 基于ATSAMD21的电容触摸蓝牙键盘设计与实现
  • PIC32MZ USB驱动开发实战:基于MPLAB Harmony框架的CDC设备配置与调试
  • phytium-kernel实时性优化:飞腾处理器实时内核补丁与调度器调优
  • 国内高校学生论文季必用的AI论文写作工具有哪些?

日新闻

  • 2026年6月公司网站搭建最新热门渠道测评:四大低成本/零代码平台对比+避坑
  • 【Linux】Linux arm 编译QT程序,出现expected “}“报错
  • 【MATLAB例程】四基站二维AOA定位与距离辅助增强对比仿真。基于角度观测和测距修正的固定目标平面定位精度分析

周新闻

  • Windows字体自定义终极方案:No!! MeiryoUI完全指南
  • Deepin Boot Maker:告别命令行,3分钟制作Linux启动盘的智能解决方案
  • Plain Craft Launcher 2:重新定义你的Minecraft游戏体验

月新闻

  • 2026年6月公司网站搭建最新热门渠道测评:四大低成本/零代码平台对比+避坑
  • 【Linux】Linux arm 编译QT程序,出现expected “}“报错
  • 【MATLAB例程】四基站二维AOA定位与距离辅助增强对比仿真。基于角度观测和测距修正的固定目标平面定位精度分析

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号