51单片机-IO扩展模块 pcf8575

发布于:2025-06-19 ⋅ 阅读:(15) ⋅ 点赞:(0)

51单片机介绍

一、51单片机基本概念

51单片机 是指基于 Intel MCS-51架构 的8位微控制器系列,由Intel在1980年推出,后由多家厂商(如Atmel、STC、NXP等)生产兼容型号。因其结构简单、成本低廉、生态完善,成为嵌入式开发的经典入门选择。


二、核心特点

特性 说明
CPU架构 8位CISC内核,12时钟周期/机器周期(增强型1T架构为1时钟周期)
存储器 - 4KB~64KB Flash ROM(程序存储)
- 128B~1KB RAM(数据存储)
I/O端口 4组8位双向I/O口(P0-P3),部分引脚复用为外设功能(如串口、中断等)
定时器 2~3个16位定时器/计数器(TIM0/TIM1/TIM2)
串口通信 1个全双工UART(支持异步串行通信)
中断系统 5~7个中断源(2外部+2定时器+1串口,增强型扩展更多)
工作频率 典型12MHz(标准型),增强型可达35MHz(如STC12系列)

三、常见型号对比

型号 厂商 Flash RAM 特殊功能
AT89C51 Atmel 4KB 128B 经典基础型号
STC89C52 STC 8KB 512B 支持ISP下载
STC12C5A60S2 STC 60KB 1KB 1T架构、ADC、PWM
P89V51RD2 NXP 64KB 1KB 双DPTR指针

四、硬件架构详解

  1. 存储器结构

    • 哈佛架构:程序存储器(ROM)与数据存储器(RAM)独立编址。

    • 特殊功能寄存器(SFR):通过直接寻址访问(地址80H~FFH),控制外设功能。

  2. I/O端口特性

    • P0口:开漏输出,需外接上拉电阻;复用为数据/地址总线。

    • P1口:准双向口,无复用功能。

    • P2/P3口:部分引脚复用(如P3.0=RXD,P3.1=TXD)。

  3. 中断优先级

    • 2级可编程优先级(IP寄存器配置)。

    • 默认优先级顺序:外部0 > 定时器0 > 外部1 > 定时器1 > 串口。


五、开发工具链

  1. 编程环境

    • Keil μVision:主流IDE,支持C51汇编和C语言开发。

    • SDCC:开源跨平台编译器(Linux/macOS适用)。

  2. 烧录工具

    • STC-ISP:STC单片机专用下载软件(通过串口烧录)。

    • USB-TTL模块:连接电脑与单片机的UART引脚。

  3. 仿真调试

    • Proteus ISIS:电路设计与代码协同仿真。

    • 硬件调试器:如J-Link(需芯片支持)

PCF8575介绍

PCF8575 是 NXP(原飞利浦半导体)生产的一款通用 I²C 总线 I/O 扩展器芯片,主要用于微控制器(如 Arduino、STM32 等)的 I/O 端口扩展。

主要特性

  • 16位并行 I/O 端口:可以配置为输入或输出

  • I²C 总线接口

    • 兼容 Fast-mode I²C (400 kHz)

    • 支持 3.3V 和 5V 系统

  • 中断输出:当输入状态改变时可触发中断

  • 低待机电流消耗:适合电池供电设备

  • 宽工作电压范围:2.5V 至 6V

  • 工业温度范围:-40°C 至 +85°C

引脚配置

PCF8575 通常采用 24 引脚 SO 或 TSSOP 封装,主要引脚包括:

  • SDA, SCL:I²C 总线接口

  • A0-A2:地址选择引脚

  • INT:中断输出

  • P00-P17:16个可编程 I/O 引脚

  • VCC, GND:电源和地

应用场景

  1. LED 控制

  2. 按键/开关输入检测

  3. 继电器控制

  4. 需要额外 I/O 端口的嵌入式系统

  5. 工业控制和自动化

与 PCF8574 的区别

PCF8575 是 PCF8574 的升级版本,主要区别在于:

  • PCF8575 提供 16 位 I/O (PCF8574 只有 8 位)

  • PCF8575 的中断功能更完善

编程接口

通过 I²C 接口通信,典型操作包括:

  • 写入输出状态

  • 读取输入状态

  • 配置 I/O 方向(通过写入特定模式)

典型电路连接

PCF8575 通常与微控制器通过 I²C 总线连接,地址由 A0-A2 引脚决定,允许同一总线上连接最多 8 个 PCF8575 设备。

proteus 51单片机 连接PCF8575

代码实现

#include <reg51.h>
#include <intrins.h>

#define u8 unsigned char
#define u16 unsigned int

// 定义I2C引脚
sbit SDA = P2^1;
sbit SCL = P2^0;

// PCF8575地址(根据A0,A1,A2引脚配置)
#define PCF8575_ADDR 0x40

// 延时函数
void delay_us(u8 t) {
    while(t--);
}

void delay_ms(u16 t) {
    u16 i, j;
    for(i=0; i<t; i++)
        for(j=0; j<120; j++);
}

// I2C起始信号
void I2C_Start() {
    SDA = 1;
    SCL = 1;
    delay_us(5);
    SDA = 0;
    delay_us(5);
    SCL = 0;
}

// I2C停止信号
void I2C_Stop() {
    SDA = 0;
    SCL = 1;
    delay_us(5);
    SDA = 1;
    delay_us(5);
}

// I2C发送应答
void I2C_Ack(u8 ack) {
    SDA = ack;
    SCL = 1;
    delay_us(5);
    SCL = 0;
    SDA = 1;
}

// I2C接收应答
u8 I2C_Wait_Ack() {
    u8 ack;
    
    SDA = 1;
    SCL = 1;
    delay_us(5);
    ack = SDA;
    SCL = 0;
    
    return ack;
}

// I2C发送一个字节
void I2C_SendByte(u8 dat) {
    u8 i;
    
    for(i=0; i<8; i++) {
        SDA = (dat & 0x80) ? 1 : 0;
        SCL = 1;
        delay_us(5);
        SCL = 0;
        dat <<= 1;
    }
}

// I2C接收一个字节
u8 I2C_RecvByte() {
    u8 i, dat = 0;
    
    SDA = 1;
    for(i=0; i<8; i++) {
        SCL = 1;
        delay_us(5);
        dat <<= 1;
        dat |= SDA;
        SCL = 0;
        delay_us(5);
    }
    
    return dat;
}

// 向PCF8575写入16位数据
void PCF8575_Write(u16 dat) {
    I2C_Start();
    I2C_SendByte(PCF8575_ADDR);  // 发送设备地址+写命令
    I2C_Wait_Ack();
    I2C_SendByte(dat >> 8);      // 发送高字节
    I2C_Wait_Ack();
    I2C_SendByte(dat & 0xFF);    // 发送低字节
    I2C_Wait_Ack();
    I2C_Stop();
}

// 从PCF8575读取16位数据
u16 PCF8575_Read() {
    u16 dat;
    
    I2C_Start();
    I2C_SendByte(PCF8575_ADDR | 0x01);  // 发送设备地址+读命令
    I2C_Wait_Ack();
    dat = I2C_RecvByte() << 8;          // 读取高字节
    I2C_Ack(0);                         // 发送应答
    dat |= I2C_RecvByte();              // 读取低字节
    I2C_Ack(1);                         // 发送非应答
    I2C_Stop();
    
    return dat;
}

// 主函数
void main() {
    u16 output_data = 0x5555;  // 示例输出数据(0101 0101 0101 0101)
    u16 input_data;
    
    // 初始化I2C引脚
    SDA = 1;
    SCL = 1;
    
    while(1) {
        // 写入数据到PCF8575
        PCF8575_Write(output_data);
        delay_ms(1000);
        
        // 从PCF8575读取数据
        input_data = PCF8575_Read();
        delay_ms(1000);
        
//        // 改变输出数据
       output_data = ~output_data;
    }
}

测试效果 


网站公告

今日签到

点亮在社区的每一天
去签到