【PCA9555详细学习及代码】


本文参考
https://blog.csdn.net/TheOneZn/article/details/122723644
https://blog.csdn.net/LH_SMD/article/details/121354625

PCA9555芯片介绍

PCA9555是一款16位通用输入/输出(GPIO)扩展器,具有中断和弱上拉电阻,适用于I2c总线/SMBus应用。它具有以下特点:
1.PCA9555由两个8位配置(输入或输出选择),输入端口,输出端口和极性反转(高电平有效或低电平有效运行)寄存器组成。
2.在加电时I /O被配置为输入,系统主控制器可以通过写入I /O配置位将I /O启动为输入或输出。
3.每一个输入或者输出的数据被保存在相应的输入或者输出寄存器内。
4.输入端口寄存器的极性可借助极性反转寄存器进行转换。
5.所有寄存器都可由系统主控器读取。
芯片引脚及功能描述:
在这里插入图片描述
在这里插入图片描述

PCA9555详细学习

1.INT引脚功能:当任何输入状态与其对应的状态不同时,PCA9555开漏中断(INT)引脚输出(只对被配置为输入模式的引脚产生反应),用于向单片机指示输入状态已更改。INT可以连接到微控制器的中断输入端,通过在这条线发送中断信号给单片机,如果端口上有传入数据,远程I/O可以通知微控制器,而不必通过通信I2C总线。因此PCA9555可以保持一个简单的从设备。

2.PCA9555芯片采用iic的方式进行通信,其地址如下:
其前四位为固定位,后三位A0,A1,A2为可编程位,用于设置地址。从地址的最后一位定义了要执行的操作(读或写)。高(1)表示读操作,低(0)表示写操作。
芯片地址图

3.控制寄存器和命令字节
当地址位正确应答之后,主机应该发送一个控制字节,控制字节将会存PCA9555的控制寄存器中,其中B0,B1,B2三位,将会定义操作以及内部的寄存器(输入、输出、极性反转或配置),控制寄存器能被读以及写,控制字节只有写的时候才发送。一旦发送了一个命令字节,被寻址的寄存器将继续被读访问,直到已发送新的命令字节。command其实就相当于相应的控制寄存器地址,比如000就是访问input port0的寄存器
在这里插入图片描述

4.PCA9555芯片具有四种内部寄存器:

输入寄存器:输入端口寄存器(寄存器0和1)反映引脚的传入逻辑电平,而不管是否
引脚由配置寄存器定义为输入或输出。它只作用于读操作。写入这些寄存器没有作用。默认值X由外部应用的逻辑级别决定。在进行读操作之前,发送一个带有命令字节的写传输,以指示I2C设备接下来将访问输入端口寄存器。
在这里插入图片描述

输出寄存器:输出端口寄存器(寄存器2和3)显示定义为输出的引脚的传出逻辑电
配置寄存器。这个寄存器中的位值对定义为输入的引脚没有影响。反过来,从这里读寄存器反映控制输出选择的触发器中的值,而不是实际引脚值。
在这里插入图片描述

极性反转寄存器:极性反转寄存器(寄存器4和5)允许定义为输入的引脚极性反转
配置寄存器。向该寄存器里某一位写入1,表明该引脚在输入状态的时候输入极性会反转,写入0则不起作用。
在这里插入图片描述

配置寄存器:配置寄存器(寄存器6和7)配置I/O引脚的方向。如果这个寄存器中的位是设置为1,对应的端口引脚作为高阻抗输出驱动器的输入启用。如果在这一点寄存器清除为0,相应的端口引脚作为输出启用。
在这里插入图片描述

5.通过上面的介绍,PCA9555的功能应该有所了解了,下面来看下然后使用这个芯片:

例1:主机发送从设备地址,从设备地址匹配,从设备发送ack,主机接收应答后发生命令字节,比如发送0x02,等待从机应答后,即可向输出寄存器写入数据改变拓展IO引脚输出。如果命令直接写入的配置寄存器的地址,则可配置IO口的输入输出状态。(在写入输出状态前因先将IO口通过配置寄存器设置为输出状态)

例2:主机发送从设备地址(主要此时起始信号为读写位为写状态,因为等下得得写入命令字节),从设备地址匹配,从设备发送ack,主机发送命令字节,接收应答后,重新发送设备地址(此时起始信号为读写位为读取状态),等待应答主机即可读取从机发送过来得数据。

在这里插入图片描述

PCA9555代码实例

头文件:


#ifndef USER_APP_PCA9555_H_
#define USER_APP_PCA9555_H_

#include "stm32f4xx_ll_gpio.h"
/***************************************************IIC 驱动部门**********************************************************/
#define IIC_SCL_GPIO_PORT  GPIOB
#define IIC_SCL_GPIO_PIN   LL_GPIO_PIN_7

#define IIC_SDA_GPIO_PORT  GPIOB
#define IIC_SDA_GPIO_PIN   LL_GPIO_PIN_8

#define IIC_SCL_SET_GPIO_OUTPUT_STATUS(status)      if(status == 1)   LL_GPIO_SetOutputPin(IIC_SCL_GPIO_PORT, IIC_SCL_GPIO_PIN);\
                                                    else if(status == 0)  LL_GPIO_ResetOutputPin(IIC_SCL_GPIO_PORT,IIC_SCL_GPIO_PIN);

#define IIC_SDA_SET_GPIO_OUTPUT_STATUS(status)     if(status == 1)   LL_GPIO_SetOutputPin(IIC_SDA_GPIO_PORT, IIC_SDA_GPIO_PIN);\
                                                    else if(status == 0)  LL_GPIO_ResetOutputPin(IIC_SDA_GPIO_PORT, IIC_SDA_GPIO_PIN);

#define IIC_SDA_GET_GPIO_INPUT_STATUS   			LL_GPIO_IsInputPinSet(IIC_SDA_GPIO_PORT, IIC_SDA_GPIO_PIN)


void IIC_gpio_init(void);
void IIC_start(void);
void IIC_stop(void);
uint8_t IIC_wait_ack(void);
void IIC_ack(void);
void IIC_nack(void);
void IIC_send_byte(uint8_t txd);
void IIC_send_byte(uint8_t txd);
uint8_t IIC_read_byte(unsigned char ack);
/***********************************************************IIC 驱动 END**********************************************************************/

/************************************************************PCA9555 驱动***********************************************************/
#define SUCCESS 0
#define ERROR   1

#define SLAVE_ADDR0   0x40

#define HOST_WRITE_COMMAND 0x00
#define HOST_READ_COMMAND  0x01

#define INPUT_PORT_REGISTER0                    0x00   /* 输入端口寄存器0,负责IO00-IO07 */
#define INPUT_PORT_REGISTER1                    0x01   /* 输入端口寄存器1,负责IO10-IO17 */
#define OUTPUT_PORT_REGISTER0                   0x02   /* 输入端口寄存器0,负责IO00-IO07 */
#define OUTPUT_PORT_REGISTER1                   0x03   /* 输入端口寄存器1,负责IO10-IO17 */
#define POLARITY_INVERSION_PORT_REGISTER0       0x04   /* 极性反转端口寄存器0,负责IO00-IO07 */
#define POLARITY_INVERSION_PORT_REGISTER1       0x05   /* 极性反转端口寄存器1,负责IO10-IO17 */
#define CONFIG_PORT_REGISTER0                   0x06   /* 输入端口寄存器0,负责IO00-IO07 */
#define CONFIG_PORT_REGISTER1                   0x07   /* 输入端口寄存器1,负责IO10-IO17 */

#define GPIO_PORT0 0
#define GPIO_PORT1 1

#define GPIO_0 0x01
#define GPIO_1 0x02
#define GPIO_2 0x04
#define GPIO_3 0x08
#define GPIO_4 0x10
#define GPIO_5 0x20
#define GPIO_6 0x40
#define GPIO_7 0x80


#define PCA9555_WAIT_IS_RETURN_SUCCESS(flag, tips)    if(flag != SUCCESS)\
                                                        { \
                                                            printf("%s", tips); \
                                                            return ERROR;\
                                                        }

void pca9555_init(void);
void pca9555_read_wtite_test(void);
void pca9555_set_output_mode_all(uint8_t slave_num, uint8_t gpio_port);
void pca9555_set_output_mode(uint8_t slave_num, uint8_t gpio_port,  uint8_t gpio_num);
void pca9555_set_input_mode_all(uint8_t slave_num, uint8_t gpio_port);
void pca9555_set_gpio_output_status(uint8_t slave_num, uint8_t gpio_port,  uint8_t gpio_num, uint8_t status);
void pca9555_set_input_mode(uint8_t slave_num, uint8_t gpio_port,  uint8_t gpio_num);
void pca9555_set_input_mode_all(uint8_t slave_num, uint8_t gpio_port);
void pca9555_set_output_mode_all(uint8_t slave_num, uint8_t gpio_port);
uint8_t pca9555_get_gpio_status(uint8_t slave_num, uint8_t gpio_port,  uint8_t gpio_num);
uint8_t pca9555_read_byte(uint8_t slave_num, uint8_t addr, uint8_t read_register_data, uint8_t *read_data);
uint8_t pca9555_write_byte(uint8_t addr, uint8_t command, uint8_t write_register_data);

#endif /* USER_APP_PCA9555_H_ */

源文件:


#include "hardware/pca9555.h"
#include "main.h"
#include "hardware/timer.h"
#include <stdio.h>

void IIC_gpio_init(void)
{
	LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOC);	/* 使能GPIO时钟 */
	
	LL_GPIO_SetPinMode(IIC_SCL_GPIO_PORT, IIC_SCL_GPIO_PIN, LL_GPIO_MODE_OUTPUT);//设置为推挽输出,初始化高电平
	LL_GPIO_SetPinOutputType(IIC_SCL_GPIO_PORT, IIC_SCL_GPIO_PIN,LL_GPIO_OUTPUT_PUSHPULL);//设置为推挽输出
	LL_GPIO_SetOutputPin(IIC_SCL_GPIO_PORT, IIC_SCL_GPIO_PIN);
	
	LL_GPIO_SetPinMode(IIC_SDA_GPIO_PORT, IIC_SDA_GPIO_PIN, LL_GPIO_MODE_OUTPUT);//设置为推挽输出,初始化高电平
	LL_GPIO_SetPinOutputType(IIC_SDA_GPIO_PORT, IIC_SDA_GPIO_PIN,LL_GPIO_OUTPUT_PUSHPULL);
	LL_GPIO_SetOutputPin(IIC_SDA_GPIO_PORT, IIC_SDA_GPIO_PIN);
}


static void IIC_SDA_set_output(void)
{
	LL_GPIO_SetPinMode(IIC_SDA_GPIO_PORT, IIC_SDA_GPIO_PIN, LL_GPIO_MODE_OUTPUT);
	LL_GPIO_SetPinOutputType(IIC_SDA_GPIO_PORT, IIC_SDA_GPIO_PIN, LL_GPIO_OUTPUT_PUSHPULL);
	LL_GPIO_SetOutputPin(IIC_SDA_GPIO_PORT, IIC_SDA_GPIO_PIN);
}

static void IIC_SDA_set_input(void)
{
	LL_GPIO_SetPinMode(IIC_SDA_GPIO_PORT, IIC_SDA_GPIO_PIN, LL_GPIO_MODE_INPUT);
	LL_GPIO_SetPinPull(IIC_SDA_GPIO_PORT, IIC_SDA_GPIO_PIN, LL_GPIO_PULL_UP);
}

//产生IIC起始信号
void IIC_start(void)
{
    IIC_SDA_set_output(); //sda线输出
    IIC_SDA_SET_GPIO_OUTPUT_STATUS(1);
    IIC_SCL_SET_GPIO_OUTPUT_STATUS(1);
    //sl_udelay_wait(6);
	delay_us(6);
    IIC_SDA_SET_GPIO_OUTPUT_STATUS(0);//START:when CLK is high,DATA change form high to low
    //sl_udelay_wait(6);
	delay_us(6);
    IIC_SCL_SET_GPIO_OUTPUT_STATUS(0);//钳住I2C总线,准备发送或接收数据
}

//产生IIC停止信号
void IIC_stop(void)
{
    IIC_SDA_set_output();//sda线输出
    IIC_SCL_SET_GPIO_OUTPUT_STATUS(0);
    IIC_SDA_SET_GPIO_OUTPUT_STATUS(0);//STOP:when CLK is high DATA change form low to high
    //sl_udelay_wait(6);
	delay_us(6);
    IIC_SCL_SET_GPIO_OUTPUT_STATUS(1);
    IIC_SDA_SET_GPIO_OUTPUT_STATUS(1);//发送I2C总线结束信号
    //sl_udelay_wait(6);
	delay_us(6);
}

//等待应答信号到来
//返回值:1,接收应答失败
//        0,接收应答成功
uint8_t IIC_wait_ack(void)
{
    uint8_t ucErrTime=0;
    IIC_SDA_set_input();  //SDA设置为输入
    IIC_SDA_SET_GPIO_OUTPUT_STATUS(1);
    //sl_udelay_wait(1);
	delay_us(1);
    IIC_SCL_SET_GPIO_OUTPUT_STATUS(1);
    //sl_udelay_wait(1);
	delay_us(1);

    while(IIC_SDA_GET_GPIO_INPUT_STATUS)
    {
        ucErrTime++;
        //sl_udelay_wait(1);
    	delay_us(1);
        if(ucErrTime>250)
        {
            IIC_stop();
            printf("return 1\r\n");
            return 1;
        }
    }
    IIC_SCL_SET_GPIO_OUTPUT_STATUS(0);//时钟输出0
    return 0;
}

//产生ACK应答
 void IIC_ack(void)
{
    IIC_SCL_SET_GPIO_OUTPUT_STATUS(0);
    IIC_SDA_set_output();
    IIC_SDA_SET_GPIO_OUTPUT_STATUS(1);
    //sl_udelay_wait(5);
	delay_us(5);
    IIC_SCL_SET_GPIO_OUTPUT_STATUS(1);
    //sl_udelay_wait(5);
	delay_us(5);
    IIC_SCL_SET_GPIO_OUTPUT_STATUS(0);
}

//不产生ACK应答
void IIC_nack(void)
{
    IIC_SCL_SET_GPIO_OUTPUT_STATUS(0);
    IIC_SDA_set_output();
    IIC_SDA_SET_GPIO_OUTPUT_STATUS(1);
    //sl_udelay_wait(5);
	delay_us(5);
    IIC_SCL_SET_GPIO_OUTPUT_STATUS(1);
    //sl_udelay_wait(5);
	delay_us(5);
    IIC_SCL_SET_GPIO_OUTPUT_STATUS(0);
}

//IIC发送一个字节(高位先发)
//返回从机有无应答
//1,有应答
//0,无应答
void IIC_send_byte(uint8_t txd)
{
    uint8_t t;
    IIC_SDA_set_output();
    IIC_SCL_SET_GPIO_OUTPUT_STATUS(0);//拉低时钟开始数据传输
    for(t=0;t<8;t++)
    {
        //printf("\r\n1 GPIO_PinInGet(IIC_SDA_GPIO_PORT, IIC_SDA_GPIO_PIN) = %d\r\n",  GPIO_PinInGet(IIC_SDA_GPIO_PORT, IIC_SDA_GPIO_PIN));
        IIC_SDA_SET_GPIO_OUTPUT_STATUS((txd&0x80)>>7);
        txd<<=1;
        delay_us(4);
        IIC_SCL_SET_GPIO_OUTPUT_STATUS(1);
        delay_us(4);
        IIC_SCL_SET_GPIO_OUTPUT_STATUS(0);
        delay_us(4);
    }
}

//读1个字节,ack=1时,发送ACK,ack=0,发送nACK(高位先接收)
uint8_t IIC_read_byte(unsigned char ack)
{
    unsigned char i,receive=0;
    IIC_SDA_set_input();//SDA设置为输入
    for(i=0;i<8;i++)
    {
        IIC_SCL_SET_GPIO_OUTPUT_STATUS(0);
        delay_us(4);
        IIC_SCL_SET_GPIO_OUTPUT_STATUS(1);
        receive<<=1;
        if(IIC_SDA_GET_GPIO_INPUT_STATUS)receive++;
        //printf("\r\n2 GPIO_PinInGet(IIC_SDA_GPIO_PORT, IIC_SDA_GPIO_PIN) = %d\r\n",  GPIO_PinInGet(IIC_SDA_GPIO_PORT, IIC_SDA_GPIO_PIN));
        delay_us(4);
    }
    if (!ack)
        IIC_nack();//发送nACK
    else
        IIC_ack(); //发送ACK
    return receive;
}



void pca9555_init(void)
{
    IIC_gpio_init();
}


//pca9555写寄存器值
uint8_t pca9555_write_byte(uint8_t addr, uint8_t command, uint8_t write_register_data)
{
    uint8_t ret = 1;
    IIC_start();
    IIC_send_byte(addr);	//写从机地址
    ret =  IIC_wait_ack();
    PCA9555_WAIT_IS_RETURN_SUCCESS(ret, "[ERROR] wait slave ack error!\r\n");

    IIC_send_byte(command);	//写要写的寄存器地址
    ret =  IIC_wait_ack();
    PCA9555_WAIT_IS_RETURN_SUCCESS(ret, "[ERROR] wait slave ack error!\r\n");

    IIC_send_byte(write_register_data);//写入数据
    ret =  IIC_wait_ack();
    PCA9555_WAIT_IS_RETURN_SUCCESS(ret, "[ERROR] wait slave ack error!\r\n");

    IIC_stop();
    delay_us(10000);
    return SUCCESS;
}

/*
 * pca9555读取寄存器值
 *
 * addr 读取地址
 * read_register_data 要读取的寄存器
 * read_data 读取数据存放地址
 *
 *
 * 返回值:读取成功返回SUCCESS  失败返回ERROR
 *
 * */
uint8_t pca9555_read_byte(uint8_t slave_num, uint8_t addr, uint8_t read_register_data, uint8_t *read_data)
{
    uint8_t ret = 0;
    IIC_start();
    IIC_send_byte(slave_num);			//	写入从机地址
    ret =  IIC_wait_ack();
    PCA9555_WAIT_IS_RETURN_SUCCESS(ret, "[ERROR] wait slave ack error!\r\n");

    IIC_send_byte(read_register_data); //写入要读取的寄存器地址
    ret = IIC_wait_ack();
    PCA9555_WAIT_IS_RETURN_SUCCESS(ret, "[ERROR] wait slave ack error!\r\n");

    IIC_start(); /* 开始接收数据 */
    IIC_send_byte(addr);			   //发送从机地址并设置为读取
    ret = IIC_wait_ack();
    PCA9555_WAIT_IS_RETURN_SUCCESS(ret, "[ERROR] wait slave ack error!\r\n");

    *read_data = IIC_read_byte(0);

    IIC_stop();
    return SUCCESS;
}


/*
 * 设置指定GPIO的模式
 *
 * slave_num  需要操作的从机设备
 * gpio_port  gpio端口  端口0/1
 * gpio_num   哪一个GPIO
 *
 * 返回值:void
 * */
void pca9555_set_output_mode(uint8_t slave_num, uint8_t gpio_port,  uint8_t gpio_num)
{
    uint8_t register_original_data = 0;
    if(gpio_port > 1 || gpio_num > 0x80)  return;
    if(gpio_port == 0)
    {
        pca9555_read_byte(slave_num, slave_num  | HOST_READ_COMMAND, CONFIG_PORT_REGISTER0, &register_original_data);//读取原来的设置
        pca9555_write_byte(slave_num | HOST_WRITE_COMMAND, CONFIG_PORT_REGISTER0, register_original_data & (~gpio_num));//在不影响原来设置的情况下修改配置寄存器的设置
    }
    else if(gpio_port == 1)
    {
        pca9555_read_byte(slave_num, slave_num  | HOST_READ_COMMAND, CONFIG_PORT_REGISTER1, &register_original_data);
        pca9555_write_byte( slave_num | HOST_WRITE_COMMAND, CONFIG_PORT_REGISTER1, register_original_data & (~gpio_num));
    }
}

void pca9555_set_output_mode_all(uint8_t slave_num, uint8_t gpio_port)
{
    uint8_t register_original_data = 0x00;
    if(gpio_port > 1)  return;
    if(gpio_port == 0)
    {
        pca9555_write_byte(slave_num | HOST_WRITE_COMMAND, CONFIG_PORT_REGISTER0, register_original_data);
    }
    else if(gpio_port == 1)
    {
        pca9555_write_byte( slave_num | HOST_WRITE_COMMAND, CONFIG_PORT_REGISTER1, register_original_data);
    }
}

/*
 * 设置GPIO为输入模式
 *
 * slave_num  需要操作的从机设备
 * gpio_port  gpio端口  端口0/1
 * gpio_num   哪一个GPIO
 *
 * 返回值:void
 **/
void pca9555_set_input_mode(uint8_t slave_num, uint8_t gpio_port,  uint8_t gpio_num)
{
    uint8_t register_original_data = 0;
    if(gpio_port > 1 || gpio_num > 0x80)  return;
    if(gpio_port == 0)
    {
        pca9555_read_byte(slave_num, slave_num  | HOST_READ_COMMAND, CONFIG_PORT_REGISTER0, &register_original_data);
        pca9555_write_byte(slave_num | HOST_WRITE_COMMAND, CONFIG_PORT_REGISTER0, register_original_data | gpio_num);
    }
    else if(gpio_port == 1)
    {

        pca9555_read_byte(slave_num, slave_num  | HOST_READ_COMMAND, CONFIG_PORT_REGISTER1, &register_original_data);

        pca9555_write_byte(slave_num | HOST_WRITE_COMMAND, CONFIG_PORT_REGISTER1, register_original_data | gpio_num);//参考的文章里给的代码这里使用的是&,但其实这里应该用|才对啊,不然另外7个全变0了
    }
}

void pca9555_set_input_mode_all(uint8_t slave_num, uint8_t gpio_port)
{
    uint8_t register_original_data = 0xff;
    if(gpio_port > 1 )  return;
    if(gpio_port == 0)
    {
        pca9555_write_byte(slave_num | HOST_WRITE_COMMAND, CONFIG_PORT_REGISTER0, register_original_data);
    }
    else if(gpio_port == 1)
    {
        pca9555_write_byte(slave_num | HOST_WRITE_COMMAND, CONFIG_PORT_REGISTER1, register_original_data);
    }
}

/*
 * 设置GPIO输出状态
 *
 * slave_num  需要操作的从机设备
 * gpio_port  gpio端口  端口0/1
 * gpio_num   哪一个GPIO
 * status     输出状态
 *
 * 返回值:void
 **/
void pca9555_set_gpio_output_status(uint8_t slave_num, uint8_t gpio_port,  uint8_t gpio_num, uint8_t status)
{
    uint8_t register_original_data = 0;
    if(gpio_port > 1 || gpio_num > 0x80)  return;
    if(gpio_port == 0)
    {
        pca9555_read_byte(slave_num, slave_num  | HOST_READ_COMMAND, OUTPUT_PORT_REGISTER0, &register_original_data);
        if(status == 1)
        {
            pca9555_write_byte(slave_num | HOST_WRITE_COMMAND, OUTPUT_PORT_REGISTER0, register_original_data | gpio_num);
        }
        else
        {
            pca9555_write_byte(slave_num | HOST_WRITE_COMMAND, OUTPUT_PORT_REGISTER0, register_original_data & (~gpio_num));
        }
    }
    else if(gpio_port == 1)
    {
        pca9555_read_byte(slave_num, slave_num  | HOST_READ_COMMAND, OUTPUT_PORT_REGISTER1, &register_original_data);
        if(status == 1)
        {
            pca9555_write_byte(slave_num | HOST_WRITE_COMMAND, OUTPUT_PORT_REGISTER1, register_original_data | gpio_num);
        }
        else
        {
            pca9555_write_byte(slave_num | HOST_WRITE_COMMAND, OUTPUT_PORT_REGISTER1, register_original_data & (~gpio_num));
        }
    }
}

/*
 * 获取GPIO状态
 *
 * slave_num  需要操作的从机设备
 * gpio_port  gpio端口  端口0/1
 * gpio_num   哪一个GPIO
 *
 * 返回值:GPIO状态
 **/
uint8_t pca9555_get_gpio_status(uint8_t slave_num, uint8_t gpio_port,  uint8_t gpio_num)
{
    uint8_t register_original_data = 0;
    uint8_t gpio_status = 0;
    if(gpio_port > 1 || gpio_num > 0x80)
    {
        printf("[ERROR] gpio_port > 1 || gpio_num > 0x80\r\n");
        return 2;
    }
    if(gpio_port == 0)
    {

        pca9555_read_byte(slave_num, slave_num  | HOST_READ_COMMAND, INPUT_PORT_REGISTER0, &register_original_data);

    }
    else if(gpio_port == 1)
    {
        pca9555_read_byte(slave_num, slave_num  | HOST_READ_COMMAND, INPUT_PORT_REGISTER1, &register_original_data);
    }
    switch(gpio_num)
    {
        case 0x01:  gpio_status = register_original_data & gpio_num;break;
        case 0x02:  gpio_status = (register_original_data & gpio_num) >> 1;break;
        case 0x04:  gpio_status = (register_original_data & gpio_num) >> 2;break;
        case 0x08:  gpio_status = (register_original_data & gpio_num) >> 3;break;
        case 0x10:  gpio_status = (register_original_data & gpio_num) >> 4;break;
        case 0x20:  gpio_status = (register_original_data & gpio_num) >> 5;break;
        case 0x40:  gpio_status = (register_original_data & gpio_num) >> 6;break;
        case 0x80:  gpio_status = (register_original_data & gpio_num) >> 7;break;
        default:  	printf("[ERROR] gpio error!\r\n");
    }
    return gpio_status;
}

注:
PCA9555采用IIC通信,协议中涉及的延时函数务必保证精确。
上面代码可直接运行在STM32单片机中,只需要对以下两部点进行修改即可
①GPIO输入输出设置
②精确到us级别的延时函数

  • 13
    点赞
  • 53
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值