大家好,欢迎来到IT知识分享网。
1)实验平台:alientek 阿波罗 STM32F767 开发板
2)摘自《STM32F7 开发指南(HAL 库版)》关注官方微信号公众号,获取更多资料:正点原子
第三十一章 IO 扩展实验
上一章,我们介绍了 IIC 驱动 24C02,本章我们将向大家介绍如何使用 IIC 来扩展 IO 口。
在本章中,我们将使用 STM32F767 的普通 IO 口模拟 IIC 时序,来驱动 PCF8574/AT8574,达
到扩展 IO 口的目的。本章分为如下几个部分:
31.1 PCF8574/AT8574 简介
31.2 硬件设计
31.3 软件设计
31.4 下载验证
31.1 PCF8574/AT8574 简介
PCF8574 是飞利浦公司推出的一款 IIC 接口的远程 I/O 扩展芯片,AT8574 则是芯景科技的
产品,PCF8574 和 AT8574 完全兼容,他们可以互相替换使用,接下来的介绍和说明,我们仅
以 PCF8754 为例做说明,AT8574 参考学习即可。
PCF8574 包含一个 8 位准双向口和一个 IIC 总线接口。PCF8574 电流消耗很低且口输出锁
存具有大电流驱动能力可直接驱动 LED 它还带有一条中断接线(INT)可与 MCU 的中断逻辑
相连,通过 INT 发送中断信号,远端 I/O 口不必经过 IIC 总线通信就可通知 MCU 是否有数据
从端口输入,这意味着 PCF8574 可以作为一个单被控器。
PCF8574 有如下特性:
支持 2.5~6.0V 操作电压
低备用电流(≤10u A)
支持开漏中断输出
支持 IIC 总线扩展 8 路 I/O 口
口输出锁存具有大电流驱动能力可直接驱动 LED
通过 3 个硬件地址引脚可寻址 8 个器件
1,引脚说明
PCF8574 的引脚说明如表 31.1.1 所示:
表 31.1.1 PCF8574 引脚说明
我们使用的 PCF8574T 采用 SO16 封装,总共 16 个脚,其中包括:
8 个准双向 IO 口(P0~P7)、
3 个地址线(A0~A2)、SCL、SDA、INT、VDD 和 VSS。每个 PCF8574T 只需要最少 2 个 IO
口,就可以扩展 8 路 IO,且支持一个 IIC 总线上挂最多 8 个 PCF8574T,这样通过 2 个 IO,最
多可以扩展 64 个 IO 口,在 MCU 的 IO 不够用的时候,PCF8574T 是一个非常不错的 IO 扩展
方案。
2,寻址
一个 IIC 总线上,最多可以挂 8 个 PCF8574T(通过 A0~A2 寻址),PCF8574T 的从机地址
格式如图 31.1.1 所示:
图 31.1.1 PCF8574T 从机地址格式
图中的 S 代表 IIC 的 Start 信号(启动信号);A 代表 PCF8574T 发出的应答信号;A0~A2
为 PCF8574T 的寻址信息,我们开发板上 A0~A2 都是接 GND 的,所以,PCF8574T 的地址为:
0X40(左移了一位);R/W 为读/写控制位,R/W=0 的时候,表示写数据到 PCF8574T,输出到
P0~P7 口,R/W=1 的时候,表示读取 PCF8574T 的数据,获取 P0~P7 的 IO 口状态。
关于 IIC 协议的介绍,请参考上一章节。
3,写数据(输出)
PCF8574T 的写数据时序如图 31.1.2 所示:
图 31.1.2 PCF8574T 写数据时序
由图可知,PCF8574T 的数据写入非常简单,首先发送 PCF8574T 的从机地址+写信号
(R/W=0),然后等待 PCF8574T 的应答信号,在应答成功后,发送数据(DATA1)给 PCF8574T
就可以了,发送完数据,会受到 PCF8574T 的应答信号,在发送应答信号的同时,PCF8574T
会将接收到的数据(DATA1)输出到 P0~P7 上面(对应关系见上图)。注意:图中的 WRITE TO
PORT 信号是 PCF8574T 内部自己产生的,它在每次发送应答的同时产生,用于将刚刚接收到
的数据,输出到 P0~P7 上,此信号不需要 MCU 发送。
4,读数据(输入)
PCF8574T 的读数据时序如图 31.1.3 所示:
图 31.1.3 PCF8574T 读数据时序
PCF8574T 的读数据流程:首先发送 PCF8574T 的从机地址+读信号(R/W=1),然后等待
PCF8574T 应答(注意:PCF8574T 在发送应答的同时,会锁存 P0~P7 的数据),然后读取 P0~P7
的数据。数据读取支持连续读取,在最后的时候发送 STOP 信号,即可完成读数据操作。
这里需要注意的是:PCF8574T 的数据锁存(READ FROM PORT),发生在发送应答信号
的时候,之后,P0~P7 发送的数据变化(比如图中的 DATA2 和 DATA3),将不会读取进来,直
到下一个应答信号进行锁存。
5,中断
PCF8574T 带有中断输出脚,它可以连接到 MCU 的中断输入引脚上。在输入模式中(IO
口输出高电平,即可做输入使用),输入信的上升或下降沿都可以产生中断,在 tiv 时间之后 INT
有效。特别注意:一旦中断有效后,必须对 PCF8574T 进行一次读取/写入操作,复位中断,
才可以输出下一次中断,否则中断将一直保持(无法输出下一次输入信号变化所产生的中断)。
关于 PCF8574 的简介,我们就介绍到这里。
本章实验功能简介:开机的时候先检测 PCF8574T 是否存在,然后在主循环里面检测 KEY0
按键和 PCF8574T 的中断信号,当 KEY0 按下时,控制 PCF8574T 的 P0 口输出,从而控制蜂鸣
器(连接在 P0 口)的开关;当检测到 PCF8574T 的中断信号时,读取 EXIO(连接在 PCF8574T
的 P4 口)的状态,当 EXIO=0(即 P4=0)的时候,控制 LED1 的翻转。同时,LCD 模块上显
示相关信息,并用 DS0 提示程序正在运行。另外,本例程将 PCF8574T 的相关控制函数加入
USMART 控制,我们也可以通过 USMART 控制/读取 PCF8574T。
31.2 硬件设计
本章需要用到的硬件资源有:
1) 指示灯 DS0
2)KEY0 按键
3)串口(USMART 使用)
4)LCD 模块
5)PCF8574T
6)蜂鸣器
前面 4 部分的资源,我们前面已经介绍了,请大家参考相关章节。这里介绍 PCF8574T 与
STM32F767 和蜂鸣器的连接,PCF8574T 同 24C02 等共用一个 IIC 接口,SCL 和 SDA 分别连
在 STM32F767 的 PH4 和 PH5 上的,另外 INT 脚连接在 STM32F767 的 PB12 上面,连接关系
如图 31.2.1 所示:
图 31.2.1 PCF8574T 与 STM32F767 和蜂鸣器的连接图
由图可知,蜂鸣器控制信号 BEEP 连接在 PCF8574T 的 P0 脚上,EXIO 连接在 P4 脚上,
其他还连接了一些外设(比如网络复位脚、摄像头、USB、485 等),我们将在对应章节进行
介绍,这里就不多说了。这里需要注意的是:IIC_INT 脚,同 1WIRE_DQ 共用了 PB12,在使
用的时候,他们只能分时复用,不能同时使用。
31.3 软件设计
打开本章实验工程可以看到,由于 PCF8574 要使用到 IIC 接口,所以这里我们保留了上一
章 icc 相关源码。同时还新建了 pcf8574.c 源文件和 pcf8574.h 头文件,PCF8574 相关的驱动代
码就存放在这两个文件中。
打开 pcf8574.c 文件,代码如下:
//初始化 PCF8574
u8 PCF8574_Init(void)
{
u8 temp=0;
GPIO_InitTypeDef GPIO_Initure;
__HAL_RCC_GPIOB_CLK_ENABLE();
//使能 GPIOB 时钟
GPIO_Initure.Pin=GPIO_PIN_12; //PB12
GPIO_Initure.Mode=GPIO_MODE_INPUT; //输入
GPIO_Initure.Pull=GPIO_PULLUP; //上拉
GPIO_Initure.Speed=GPIO_SPEED_HIGH; //高速
HAL_GPIO_Init(GPIOB,&GPIO_Initure); //初始化
IIC_Init();
//IIC 初始化
//检查 PCF8574 是否在位
IIC_Start();
IIC_Send_Byte(PCF8574_ADDR); //写地址
temp=IIC_Wait_Ack(); //等待应答,通过判断是否有 ACK 应答,来判断 PCF8574 的状态
IIC_Stop();
//产生一个停止条件
PCF8574_WriteOneByte(0XFF); //默认情况下所有 IO 输出高电平
return temp;
}
//读取 PCF8574 的 8 位 IO 值
//返回值:读到的数据
u8 PCF8574_ReadOneByte(void)
{
u8 temp=0;
IIC_Start();
IIC_Send_Byte(PCF8574_ADDR|0X01); //进入接收模式
IIC_Wait_Ack();
temp=IIC_Read_Byte(0);
IIC_Stop();
//产生一个停止条件
return temp;
}
//向 PCF8574 写入 8 位 IO 值
//DataToWrite:要写入的数据
void PCF8574_WriteOneByte(u8 DataToWrite)
{
IIC_Start();
IIC_Send_Byte(PCF8574_ADDR|0X00); //发送器件地址 0X40,写数据
IIC_Wait_Ack();
IIC_Send_Byte(DataToWrite);
//发送字节
IIC_Wait_Ack();
IIC_Stop();
//产生一个停止条件
delay_ms(10);
}
//设置 PCF8574 某个 IO 的高低电平
//bit:要设置的 IO 编号,0~7
//sta:IO 的状态;0 或 1
void PCF8574_WriteBit(u8 bit,u8 sta)
{
u8 data;
data=PCF8574_ReadOneByte(); //先读出原来的设置
if(sta==0)data&=~(1<
else data|=1<
PCF8574_WriteOneByte(data); //写入新的数据
}
//读取 PCF8574 的某个 IO 的值
//bit:要读取的 IO 编号,0~7
//返回值:此 IO 的值,0 或 1
u8 PCF8574_ReadBit(u8 bit)
{
u8 data;
data=PCF8574_ReadOneByte(); //先读取这个 8 位 IO 的值
if(data&(1<
else return 0;
}
该部分为 PCF8574 的驱动代码,其中的 IIC 相关函数,直接是用的上一章 myiic.c 里面提
供的相关函数,这里不做介绍。
这里总共有5 个函数:PCF8574_Init函数用于初始化并检测PCF8574,这里我们初始化PB12
为上拉输入,以检测 PCF8574T 的中断输出信号,另外,在该函数里面,我们通过检查 PCF8574
的应答信号来确认 PCF8574 是否正常(在位);PCF8574_ReadOneByte 和 PCF8574_WriteOneByte
这两个函数用于读取/写入 PCF8574,从而读取/控制 P0~P7;最后,PCF8574_WriteBit 和
PCF8574_ReadBit 函数用于控制或者读取 PCF8574 的单个 IO。
pcf8547.h 头文件定义了 PCF8574 的中断检测脚、地址、每个 IO 连接的外设宏定义和相
关操作函数声明。这里我们就不列出该头文件内容,请大家自行打开实验工程查看。
最后我们看看 main 函数,程序如下:
int main(void)
{
u8 key;
u16 i=0;
u8 beepsta=1;
Cache_Enable(); //打开 L1-Cache
HAL_Init();
//初始化 HAL 库
Stm32_Clock_Init(432,25,2,9);
//设置时钟,216Mhz
…//此处省略部分代码
LCD_ShowString(30,130,200,16,16,”KEY0:BEEP ON/OFF”); //显示提示信息
LCD_ShowString(30,150,200,16,16,”EXIO:DS1 ON/OFF”);
//显示提示信息
while(PCF8574_Init())
//检测不到 PCF8574
{
LCD_ShowString(30,170,200,16,16,”PCF8574 Check Failed!”);
delay_ms(500);
LCD_ShowString(30,170,200,16,16,”Please Check! “);
delay_ms(500);
LED0_Toggle;//DS0 闪烁
}
LCD_ShowString(30,170,200,16,16,”PCF8574 Ready!”);
POINT_COLOR=BLUE;//设置字体为蓝色
while(1)
{
key=KEY_Scan(0);
if(key==KEY0_PRES)//KEY0 按下,读取字符串并显示
{
beepsta=!beepsta;
//蜂鸣器状态取反
PCF8574_WriteBit(BEEP_IO,beepsta);//控制蜂鸣器
}
if(PCF8574_INT==0)
//PCF8574 的中断低电平有效
{
key=PCF8574_ReadBit(EX_IO);
//读取 EXIO 状态,同时清除 PCF8574 的中断输出(INT 恢复高电平)
if(key==0)LED1_Toggle;
//LED1 状态取反
}
i++;
delay_ms(10);
if(i==20)
{
LED0_Toggle;//提示系统正在运行
i=0;
}
}
}
该段代码,我们通过 KEY0 按键可以控制蜂鸣器的开关,另外,在 while 循环里面,会不
停的检测 PCF8574 的中断引脚,是否有输出中断,如果有,就读取 EXIO 的状态(读操作会复
位中断,以便检测下一个中断),当 EXIO=0 的时候控制 DS1 开关。同时,在 LCD 模块上面
显示相关信息,并用 DS0 指示程序运行状态。
最后,我们将 PCF8574_ReadOneByte、PCF8574_WriteOneByte、PCF8574_ReadBit 和
PCF8574_WriteBit 这四个函数加入 USMART 控制,这样,我们就可以通过串口调试助手,控
制 PCF8574,方便测试。
至此,我们的软件设计部分就结束了。
31.4 下载验证
在代码编译成功之后,我们通过下载代码到 ALIENTEK 阿波罗 STM32 开发板上,得到如
图 31.4.1 所示的界面:
图 31.4.1 程序运行界面
屏幕提示 PCF8574 Ready!,表示 PCF8574 已经准备好,同时 DS0 会不停的闪烁,提示程
序正在运行。此时,我们按按键 KEY0,就可以控制蜂鸣器的开和关。我也可以用一根杜邦线,
连接 EXIO(在 P3 排针的最左下角)和 GND(短接一次 GND,改变一次 DS1 的状态),就可
以控制 DS1 的开和关。
另外,本例程还可以用 USMART 调用 PCF8574 相关函数进行控制,大家可以自行测试下,
我们这里就不给大家演示了。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/90305.html