PCF8575是一个I/O扩展芯片,德州仪器的芯片。有3个硬件地址引脚寻址,也就是说这个芯片可以设置8个IIC器件地址;芯片工作电压2.5V~5.5V,具有16位准双向输入/输出(I/O)端口(P07-P00、P17-P10)。当我们在做嵌入式开发时,MCU接口不够用可以考虑使用这一款芯片扩展,详细查看相关芯片手册。
淘宝有这一款模块售卖,我使用的经验总结是:使用IO扩展模块当输出时,必须加上拉电阻。上拉电阻选择是1K-10K之间就行了。不然驱动的电压很低!
备注:使用例程编译的时候会出现警告,已经检查过警告原因是没有调用函数,不影响功能运行。不用理会即可。
例程1:使用STC12使端口持续高低电平切换
// //PCF8575控制电平和读取电平 //作者:小途 //时间:2022年2月17日 // #include#include #define uchar unsigned char #define uint unsigned int //常用数据宏定义 #define MAIN_Fosc 11059200L //宏定义主时钟HZ //#define MAIN_Fosc 12000000L //当A0 A1 A2 为000时 #define PCF8575_READ_ADDRESS 0x41 //IIC总线从机8位读地址 #define PCF8575_WRITEADDRESS 0x40 //IIC总线从机8位写地址 sbit SCL = P3^2; //I2C时钟总线 sbit SDA = P3^3; //I2C数据总线 #define I2cRead 1 //I2C读方向位 #define I2cWrite 0 //I2C写方向 bit AckFlag; //应答标志位 uchar PCF8575_LVal,PCF8575_HVal; //基于STC12单片机1ms延时函数 //函数说明:内部调用 static void Delay1ms() { # if MAIN_Fosc == 11059200L //晶振11.0592MHz unsigned char i, j; _nop_(); i = 11; j = 190; do { while (--j); } while (--i); #elif MAIN_Fosc == 12000000L //晶振12.000000MHZ unsigned char i, j; _nop_(); _nop_(); i = 12; j = 168; do { while (--j); } while (--i); #endif } //基于STC12单片机1us延时函数 //函数说明:内部调用 static void Delaym1us() { # if MAIN_Fosc == 11059200L //晶振11.0592MHz _nop_(); #elif MAIN_Fosc == 12000000L //晶振12.000000MHZ _nop_(); _nop_(); #endif } //基于STC12单片机ms延时函数 //函数说明:外部调用 void Delay_ms(uint time) { int i; for(i=0; i
例程2:使用STC12读取PCF8575端口电平,通过串口发送当前电平状态
#include#include //数据类型重定义 #define uchar unsigned char #define uint unsigned int //常用数据宏定义 #define MAIN_Fosc 11059200L //宏定义主时钟HZ //#define MAIN_Fosc 12000000L //当A0 A1 A2 为000时 //IIC总线从机8位读地址 //IIC总线从机8位写地址 //#define PCF8575_READ_ADDRESS 0x41 //#define PCF8575_WRITEADDRESS 0x40 #define I2cRead 1 //I2C读方向位 #define I2cWrite 0 //I2C写方向 //IO管脚定义 sbit SDA = P0^7;//I2C时钟总线 sbit SCL = P0^6;//I2C数据总线 sbit INT0 = P3^2;//按键中断引脚 //全局变量定义 uchar PCF8575_LVal; uchar PCF8575_HVal; //基于STC12单片机1ms延时函数 //函数说明:内部调用 static void Delay1ms() { # if MAIN_Fosc == 11059200L //晶振11.0592MHz unsigned char i, j; _nop_(); i = 11; j = 190; do { while (--j); } while (--i); #elif MAIN_Fosc == 12000000L //晶振12.000000MHZ unsigned char i, j; _nop_(); _nop_(); i = 12; j = 168; do { while (--j); } while (--i); #endif } //基于STC12单片机1us延时函数 //函数说明:内部调用 static void Delaym1us() { # if MAIN_Fosc == 11059200L //晶振11.0592MHz _nop_(); #elif MAIN_Fosc == 12000000L //晶振12.000000MHZ _nop_(); _nop_(); #endif } //基于STC12单片机ms延时函数 //函数说明:外部调用 void Delay_ms(uint time) { int i; for(i=0; i Delay1ms(); } } //基于STC12单片机us延时函数 //函数说明:外部调用 void Delay_us(uint time) { int i; for(i=0; i Delaym1us(); } } // 发送I2C启动位 void I2C_Start(void) { SDA=1; SCL=1; Delay_us(2); SDA=0; Delay_us(2); SCL=0; Delay_us(2); } // 发送I2C停止位 void I2C_Stop(void) { SDA=0; SCL=1; Delay_us(2); SDA=1; Delay_us(2); SCL=0; Delay_us(2); } // 发送BIT0 void I2C_Send_Bit_0(void) { SDA=0; SCL=1; Delay_us(2); SCL=0; Delay_us(2); } // 发送BIT1 void I2C_Send_Bit_1(void) { SDA=1; SCL=1; Delay_us(2); SCL=0; Delay_us(2); } // 接收应答信号 bit I2C_Check_Ack(void) { SDA=1; SCL=1; Delay_us(2); F0=SDA; Delay_us(2); SCL=0; Delay_us(2); if(F0==1) return 1; return 0; } // 发送应答信号 void I2C_Ack() { SDA=0; SCL=1; Delay_us(2); SDA=0; Delay_us(2); SCL=0; Delay_us(2); } void I2C_NoAck() { SDA=1; SCL=1; Delay_us(2); SDA=1; Delay_us(2); SCL=0; Delay_us(2); } // 写一个字节 void I2C_Write8Bit(unsigned char I2C_data) { unsigned char i; for(i=0;i<8;i++) { if((I2C_data< unsigned char I2C_data=0,i; for(i=0;i<8;i++) { SDA=1; SCL=1; Delay_us(2); F0=SDA; Delay_us(2); SCL=0; if(F0==1) { I2C_data=I2C_data<<1; I2C_data=I2C_data|0x01; } else I2C_data=I2C_data<<1; } return I2C_data; } // 控制PCF8575引脚电平 void PCF8575_Wirte(unsigned char addr, unsigned int val) { bit AckTemp=1; I2C_Start(); I2C_Write8Bit(0x40|(addr<<1)); I2C_Check_Ack(); I2C_Write8Bit(val); I2C_Check_Ack(); I2C_Write8Bit(val>>8); I2C_Check_Ack(); I2C_Stop(); } // 读出PCF8575引脚电平 void PCF8575_Read(unsigned char addr) { bit AckTemp=1; I2C_Start(); I2C_Write8Bit(0x41|(addr<<1)); AckTemp=I2C_Check_Ack(); PCF8575_LVal=I2C_Read8Bit(); I2C_Ack(); PCF8575_HVal=I2C_Read8Bit(); I2C_NoAck(); I2C_Stop(); } //串口初始化,晶振11.0592,波特率9600 void UartInit(void) //9600bps@11.0592MHz { PCON &= 0x7F; //波特率不倍速 SCON = 0x50; //8位数据,可变波特率 AUXR |= 0x04; //独立波特率发生器时钟为Fosc,即1T BRT = 0xDC; //设定独立波特率发生器重装值 AUXR |= 0x01; //串口1选择独立波特率发生器为波特率发生器 AUXR |= 0x10; //启动独立波特率发生器 EA = 1;//开总中断 ES = 1;//开串口中断 } //向串口发送一个字符 void putchar(char ch) { SBUF = ch; while(!TI);TI = 0; } void main() { UartInit();//串口初始化 PCF8575_Wirte(0,0xffff); // 让PCF8575的所有IO口输出高电平 while(1) { Delay_ms(100); PCF8575_Read(0); // 读PCF8575引脚电平 putchar(PCF8575_LVal); // 把P0.0~P0.7的电平字节发送到串口 putchar(PCF8575_HVal); // 把P1.0~P1.7的电平字节发送到串口 } }



