I2C总线8位远程I/O扩展口芯片PCF8574的原理与应用
摘要本文概括介绍了PCF8574 I/O扩展口芯片的特点和基本组成通过实例详细说明了有关功能的应用软件关于 PCF8574的详细位控功能请参考PHILIPS公司的相应产品资料
一概述
PCF8574是PHILIPS公司推出的一款带I2C总线,具有CMOS电路可使大多数MCU实现远程I/O口扩展该
器件包含一个8位准双向口和一个I2C总线接口PCF8574电流消耗很低且口输出锁存具有大电流驱动能力可直接驱动LED它还带有一条中断接线INT可与MCU的中断逻辑相连通过INT发送中断信号远端I/O口不必经过I2C总线通信就可通知MCU是否有数据从端口输入这意味着PCF8574可以作为一个单被控器下面将主要的性能指标作一综合
1. 操作电压
2.5~6.0V;
2. 低备用电流10A;
3. I2C并行口扩展电路;
4. 开漏中断输出;
5. I2C总线实现8位远程I/O口;
6. 与大多数MCU兼容;
7. 口输出锁存具有大电流驱动能力可直接驱动LED;
8. 通过3个硬件地址引脚可寻址8个器件PCF8574A可多达16个;
9. DIP16SO16或SSOP20形式封装.
二PCF8574的基本组成
中断输出低电平有效
串行时钟线
串行数据线
三PCF8574与微控制器的接口软件及功能应用举例
按I2C总线规约PCF8574的器件地址为40h, PCF8574A的器件地址为70h, 当然,由于硬件地址引脚A0-A2可寻址8个器件,所以器件地址并不唯一,例如:A0接GND,A1接VCC,A2接VCC,则PCF8574的器件地址为4Ch.
下面首先给出基本的应用原理图(以4个按键输入和4个LED为例)然后说明各种功能的应用
PCF8574应用电路原理图P87LPC764采用内部振荡内部复位电路
1作为准双向口输出
作为准双向口扩展功能使用时无需任何控制寄存器来进行输入或输出设定参照上面的原理图举例
说明作为输出控制LED的设定欲使LED1LED3亮LED2LED4灭软件模块如下
Output_Control:
MOV SlvAdr,#40h ; 取PCF8574的器件地址
MOV ByteCnt,#1传送字节个数为1
MOV XmtDat,#0F5h 传送的字节内容为#0F5h
; 并口P0-P7的输出值为11110101
ACALL SendData 调用数据发送模块
RET 返回调用处
2作为准双向口输入
作为准双向口扩展功能使用时无需任何控制寄存器来进行输入或输出设定参照上面的原理图举例
说明作为按键输入的设定首先请用户特别注意PCF8574的/INT输出在上电复位或进行了输出操作之
后一直保持低电平因此用户在进行输入操作之前如果想等待/INT中断再处理的话必须进行输入检
测之前的预操作之后可采取查询或中断方式来判断/INT输出
Input_Check:
MOV SlvAdr,#40h ; 取PCF8574的器件地址
MOV ByteCnt,#1传送字节个数为1
ACALL RcvData 调用数据接收模块
; 接收预处理完毕
JB P1.4,$ ; PCF8574无数据输出则在此等待
MOV ByteCnt,#1接收字节个数为1
ACALL RcvData 调用数据接收模块
RET 返回调用处
以上程序调用了I2C总线的基本数据发送(SendData)和接收(RcvData)模块,这些模块的源程序清单以及MCU的内部RAM定义在附录中给出
附录I2C总线数据发送与接收模块源程序清单
; I2C总线模块化程序 ZM-I2C -5124-V0.1
;**********************************************************************************************
; 87LPC762/4单主控器模拟I2C总线发送接受数据程序
;说明本程序是利用Philip公司的P87LPC764单片机的I/O口(如P1.2/P1.3)模拟实现I2C总线的功能对I2C总线上的器件本程序采用PCF8574进行读写操作当然用户有兴趣的话也可采用硬件I2C总线控制寄存
器来编写控制程序
; 被控器地址在SlvAdr所发送的数据字节数在ByteCnt中所发送的数据在XmtDat中
接收的数据在RcvDat中
************************************************************************************************** ;87LPC762/4单主控器模拟I2C总线发送接受数据程序头文件
;内存数据定义
BitCnt DATA 30H ; I2C数据位计数器
ByteCnt DATA 31H ; I2C数据字节计数器
SlvAdr DATA 32H ;被控器地址
RcvDat DATA 40H ;接收数据缓冲区
XmtDat DATA 50H ;发送数据缓冲区
;端口位定义
SDA BIT P1.3 ;模拟I2C数据传送位
SCL BIT P1 2 ;模拟I2C时钟控制状态标志
ACK BIT 20H ;接收数据非应答标志
;************************************************************************************************** ; 发送数据程序
;名称:SendData
;描述:发送ByteCnt个字节给被控器PCF8574
;被控器地址在SlvAdr中
;所发送数据的字节数ByteCnt在中发送的数据在XmtDat缓冲区中
;发送数据正常返回标志F0=0F0=1表示被控器无应答或损坏
;************************************************************************************************* SendData:
ACALL START ;发送I2C总线起始条件
MOV A ,SlvAdr ;取被控器总线地址
ACALL SentByte ;发送被控器总线地址
JB F0,SendReturn ;出错返回
MOV R0,#XmtDat ;取发送数据缓冲区首址
SentNext:
MOV A,@R0
ACALL SentByte ;发送一次数据
JB F0,SendReturn ;出错返回
INC R0 ;取下一个数据
DJNZ ByteCnt,SentNext ;重复操作直到发送完最后一个数据
ACALL STOP ;发送I2C 总线停止条件
Delay10:
MOV R7,#30H ;延时10ms,等待数据写完
D1:
MOV R6,#34H
D2:
DJNZ R6,D2
DJNZ R7,D1
SendReturn:
RET
;*************************************************************************************************** ; 接收数据程序;
;名称:RcvData
;描述:从被控器PCF8563接收ByteCnt个字节数据
;被控器地址在SlvAdr中
;所接收数据的字节数ByteCnt在中接收的数据在RcvDat缓冲区中
;接收数据正常返回标志F0=0F0=1表示被控器无应答或损坏
;**************************************************************************************************
RcvData:
ACALL START ;发送I2C总线重复起始条件
MOV A,SlvAdr ;取被控器总线地址
SETB ACC.0 ;取总线读操作位
ACALL SentByte ;发送被控器总线地址
JB F0,RcvReturn ;出错返回
CLR ACK ;清接收非应答标志准备接收数据
MOV R0,#RcvDat ;取接收数据缓冲区首址
DJNZ ByteCnt,RcvNext ;如果还未接收数据则转去接收前ByteCnt)-1个数据
SJMP RcvLast ;只剩最后一个数据未接收转去接收最后一个数据
RcvNext:
ACALL RcvByte ;接收数据
MOV @R0,A ;将数据放入接收缓冲区中
INC R0 ;指向下一个缓冲区地址
DJNZ ByteCnt,RcvNext ;重复操作直到剩下最后一个数据
RcvLast:
SETB ACK ;置接收非应答标志准备在接收完最后一个数据后
;发出非应答信号以停止接收数据
ACAL RcvByte ;接收最后一个数据
MOV @R0,A ;将最后一个数据放入接收缓冲区中
ACALL STOP ;发送I2C 总线停止条件
RcvReturn:
RET
;**************************************************************************************************** ; 子程序
;*************************************************************************************************** ;名称:START
;描述:启动I2C总线子程序--发送I2C起始条件
;-------------------------------------------------------------------------------------------------- START:
SETB SDA ;发送起始条件的数据信号
NOP
SETB SCL ;发送起始条件的时钟信号
NOP ;起始条件建立时间大于4.7s
NOP
NOP
NOP
NOP
CLR SDA ;发送起始信号
NOP ;起始条件锁定时间大于4s
NOP
NOP
NOP
NOP
CLR SCL ;钳住I2C总线准备发送或接收数据
RET
;--------------------------------------------------------------------------------------------------- ;名称:STOP
;描述:停止I2C总线子程序--发送I2C总线停止条件
;--------------------------------------------------------------------------------------------------- STOP:
CLR SDA ;发送停止条件的数据信号
NOP
SETB SCL ;发送停止条件的时钟信号
NOP ;起始条件建立时间大于4s
NOP
NOP
NOP
NOP
SETB SDA ;发送I2C总线停止信号
NOP
NOP
NOP
NOP
RET
;------------------------------------------------------------------------------------
;名称:SentByte
;描述:字节数据传送子程序发送一个字节数据或地址给被控器PCF8574
;要发送的数据在ACC中
;发送数据正常返回标志F0=0F0=1表示被控器无应答或损坏
;-------------------------------------------------------------------------------------
SentByte:
MOV BitCnt,#08H ;要传送的数据长度为8位
SentB:
RLC A ;要发送的数据左移,发送位入C
JC Sent1 ;发送位为“1”转发送数据位“1”
CLR SDA ;发送数据位“0”
SJMP Sent ;转发送数据位
Sent1:
SETB SDA ;发送数据位“1”
NOP
Sent:
NOP
SETB SCL ;置时钟线为高通知被控器开始接收数据位
NOP ;保证时钟高周期大于4s
NOP
NOP
NOP
NOP
CLR SCL ;钳住总线准备接收下一个数据位
DJNZ BitCnt,SentB ;8位没发送完继续发送
NOP
NOP
SETB SDA ;8位发送完后释放数据线准备收应答位
NOP
NOP
SETB SCL ;开始接收应答信号
NOP
NOP
CLR F0 ;预先清发送数据出错标志
JNB SDA, AckEnd ;判断是否接收到应答信号正常转AckEnd
SETB F0 ;未收到应答置位错误标志
AckEnd:
NOP
CLR SCL ;发送结束钳住总线准备下一步发送或接收数据或进行其它处理
RET
;---------------------------------------------------------------------------------------------------- ;名称:RcvByte
;描述:字节数据接收子程序从被控器PCF8574接收一个字节数据然后根据主程序要求发送应答位
;接收的字节数据在ACC中
;--------------------------------------------------------------------------------------------------- RcvByte:
SETB SDA ;置数据线为输入方式
MOV BitCnt,#08H ;要传送的数据长度为8位
Rcv:
NOP
CLR SCL ;置时钟线为低准备接收数据位
NOP ;时钟低周期大于4.7s
NOP
NOP
NOP
NOP
SETB SCL ;置时钟线为高使数据线上数据有效
NOP
NOP
CLR C ;准备将接收的数据位放入ACC中
JNB SDA,Rcv0 ;读数据位若为“0”则置C=0并转Rcv0接收数据位
SETB C ;读数据位若为“1”则置C=1
Rcv0:
RLC A ;接收的数据位放入ACC中
NOP
NOP
DJNZ BitCnt,Rcv ;8位没收完继续接收
CLR SCL ;8位接收完置时钟线和数据线为低准备发送应答或非应答信号
NOP
NOP
NOP
CLR SDA
JNB ACK,SentAckB ;判断是否需要继续接收字节数据若需要则转SentAckB发送应答位
SETB SDA ;发送非应答信号
SentAckB: ;以下程序发送应答位
NOP
NOP
SETB SCL ;置时钟线为高使应答位有效
NOP ;时钟高周期大于4s
NOP
NOP
NOP
NOP
CLR SCL ;清时钟线钳住I2C总线以便继续接收字接数据或发送停止条件
CLR ACK ;清接收非应答标志
RET
;=================================================================================================== END