完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
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< } //读取 PCF8574 的某个 IO 的值 //bit:要读取的 IO 编号,0~7 //返回值:此 IO 的值,0 或 1 u8 PCF8574_ReadBit(u8 bit) { u8 data; data=PCF8574_ReadOneByte(); //先读取这个 8 位 IO 的值 if(data&(1< } 该部分为 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 相关函数进行控制,大家可以自行测试下, 我们这里就不给大家演示了。 |
|
相关推荐
|
|
1276 浏览 1 评论
AD7686芯片不传输数据给STM32,但是手按住就会有数据。
1209 浏览 3 评论
2288 浏览 0 评论
如何解决MPU-9250与STM32通讯时,出现HAL_ERROR = 0x01U
1372 浏览 1 评论
hal库中i2c卡死在HAL_I2C_Master_Transmit
1799 浏览 1 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-29 07:01 , Processed in 0.333275 second(s), Total 36, Slave 28 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号