打造一个通用性MCU架构,支持CX32/AT32/NRF51/NRF52等。 OS支持RTX4/RTX5/FreeRtos。 采用VsCode+GCC组合,VsCode+KEIL5,超强开发方式。 QQ群:524408033

LiSun

打造一个通用性MCU架构,支持CX32/AT32/NRF51/NRF52等。 OS支持RTX4/RTX5/FreeRtos。 采用VsCode+GCC组合,VsCode+KEIL5,超强开发方式。 QQ群:524408033

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

描述
这个用于两线双向总线(I 2 C)的16位扩展器设计用于2.3V至5.5VV CC 运行。通过I 2 C接口[串行时钟(SCL),串行数据(SDA)],它为大多数微控制器系列产品提供通用远程I /O扩展。

PCA9555由两个8位配置(输入或输出选择),输入端口,输出端口和极性反转(高电平有效或低电平有效运行)寄存器组成。在加电时,I /O被配置为输入。系统主控制器可以通过写入I /O配置位将I /O启动为输入或输出。每一个输入或者输出的数据被保存在相应的输入或者输出寄存器内。输入端口寄存器的极性可借助极性反转寄存器进行转换。所有寄存器都可由系统主控器读取。

特性
1μA低待机电流消耗(最大值)
I 2 C至并行端口扩展器
开漏电路低电平有效中断输出
可耐受5V电压的I /O端口
兼容大多数微控制器
li>400kHz快速I 2 C总线
针对多达8个器件使用的3个硬件地址引脚寻址
极性反转寄存器
具有最大高电流驱动能力的锁存输出,可用于直接驱动LED
闩锁性能超出JESD 78 II类规范要求的100mA
< li>静电放电(ESD)保护性能超过JESD 22规范的要求
2000V人体放电模型(A114-A)
200V机器模型(A115-A)
< li> 1000V充电器件模型(C101)

端口扩展芯片 PCA9555重新上电后,配置会恢复到默认值,P0.0引脚默认是输入状态。
在加电时,I/O 被配置为输入。系统主控制器可以通过写入 I/O 配置位将 I/O 启动为输入或输出。每一个输入或者输出的数据被保存在相应的输入或者输出寄存器内。
在这里插入图片描述
PCA9555,将8个寄存器分为四个寄存器组,即每组2个寄存器,这样可以联系写两个数据,第二个数据指的是REG_ADDR的下一个寄存器,而且也指出了,没有限制非要写两个数据,可以写一个之后主机立马发送停止位,这样相当于只写了一位数据,这种的状态机就比较复杂一些。

再针对时序进行分析,如下是写的时序,一共有两种command,一种是将数据作为并行端口输出,一种是将相应的寄存器写入到相应的配置中去,分别解释

1、写从机地址,从机应答,写COMMAND指出要开始转换数据,从机应答,写PORT0的数据,从机应答,并开始转换,写PORT1的数据,从机应答,并开始转换,其中转换时间位Tpv,主机发送结束

2、写从机地址,从机应答,写COMMADN指出要写配置寄存器,从机应答,写配置寄存器数据,从机应答,写下一个配置寄存器的数据,从机应答,主机发送结束

#include "pca9555.h"
/******************
笔记:pca9555.pdf
1、P17-控制寄存器和命令字节
2、P17-特性:如果之前有发送命令地址,则读数据命令,会从上个地址顺延,并读取数据。直到发送了新的命令地址。
3、P10-通讯过程:IIC启动-->发送器件识别地址1byte(0bit=R1/W0)-->ACK-->发送器件寄存器地址-->ACK-->[读数据/写数据]1byte
*******************/
U_INPUT   EX_IN;
U_OUTPUT  EX_OUT;

/******************************
函数名:PCA9555Init
功  能:初始化器件两组IO口的引脚功能
形  参:PIN--器件信息结构体
返回值:
备  注:
*******************************/
IIC_STATUS PCA9555Init(const IIC_PIN *PIN)
{
    IIC_STATUS status;

    IIC_Init(PIN);
    IIC_Start(PIN);
    IIC_WriteByte(PIN, PIN->ADDR);             //发送器件识别地址+写
    status = IIC_Wait_ACK(PIN);
//  IIC_WriteByte(PIN, PCA9555_REG_POL0);
//  status |= IIC_Wait_ACK(PIN);
//  IIC_WriteByte(PIN, PCA9555_POLARITY0);
//  status |= IIC_Wait_ACK(PIN);
//  IIC_WriteByte(PIN, PCA9555_POLARITY1);
//  status |= IIC_Wait_ACK(PIN);
    IIC_WriteByte(PIN, PCA9555_REG_CFG0);     //寄存器地址写入(配置PIN脚为输入或输出)
    status |= IIC_Wait_ACK(PIN);
    IIC_WriteByte(PIN, PCA9555_DERECTION0);   //设置IO0的0-7引脚全部为输入模式,因为与拨码器连接,作为IPADDR使用。
    status |= IIC_Wait_ACK(PIN);
    IIC_WriteByte(PIN, PCA9555_DERECTION1);   //设置IO1的0-3引脚为输入,4-7为引脚为输出。
    status |= IIC_Wait_ACK(PIN);
    IIC_Stop(PIN);

    if(status)
        return(IIC_WRITE_ERR);
    else
        return(IIC_OK);
}

/******************************
函数名:PCA9555GetPin
功  能:从器件读取引脚状态
形  参:PIN--器件信息结构体 pin--存放引脚状态结构体
返回值:
备  注:
*******************************/
IIC_STATUS PCA9555GetPin(const IIC_PIN *PIN, U_INPUT *pin)
{
    uint8_t ch[2];
    IIC_STATUS status;

    IIC_Start(PIN);
    IIC_WriteByte(PIN, PIN->ADDR);              //发送器件地址+写命令
    status = IIC_Wait_ACK(PIN);
    IIC_WriteByte(PIN, PCA9555_REG_IN0);        //发送器件寄存器地址--0x00--输入寄存器0地址
    status |= IIC_Wait_ACK(PIN);

    IIC_Start(PIN);
    IIC_WriteByte(PIN, PIN->ADDR | 0x01);       //发送器件地址+读命令
    status |= IIC_Wait_ACK(PIN);
    IIC_ReadByte(PIN, &ch[0]);                  //读取[输入寄存器0]的数据
    IIC_ACK(PIN);
    IIC_ReadByte(PIN, &ch[1]);                  //读取[输入寄存器1]的数据(特性:地址自动顺延)
    IIC_NACK(PIN);
    IIC_Stop(PIN);

    if(status)
        return (IIC_READ_ERR);
    else
    {
        pin->input[0] = ch[0];
        pin->input[1] = ch[1];
        return (IIC_OK);
    }
}

/******************************
函数名:PCA9555SetPin
功  能:设置器件的扩展IO口电平状态
形  参:PIN--器件信息结构体   pout--存放引脚状态结构体
返回值:
备  注:设置的值,只对之前配置为输出模式的引脚有效,输入模式的引脚无效。
*******************************/
IIC_STATUS PCA9555SetPin(const IIC_PIN *PIN, const U_OUTPUT *pout)
{
    IIC_STATUS status;

    IIC_Start(PIN);
    IIC_WriteByte(PIN, PIN->ADDR);
    status = IIC_Wait_ACK(PIN);
    IIC_WriteByte(PIN, PCA9555_REG_OUT0);
    status |= IIC_Wait_ACK(PIN);
    IIC_WriteByte(PIN, pout->output[0]);
    status |= IIC_Wait_ACK(PIN);
    IIC_WriteByte(PIN, pout->output[1]);
    status |= IIC_Wait_ACK(PIN);
    IIC_Stop(PIN);
    osDelay(10);
    if(status)
        return (IIC_WRITE_ERR);
    else
        return (IIC_OK);
}

#ifndef __PCA9555_HEAD_
#define __PCA9555_HEAD_

#include "stdio.h"
#include "stdint.h"
#include "string.h"
#include "cmsis_os.h"
#include "hal_iic.h"

/********************* 个人自定义PAC9555的寄存器参数值***********************/
#define	PCA9555_POLARITY0				0x00									//极性反转值0(0不反转 1反转,PIN脚为输入时有效,)
#define	PCA9555_POLARITY1				0x00									//极性反转值1
#define	PCA9555_DERECTION0			0xFF									//方向配置值0 (0输出 1输入)
#define	PCA9555_DERECTION1			0x0F									//方向配置值1  高4位输出脚,低四位输入脚

/********************* 定义PAC9555的寄存器地址 ***********************/
#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地址


typedef struct{
  GPIO_TypeDef* port;
  uint16_t      pin;
}T_GPIO_TYPE;

/*存放PCA9555扩展口的引脚电平状态*/
typedef union{
  uint8_t  input[2];
  uint16_t data;
}U_INPUT;

/*需要对PCA9555扩展口的输出引脚设置电平信息*/
typedef union{
  uint8_t  output[2];
  uint16_t data;
}U_OUTPUT;

extern U_INPUT	EX_IN;
extern U_OUTPUT EX_OUT;
IIC_STATUS PCA9555Init(const IIC_PIN *PIN);
IIC_STATUS PCA9555GetPin(const IIC_PIN *PIN,U_INPUT *pin);
IIC_STATUS PCA9555SetPin(const IIC_PIN *PIN,const U_OUTPUT *pout);

#endif

pca9555.pdf

posted on 2020-04-11 11:18  xuejianqiang  阅读(171)  评论(0编辑  收藏  举报  来源
打造一个通用性MCU架构,支持CX32/AT32/NRF51/NRF52等。 OS支持RTX4/RTX5/FreeRtos。 采用VsCode+GCC组合,VsCode+KEIL5,超强开发方式。 QQ群:524408033