PCF8574有两个型号,PCF8574T是简称PCF8574,PCF8574A又是另一个版本,一定要分清楚它们的区别,因为不分清后面发地址会很麻烦,他们前三位地址不一样。
我使用的就是PCF8574T
实际上他俩也就地址不同
地址字节内容:
PCF8574A地址前四位不是0100而是0111
PCF8574时序图
A是应答信号
A是应答信号
PCF8574中断引脚的用处:
默认初始引脚是都为1,一旦引脚发生上升沿或下降沿变化,INT引脚就会变低,你可以设置mcu去读取该引脚,若为低就读取判断哪个引脚变化了,再把读取到的引脚状态写入PCF8574里,这就可在不影响现在引脚状态的情况下,完成消除中断的作用,不然他会一直INT拉低
INT引脚检查的上升沿下降沿是针对初始值11111111,但当你写入引脚后就会变为关于写入的引脚状态的边沿检测
pcf8574.c
#include "./BSP/PCF8574/pcf8574.h"
#include "./SYSTEM/delay/delay.h"
/**
* @brief 初始化PCF8574
* @param 无
* @retval 0, 成功;
1, 失败;
*/
uint8_t pcf8574_init(void)
{
uint8_t temp = 0;
GPIO_InitTypeDef gpio_init_struct;
PCF8574_GPIO_CLK_ENABLE(); /* 使能GPIOB时钟 */
gpio_init_struct.Pin = PCF8574_GPIO_PIN; /* PB12 */
gpio_init_struct.Mode = GPIO_MODE_INPUT; /* 输入 */
gpio_init_struct.Pull = GPIO_PULLUP; /* 上拉 */
gpio_init_struct.Speed = GPIO_SPEED_HIGH; /* 高速 */
HAL_GPIO_Init(PCF8574_GPIO_PORT, &gpio_init_struct); /* 初始化 */
iic_init(); /* IIC初始化 */
/* 检查PCF8574是否在位 */
iic_start();
iic_send_byte(PCF8574_ADDR); /* 写地址 */
temp = iic_wait_ack(); /* 等待应答,通过判断是否有ACK应答,来判断PCF8574的状态 */
iic_stop(); /* 产生一个停止条件 */
pcf8574_write_byte (0xFF);
return temp;
}
uint8_t pcf8574_read_byte (void)
{
uint8_t temp = 0;
iic_start(); /* 发送起始信号 */
iic_send_byte(0x41); /* 发送读操作地址 */
iic_wait_ack( ); /* 等待pcf8574的应答 */
temp = iic_read_byte(0); /* 读取1Byte数据并发nACK信号 */
iic_stop (); /* 发送停止信号 */
return temp;
}
void pcf8574_write_byte (uint8_t data)
{
iic_start(); /* 发送起始信号 */
iic_send_byte(0x40); /* 发送写操作地址 */
iic_wait_ack( ); /* 等待pcf8574的应答 */
iic_send_byte(data); /* 发送1Byte数据设置pcf8574的IO状态 */
iic_wait_ack( ); /* 等待pcf8574的应答 */
iic_stop (); /* 发送停止信号 */
delay_ms(10);
}
uint8_t pcf8574_read_bit(uint8_t bit)
{
uint8_t temp = 0;
temp = pcf8574_read_byte (); /* temp是8个IO口的电平状态 */
if (temp & (1 << bit))
{
return 1;
}
else
{
return 0;
}
}
void pcf8574_write_bit(uint8_t bit, uint8_t sta)
{
uint8_t temp = 0;
temp = pcf8574_read_byte (); /* temp是8个IO口的电平状态 */
if (sta)
{
temp |= (1 << bit);
}
else
{
temp &= ~(1 << bit);
}
pcf8574_write_byte (temp);
}
pcf8574.h
#ifndef __PCF8574_H
#define __PCF8574_H
#include "./SYSTEM/sys/sys.h"
#include "./BSP/IIC/myiic.h"
/******************************************************************************************/
/* 引脚 定义 */
#define PCF8574_GPIO_PORT GPIOB
#define PCF8574_GPIO_PIN GPIO_PIN_12
#define PCF8574_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOB_CLK_ENABLE(); }while(0) /* PB口时钟使能 */
/******************************************************************************************/
#define PCF8574_INT HAL_GPIO_ReadPin(PCF8574_GPIO_PORT, PCF8574_GPIO_PIN) /* PCF8574 INT脚 */
#define PCF8574_ADDR 0X40 /* PCF8574地址(左移了一位) */
/* PCF8574各个IO的功能 */
#define BEEP_IO 0 /* 蜂鸣器控制引脚 P0 */
#define AP_INT_IO 1 /* AP3216C中断引脚 P1 */
#define DCMI_PWDN_IO 2 /* DCMI的电源控制引脚 P2 */
#define USB_PWR_IO 3 /* USB电源控制引脚 P3 */
#define EX_IO 4 /* 扩展IO,自定义使用 P4 */
#define MPU_INT_IO 5 /* SH3001中断引脚 P5 */
#define RS485_RE_IO 6 /* RS485_RE引脚 P6 */
#define ETH_RESET_IO 7 /* 以太网复位引脚 P7 */
uint8_t pcf8574_init(void);
void pcf8574_write_bit(uint8_t bit, uint8_t sta);
uint8_t pcf8574_read_bit(uint8_t bit);
uint8_t pcf8574_read_byte (void);
void pcf8574_write_byte (uint8_t data);
#endif