PCF8574T特性
时序
I2C通讯地址=设备地址(固定位+硬件选择位)+数据流向方向(读写位)
关于通讯地址手册 PCF8574T
PCF8574A地址不同
读操作时序
写操作时序
PCF8574中断引脚
PCF8574驱动步骤
步骤2代码 读取PCF8574IO口状态,从机在接收到主机发送的读通讯地址后会锁存IO口状态,并将8个IO口发送到SDA,主机读SDA就行,产生非应答信号,然后产生停止信号
步骤3,设置PCF8574IO口状态,delay_ms(10)是预留充足时间等待写入完成
正点原子PCF8574教学
pcf8574.c
#include "./BSP/MYIIC/pcf8574.h"
#include "./BSP/MYIIC/myiic.h"
//PCF8574初始化,返回0表示从机应答
uint8_t pcf8574_init(void)
{
uint8_t temp;
GPIO_InitTypeDef gpio_init_struct;
__HAL_RCC_GPIOB_CLK_ENABLE();
gpio_init_struct.Pin = GPIO_PIN_2;
gpio_init_struct.Mode = GPIO_MODE_INPUT; //输入
gpio_init_struct.Pull = GPIO_PULLUP; //上拉
gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH; //
HAL_GPIO_Init(GPIOE, &gpio_init_struct);
iic_init();
/*检查PCF8574是否在位*/
iic_start();
iic_send_byte(PCF8574_ADDR); /*写地址*/
temp = iic_wait_ack();
iic_stop();
pcf8574_write_byte(0xFF); //为了规范,把所有位都设置成高电平,PCF8574默认输入高电平
return temp;
}
//主机读pcf8574一个字节,就是读8个IO
uint8_t pcf8574_read_byte(void)
{
uint8_t temp = 0;
iic_start();
iic_send_byte(PCF8574_ADDR + 1); //主机读+1
iic_wait_ack();
temp = iic_read_byte(0); //主机非应答,表示读一个字节
iic_stop();
return temp;
}
//主机写pcf8574一个字节,就是操作8个IO
void pcf8574_write_byte(uint8_t data)
{
iic_start();
iic_send_byte(PCF8574_ADDR); //通讯地址写
iic_wait_ack();
iic_send_byte(data); //发送1byte数据设置PCF8574的IO状态
iic_wait_ack(); //等待pcf8574应答
iic_stop(); //发送停止信号
delay_ms(10); //等待写入完成
}
//主机读pcf8574某个具体IO口
uint8_t pcf8574_read_bit(uint8_t bit)
{
uint8_t temp; //
temp = pcf8574_read_byte(); /*temp 是8个IO口的电平状态*/
if(temp & (1 << bit))
return 1; //高电平
else
return 0; //低电平
}
//主机设置pcf8574某个具体IO口
void pcf8574_write_bit(uint8_t bit, uint8_t sta)
{
uint8_t temp;
temp = pcf8574_read_byte();
if(sta)
temp |= 1 << bit;
else
temp &= ~(1<<bit); //对应位取0
pcf8574_write_byte(temp); //设置
}
pcf8574.h
#ifndef __PCF8574_H
#define __PCF8574_H
#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/MYIIC/myiic.h"
/***************************************/
//引脚定义
#define PCF8574_GPIO_PORT GPIOB
#define PCF8574_GPIO_PIN GPIO_PIN_12
#define PCF8574_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIO_CLK_ENABLE(); }while(0)
/***************************************/
#define PCF8574_INT HAL_GPIO_ReadPin(PCF8574_GPIO_PORT, PCF8574_GPIO_PIN) //输入引脚变换会影响中断引脚
#define PCF8574_ADDR 0X40 /*PCF8574地址(左移了一位,最后一位的读写位,读为1,写为0)*/
/***************************************/
//PCF各个IO功能
#define BEEP_IO 0 /*蜂鸣器控制 P0*/
#define AP_INT_IO 1 /*AP3216C中断引脚*/
#define DCMI_PWDN_IO 2 /*DCMI的电源控制引脚*/
#define USB_PWR_IO 3 /*USB电源控制引脚*/
#define EX_IO 4 /*扩展IO,自定义使用 P4*/
#define MPU_INT_IO 5 /*SH3001中断引脚*/
#define RS485_RE_IO 6 /*RS485_RE引脚*/
#define ETH_RESET_IO 7 /*以太网复位引脚P7*/
uint8_t pcf8574_init(void);
uint8_t pcf8574_read_byte(void);
void pcf8574_write_byte(uint8_t data);
uint8_t pcf8574_read_bit(uint8_t bit);
void pcf8574_write_bit(uint8_t bit, uint8_t sta);
#endif
以上代码例程参考正点原子