ALIENTEK 阿波罗 STM32F767 开发板资料连载第31章 IO 扩展实验

ALIENTEK 阿波罗 STM32F767 开发板资料连载第31章 IO 扩展实验1 实验平台 alientek 阿波罗 STM32F767 开发板 2 摘自 STM32F7 开发指南 HAL 库版 关注官方微信号公众号 获取更多资料 正点原子第三十一章 IO 扩展实验上一章 我们介绍了 IIC 驱动 24C02 本章我

大家好,欢迎来到IT知识分享网。

1)实验平台:alientek 阿波罗 STM32F767 开发板

2)摘自《STM32F7 开发指南(HAL 库版)》关注官方微信号公众号,获取更多资料:正点原子

ALIENTEK 阿波罗 STM32F767 开发板资料连载第31章 IO 扩展实验

第三十一章 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 所示:

ALIENTEK 阿波罗 STM32F767 开发板资料连载第31章 IO 扩展实验

表 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 所示:

ALIENTEK 阿波罗 STM32F767 开发板资料连载第31章 IO 扩展实验

图 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 所示:

ALIENTEK 阿波罗 STM32F767 开发板资料连载第31章 IO 扩展实验

图 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 所示:

ALIENTEK 阿波罗 STM32F767 开发板资料连载第31章 IO 扩展实验

图 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 所示:

ALIENTEK 阿波罗 STM32F767 开发板资料连载第31章 IO 扩展实验

图 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 所示的界面:

ALIENTEK 阿波罗 STM32F767 开发板资料连载第31章 IO 扩展实验

图 31.4.1 程序运行界面

屏幕提示 PCF8574 Ready!,表示 PCF8574 已经准备好,同时 DS0 会不停的闪烁,提示程

序正在运行。此时,我们按按键 KEY0,就可以控制蜂鸣器的开和关。我也可以用一根杜邦线,

连接 EXIO(在 P3 排针的最左下角)和 GND(短接一次 GND,改变一次 DS1 的状态),就可

以控制 DS1 的开和关。

另外,本例程还可以用 USMART 调用 PCF8574 相关函数进行控制,大家可以自行测试下,

我们这里就不给大家演示了。

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/90305.html

(0)

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信