STM32外设芯片驱动学习记录 —— (二) PCA9555 IO扩展芯片驱动开发

文章详细介绍了PCA9555芯片的功能特性,包括其16路输入/输出口,I2C接口,硬件地址设置。解析了Datasheet中的硬件说明、寄存器配置和通信过程,并提供了软件I2C驱动的编写示例,以及PCA9555芯片的初始化和IO配置相关函数的实现。
摘要由CSDN通过智能技术生成

目录

一、芯片介绍

二、Datasheet解读

1.硬件说明

2.寄存器说明

3.通信过程

三、驱动代码编写

1.软件I2C驱动

2. PCA9555芯片驱动函数

总结

 一、芯片介绍

        PCA9555可设置16路输入或输出口,I2C接口,用于IO扩展,3个硬件地址引脚寻址,工作电压:VCC(2.3V 至 5.5V)。

二、Datasheet解读

1.硬件说明

1)框图

48499ec930a744e8bcd5401e0e0adbde.png

 

  • INT:中断输出
  • A0,A1,A2:器件地址
  • SCL,SDA:I2C总线
  • VCC,GND:器件电源供电

  • P07-P00:内部时钟

2)引脚说明

fe3d9d3e93684bc38d20665c0f980fcc.png

bfae25c18bea4cdba34af9c756165935.png 

2.寄存器说明

      cb75896e3662481c8702863c605ae87a.png

 1、对应控制寄存器的控制指令如下:

667c1cf29c7045e9ba20772c30ff23c7.png

 2、硬件地址寻址说明:最多可连接8个芯片

9f925b96b09a4fce908a3c616d46497b.png

 3、器件寄存器

①输入寄存器,用于读取输入IO值

77bfe1ad298b4fe199ab77a44298ccad.png

②输出寄存器,用于写入输出IO值

f14772e494af49d68c6441938cabc22e.png 

③极性设置寄存器,用于设置输入IO的有效电平

ab9a27acea8c4467ba8cdf9aa9cc5d5d.png 

④配置IO口为输入还是输出端口,1为输入,0为输出

081bec93ee7b4b04a2dfc0ceb1389fd4.png 

3.通信过程

       1,写时序

d98411d255c94919bae281acca4b77a4.png

归纳为:器件地址+寄存器命令+P0数据+P1数据 

        2,读时序

b59333730c424cff90d3d73a0906837c.png

 归纳为:器件地址+寄存器命令+器件地址+P0数据+P1数据

三、驱动代码编写

1.软件I2C驱动

        可参照BH1750驱动学习记录:https://blog.csdn.net/Huan_Xiang_Yu/article/details/127341523

2. PCA9555芯片驱动函数

#define   PCA9555_1               0x20//地址:A2 A1 A0均为低电平
#define   PCA9555_2               0x21//地址:A2 A1 为低电平,A0为高电平
   
/********************* 定义PCA9555的寄存器地址 ***********************/
#define   PCA9555_REG_IN0         0x00          //输入寄存器0地址
#define   PCA9555_REG_IN1         0x01          //输入寄存器1地址
#define   PCA9555_REG_OUT0        0x02          //输出寄存器0地址
#define   PCA9555_REG_OUT1        0x03          //输出寄存器1地址
#define   PCA9555_REG_POL0        0x04          //极性反转寄存器0地址(PIN脚为输入时有效)
#define   PCA9555_REG_POL1        0x05          //极性反转寄存器1地址
#define   PCA9555_REG_CFG0        0x06          //方向配置寄存器0地址
#define   PCA9555_REG_CFG1        0x07          //方向配置寄存器1地址


void PCA9555_Init(void);
void PCA9555_WriteData(uint8_t slaveAddress, uint16_t REG_Data);
uint16_t PCA9555_ReadData(uint8_t slaveAddress);





#include "myiic.h"
#include "PCA9555.h"

/**
  * 函数功能: 输入极性设置
  * 输入参数: slaveAddress:器件地址
              REG_Data    :设置值0xffee(ff设置P1,ee设置P0)
  * 返 回 值: 无
  * 说    明: 无
  */
void PCA9555_Polarity_Inversion(uint8_t slaveAddress, uint16_t REG_Data)
{
  uint8_t buf[3]={0};
  buf[0]=PCA9555_REG_POL0;
  buf[1]=(uint8_t)REG_Data;
  buf[2]=(uint8_t)(REG_Data>>8);
  Soft_I2C_Write(slaveAddress,buf,3,1);
}

/**
  * 函数功能: IO配置
  * 输入参数: slaveAddress:器件地址
              REG_Data    :设置值0xffee(ff设置P1,ee设置P0)
  * 返 回 值: 无
  * 说    明: 无
  */
void PCA9555_IOConfiguration(uint8_t slaveAddress, uint16_t REG_Data)
{
  uint8_t buf[3]={0};
  buf[0]=PCA9555_REG_CFG0;
  buf[1]=(uint8_t)REG_Data;
  buf[2]=(uint8_t)(REG_Data>>8);
  Soft_I2C_Write(slaveAddress,buf,3,1);
}

/**
  * 函数功能: 输出口数据
  * 输入参数: slaveAddress:器件地址
              REG_Data    :设置值0xffee(ff设置P1,ee设置P0)
  * 返 回 值: 无
  * 说    明: 无
  */
void PCA9555_WriteData(uint8_t slaveAddress, uint16_t REG_Data)
{
  uint8_t buf[3]={0};
  buf[0]=PCA9555_REG_OUT0;
  buf[1]=(uint8_t)REG_Data;
  buf[2]=(uint8_t)(REG_Data>>8);
  Soft_I2C_Write(slaveAddress,buf,3,1);
}

/**
  * 函数功能: 读取输入口数据
  * 输入参数: slaveAddress:器件地址
              REG_Data    :设置值0xffee(ff设置P1,ee设置P0)
  * 返 回 值: 无
  * 说    明: 无
  */
uint16_t PCA9555_ReadData(uint8_t slaveAddress)
{
  uint8_t buf[2]={0};
  uint16_t temp;
  uint8_t sendBuffer[1]={0};
  sendBuffer[0]=PCA9555_REG_IN0;
  Soft_I2C_Write(slaveAddress,sendBuffer,1,0);
  Soft_I2C_Read(slaveAddress, buf, 2, 1);
  temp= ((uint16_t)buf[1]<<8) + buf[0] ;
  return temp;
}

/**
  * 函数功能: PCA9555初始化
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明: 无
  */  
void PCA9555_Init(void)
{
  PCA9555_IOConfiguration(PCA9555_1, 0xFFFF   );// I2C设备PCA9555-1(地址 0x20) 的16个IO口 输入/输出配置,bit表示,1 - 输入,0 - 输出
  PCA9555_IOConfiguration(PCA9555_2, 0        );// I2C设备PCA9555-2(地址 0x21) 的16个IO口 输入/输出配置,bit表示,1 - 输入,0 - 输出
  PCA9555_Polarity_Inversion(PCA9555_1, 0xFFFF);// I2C设备PCA9555-1(地址 0x20) 输入/输出口反向,bit表示,1 - 反向,0 - 默认 
}

总结

        参考源代码如下链接:

https://download.csdn.net/download/Huan_Xiang_Yu/87585761

 

  • 5
    点赞
  • 55
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
以下是一个基本的STM32F4 HAL库驱动程序示例,用于控制PCA9555 I2C扩展器,并具有容错功能。如果出现错误,将重新初始化PCA9535。 ```c #include "stm32f4xx_hal.h" #define PCA9555_ADDR 0x40 << 1 I2C_HandleTypeDef hi2c1; void PCA9555_Init(void) { uint8_t data[2]; data[0] = 0x06; // Configuration register data[1] = 0x00; // All outputs HAL_I2C_Master_Transmit(&hi2c1, PCA9555_ADDR, data, 2, 1000); } void PCA9555_Write(uint8_t channel, uint8_t value) { uint8_t data[2]; data[0] = 0x02; // Output register data[1] = value; HAL_I2C_Master_Transmit(&hi2c1, PCA9555_ADDR, data, 2, 1000); } void PCA9555_Retry_Write(uint8_t channel, uint8_t value) { uint8_t retry = 3; while(retry--) { if(HAL_I2C_IsDeviceReady(&hi2c1, PCA9555_ADDR, 1, 1000) == HAL_OK) { PCA9555_Write(channel, value); break; } else { HAL_I2C_DeInit(&hi2c1); HAL_I2C_Init(&hi2c1); PCA9555_Init(); } } } int main(void) { HAL_Init(); __HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_I2C1_CLK_ENABLE(); GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_9; GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF4_I2C1; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); hi2c1.Instance = I2C1; hi2c1.Init.ClockSpeed = 100000; hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2; hi2c1.Init.OwnAddress1 = 0; hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; hi2c1.Init.OwnAddress2 = 0; hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; if (HAL_I2C_Init(&hi2c1) != HAL_OK) { Error_Handler(); } PCA9555_Init(); PCA9555_Retry_Write(0, 0xFF); while (1) { PCA9555_Retry_Write(0, 0x00); HAL_Delay(500); PCA9555_Retry_Write(0, 0xFF); HAL_Delay(500); } } ``` 在这个例子中,PCA9555_Init()函数初始化PCA9555,并将其配置为所有输出。PCA9555_Write()函数将输出值写入PCA9555的输出寄存器。PCA9555_Retry_Write()函数带有重试逻辑,如果I2C总线上的设备没有响应,则会重新初始化PCA9555,然后重试写操作。最后,在main()函数中,我们以1秒的间隔循环写入PCA9555的输出寄存器。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值