I2C接口的输入与输出驱动的PCF8574-
pcf8574采用I2C接口,有8个准双向口,可以和外部电路连接,来实现输入输出功能,可以用来对口线进行扩展
有几点需要注意
1.某位作为输入的时候,必须首先置为高电平
2.地址是0100 A2 A1 A0 R/W
3.最多可以扩展8片
4.低电流损耗,静态电流10uA,驱动电流比较大,而且有索存功能,能够驱动LED 发光管
5.带有外部中断输出,低电平有效
我作了一个电路,其中P7-P4作为输入检测开关状态,P3-P0作为输出来驱动LED 灯
程序如下
#include "reg51.h"
#define SETBIT(VAR,Place) (VAR|=(1<<Place))
#define CLRBIT(VAR,Place) (VAR&=((1<<Place)^255))
sbit IC_SCL=P3^6;
sbit IC_SDA=P3^7;
unsigned char IC_Re_Time;
unsigned char IC_Err_Flag;
void Timer0_Init(void)
{
TMOD=0x00;//timer0工作定时器方式0,13位技术
TH0=0x1e;//5ms
TL0=0x0c;//5ms
TR0=1;//启动时钟0
ET0=1;//允许时钟0进行中断
EA=1;//开放所有中断
}
void Delay(void)
{
unsigned char i;
for(i=0;i<=10;i++)
{
;
}
}
unsigned char VALBIT(unsigned int Val,unsigned char Bit) {
unsigned int Buf;
Buf=0x0001;
if(Bit)
Buf<<=Bit;
Val&=Buf;
if(Val)
return(0xff);
else
return(0x00);
}
/********************************************** 下面是PCF8574的操作程序
1.通信方式:I2C
2.通信端口:IC_SCL(P
3.6),IC_SDA(P3.7)
3.通信地址:0x0101000x
***********************************************/ void IC_Start(void)//启动IC通信
{
IC_SDA=1;
Delay();
IC_SCL=1;
Delay();
IC_SDA=0;
Delay();
IC_SCL=0;
Delay();
}
void IC_Stop(void)//停止IC通信
{
IC_SDA=0;
Delay();
IC_SCL=1;
Delay();
IC_SDA=1;
Delay();
}
void IC_Receive_Ack(void)//接受ACK {
IC_SDA=1;
IC_SCL=1;
Delay();
IC_Re_Time=0;
while(IC_Re_Time<=30)
{
if(IC_SDA==0)
{
IC_Err_Flag=0;
break;
}
else
{
IC_Err_Flag=1;
}
}
IC_SCL=0;
Delay();
}
//void IC_Send_ACK(void)//发送ACK
//{//if read many datas at a time,this can be used //IC_SDA=0;
//Delay();
//IC_SCL=1;
//Delay();
//IC_SCL=0;
//Delay();
//IC_SDA=1;
//}
void IC_Send_NAck(void)//发送NACK
{
IC_SDA=1;
Delay();
IC_SCL=1;
Delay();
IC_SCL=0;
Delay();
}
void IC_Write_Byte(unsigned char Data)//写数据到8574
{
unsigned char i;
for(i=0;i<=7;i++)
{
if(VALBIT(Data,(7-i)))//data out msb
IC_SDA=1;
else
IC_SDA=0;
IC_SCL=1;
Delay();
IC_SCL=0;
Delay();
}
}
unsigned char IC_Read_Byte(void)//从8574读取一个数据{
unsigned char i;
unsigned char Data;
for(i=0;i<=7;i++)
{
IC_SCL=1;
Delay();
IC_SDA=1;
Delay();
if(IC_SDA)
SETBIT(Data,(7-i));//data in msb too
else
CLRBIT(Data,(7-i));
IC_SCL=0;
Delay();
}
return(Data);
}
void IC_Write_Data(unsigned char Data)
{
unsigned char write_time;
unsigned char write_data;
write_data=Data;
for(write_time=0;write_time<=2;write_time++) {
IC_Start();
IC_Write_Byte(0x40);
IC_Receive_Ack();
IC_Write_Byte(write_data);
IC_Receive_Ack();
IC_Stop();
if(IC_Err_Flag==0)
break;
}
}
unsigned char IC_Read_Data(void)
{
unsigned char Return_Data;
unsigned char read_time;
for(read_time=0;read_time<=2;read_time++) {
IC_Start();
IC_Write_Byte(0x41);
IC_Receive_Ack();
Return_Data=IC_Read_Byte();
IC_Send_NAck();
IC_Stop();
if(IC_Err_Flag==0)
{
return(Return_Data);
break;
}
}
}
void PCF8574_Init(void)
{
IC_Write_Data(0xf0);//输入状态的必须开始的时候置为1,输出为0 }
void main(void)
{
unsigned char temp3;
Timer0_Init();
PCF8574_Init();
while(1)
{
temp3=IC_Read_Data();
IC_Write_Data(0x0f);
Delay();
;中间可以添加你需要的模块,比如显示或者其他的操作等
}
}
/*********************************************************
*中断服务子程序 *
*********************************************************/
extern void external0_rt(void)interrupt 0//INT0
{
}
extern void eit0_rt(void)interrupt 1//T0,标准,定时中断
{
TH0=0x1e;
TL0=0x0c;
IC_Re_Time++;
}
void external1_rt(void)interrupt 2 using 1//INT1
{
}
void eit1_rt(void)interrupt 3 using 1//T1,标准
{
}
void sci_rt(void)interrupt 4 using 1//UART
{
}
void eit2_rt(void)interrupt 5 using 1//T2 3种工作模式,输入捕捉、自动重载和波形发生器
{
}
void PCA_rt(void)interrupt 6 using 1//PCA
{
}
void KBDIT_rt(void)interrupt 7 using 1//keyboard
{
}
void spi_rt(void)interrupt 9 using 1//SPI {
}
Welcome !!! 欢迎您的下载,资料仅供参考!。