一、简介

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 <STC12C5A60S2.h>
#include <intrins.h>#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位写地址/*I2C硬件接口定义*/
sbit SCL = P3^2;       //I2C时钟总线
sbit SDA = P3^3;       //I2C数据总线/*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.0592MHzunsigned char i, j;_nop_();i = 11;j = 190;do{while (--j);} while (--i);#elif MAIN_Fosc == 12000000L//晶振12.000000MHZunsigned 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<time; i++){Delay1ms();}
}//基于STC12单片机us延时函数
//函数说明:外部调用
void Delay_us(uint time)
{int i;for(i=0; i<time; i++){Delaym1us();}
}//I2C延时5us函数
void I2cDelay_5us(void)
{Delay_us(5);
}//I2C总线起始信号
void I2cStart(void)
{SCL = 1;SDA = 1;I2cDelay_5us();//状态保持5usSDA = 0;I2cDelay_5us();//状态保持5us
}//I2C总线停止信号
void I2cStop(void)
{SCL = 0;SDA = 0;SCL = 1;I2cDelay_5us();//状态保持5usSDA = 1;I2cDelay_5us();//状态保持5us
}/*********************************函数名称:ReadACK(void)*函数输入:无*函数返回:1非应答,0应答*函数说明:I2C总线读从机应答信号********************************/
bit ReadACK(void)
{uint i;SCL = 0;//拉低时钟总线,允许从机控制SDASCL = 1;//拉高,读SDAI2cDelay_5us();while((SDA==1) && (i<250))//等待SDA应答,或者超过时间默认应答i++;SCL = 0;I2cDelay_5us();return(0);//返回0应答
}/****************************************函数名称:SendACK(bit i)*函数输入:1主机发送非应答,0发送应答*函数返回:无*函数说明:主机发送应答信号***************************************/
void SendACK(bit i)
{SCL = 0;  //拉低时钟总线,允许主机控制SDAif(i)      //发送非应答SDA = 1;elseSDA = 0;SCL = 1;  //拉高总线,让从机读SDAI2cDelay_5us();SCL = 0;   //拉低时钟总线,允许SDA释放SDA = 1;    //释放数据总线
}/****************************************函数名称:I2cSendByte(uchar DAT)*函数输入:DAT需要发送的数据*函数返回:无*函数说明:I2C发送一个字节数据***************************************/
void I2cSendByte(uchar DAT)
{uchar i;for(i=0; i<8; i++)   //分别写8次,每次写1位{SCL = 0;      //拉低时钟总线,允许SDA变化if(DAT & 0x80)   //先写数据最高位SDA = 1;      //写1elseSDA = 0;   //写0SCL = 1;       //拉高时钟,让从机读SDADAT <<= 1;      //为发送下一位左移1位}SCL = 0;          //拉低时钟总线,允许SDA释放SDA = 1;            //释放数据总线
}/*====================================
函数  :I2cReadByte()
参数  :无
返回值 :返回读出的一字节数据
描述  :I2C总线读一字节数据
====================================*/
uchar I2cReadByte(void)
{uchar i, DAT;for(i=0; i<8; i++)//分别读8次,每次读一位{DAT <<= 1; //数据左移1位,准备接收一位SCL = 0;   //拉低时钟总线,允许从机控制SDA变化SCL = 1;   //拉高时钟总线,读取SDA上的数据if(SDA)DAT |= 0X01;//为1则写1,否则不行执行写1,通过左移补0}return(DAT); //返回读出的数据
}/*=========================================*函数名称:PCF8575Read(uchar dat)*函数输入:要控制硬件的数据(16位)*函数返回:无*函数说明:控制PCF引脚*=========================================*/
void PCF8575Read(uchar dat1, uchar dat2)
{bit AckTemp=1;I2cStart();//发送启动位I2cSendByte(PCF8575_WRITEADDRESS);//发送地址AckTemp=ReadACK();//接收应答I2cSendByte(dat1);//控制P0.0-P0.7AckTemp=ReadACK();//接收应答I2cSendByte(dat2);//控制P1.0-P1.7AckTemp=ReadACK();//接收应答I2cStop();
}void PCF8575_Read()
{bit AckTemp = 1;I2cStart();//发送启动位I2cSendByte(PCF8575_READ_ADDRESS);//发送地址位AckTemp=ReadACK();//接收应答PCF8575_LVal = I2cReadByte();//接收1个字节(P0.0-P0.7)SendACK(0);//发送应答位PCF8575_HVal = I2cReadByte();//接收1个字节(P1.0-P1.7)SendACK(1);//发送非应答位I2cStop();
}void main()
{PCF8575Read(0xff,0xff);//上电复位将PCF8575的电平拉高while(1){//使控制的led闪烁Delay_ms(1000);PCF8575Read(0xff,0xff);Delay_ms(1000);PCF8575Read(0x00,0x00);}
}

例程2:使用STC12读取PCF8575端口电平,通过串口发送当前电平状态

#include <STC12C5A60S2.h>
#include <intrins.h>//数据类型重定义
#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/*I2C常用变量宏定义*/
#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.0592MHzunsigned char i, j;_nop_();i = 11;j = 190;do{while (--j);} while (--i);#elif MAIN_Fosc == 12000000L//晶振12.000000MHZunsigned 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<time; i++){Delay1ms();}
}//基于STC12单片机us延时函数
//函数说明:外部调用
void Delay_us(uint time)
{int i;for(i=0; i<time; 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<<i)&0x80)I2C_Send_Bit_1();elseI2C_Send_Bit_0();}
}// 接收一个字节
unsigned char I2C_Read8Bit(void)
{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;}elseI2C_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,即1TBRT = 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的电平字节发送到串口}
}

STC12驱动PCF8575相关推荐

  1. DS1302与STC12的连接电路和驱动实现

    简介 DS1302是低功耗带RAM的实时时钟电路, 常见的SOP8封装体积很小, 它可以对年月日周时分秒进行计时, 具有闰年补偿功能, 工作电压为2.0V-5.5V, 采用三线接口与CPU进行同步通信 ...

  2. Ardunio开发实例-PCF8575 IO扩展器

    PCF8575 IO扩展器 PCF8575 IO扩展器用两线双向总线(I2C)的16位I / O扩展器设计用于2.5V至5.5V VCC操作. PCF8575器件通过I2C接口[串行时钟(SCL),串 ...

  3. ESP8266-Arduino编程实例-PCF8575IO扩展器驱动

    PCF8575IO扩展器驱动 1.PCF8575介绍 PCF8575用于两线双向总线 (I2C) 的 16 位 I/O 扩展器专为 2.5-V 至 5.5-V VCC 操作而设计. PCF8575 器 ...

  4. STC89和STC12的区别

    STC12单片机是一个单片机的牌子.STC12系列是STC89单片机的一个种类. 单片机(Microcontrollers)是一种集成电路芯片,是采用超大规模集成电路技术把具有数据处理能力的中央处理器 ...

  5. ST7735STFT屏幕的驱动

    ST7735STFT屏幕的驱动 ST7735S简介 TFT简介 引脚说明 程序驱动 主要命令控制 部分代码框架 驱动展示 总结 原文链接:https://www.yourcee.com/newsinf ...

  6. ESP32设备驱动-Si4703调频收音机模块驱动

    Si4703调频收音机模块驱动 文章目录 Si4703调频收音机模块驱动 1.Si4703介绍 2.硬件准备 3.软件准备 4.驱动实现 1.Si4703介绍 Si4702/03 FM 无线电接收器系 ...

  7. 嵌入式Linux设备驱动程序:在运行时读取驱动程序状态

    嵌入式Linux设备驱动程序:在运行时读取驱动程序状态 Embedded Linux device drivers: Reading driver state at runtime 在运行时了解驱动程 ...

  8. 0、Spring 注解驱动开发

    0.Spring注解驱动开发 0.1 简介 <Spring注解驱动开发>是一套帮助我们深入了解Spring原理机制的教程: 现今SpringBoot.SpringCloud技术非常火热,作 ...

  9. 安装 Python MySQL 驱动(mysql-connector-python、MySQL-python)

    1. 安装 由于 MySQL 服务器以独立的进程运行,并通过网络对外服务,所以,需要支持 Python 的MySQL 驱动来连接到 MySQL 服务器. 目前,有两个MySQL驱动: mysql-co ...

最新文章

  1. 提高开发效率之安卓模板(上面有四种模板的教程,我之前会两种,看完之后还是只会两种2333)
  2. 《科学+ 预见人工智能》——“工具”本质,理性批判
  3. Log4net 在framework Client中编译失败
  4. Linux开机启动过程详细分析
  5. JDK 8与JDK 10:三元/拆箱的区别
  6. 枚举命名规范_UE4 C++基础教程 - 编码规范
  7. js/d3.min.js_在5分钟内学习D3.js
  8. xubuntu16.04是linux系统,win10建立Ubuntu16.04子系统,安装经常使用软件以及图形界面(包括win10远程桌面链接Ubuntu)...
  9. Android动画系列 - PropertyAnim 详解
  10. mysql慢查询监控及sql优化
  11. 安卓开发_使用AlertDialog实现对话框
  12. RHEL6入门系列之三十三,写在最后
  13. 常用z反变换公式表_常用excel快捷键
  14. CAD,SolidWorks相比ProE,UG等软件有什么区别?
  15. 转载 Linux新人科普
  16. 读胡适先生《赠与今年的大学毕业生》和《赠与大学毕业生的话》后感
  17. 【算法】扩展卢卡斯详解
  18. 计算机行业职业名称英语,行业英语学习
  19. 项目实战 |根据找到的variants的结果生成突变矩阵
  20. Mask Transfiner for High-Quality Instance Segmentation

热门文章

  1. CMake设置Visual Studio工程的调试环境变量和工作目录cwd的方法
  2. android 友盟微信授权2002,友盟 2002错误
  3. PR(Adobe Premimere)视频剪辑软件初次安装新手设置建议
  4. SPSS与对应分析(类别简单型)
  5. python图书馆管理系统实验报告_基于python图书馆管理系统设计实例详解
  6. 双非南京大学计算机夏令营,一名双非生的“失败”保研经历:夏令营不确定是否有保研资格,预推免上岸理想院校!...
  7. 2008北京第29届奥运会总奖牌榜
  8. 记一次长城宽带某网站打不开的问题保修全程
  9. C语言数组指针(指向数组的指针)详解
  10. Linux下查找归档的内容