📄 pca9555.c
字号:
/*=========================================================================*
* 项目:
* 文件: .\src\bsp\pca9555.c
* 描述: pca9555的驱动程序
* 编译:
* 版本: 0.1
* 创建日期: 2007年6月20日
* 最后修订:
* 函数列表:
* 修改历史:
* 编译环境: RVMDK 3.05 + RTL-ARM 3.05
* ----------------------------------------------------------------------
* 使用IIC0
* 使用互斥量MUT_i2c
*=========================================================================*/
#include <71x_lib.h>
#include <RTL.h>
#include "PCA9555.h"
#define PCA9555_I2C_ADDR 0x40
#define PCA9555_ADDR 0x00
#define I2C_ERR_EXIT(v) v -= 1; if(v == 0) return;
#define I2C_ERR_RETURN(v,r) v -= 1; if(v == 0) return(r);
extern OS_MUT MUT_i2c;
#define I2C_SCL 0x2000
#define I2C_SDA 0x4000
/*=============================================================================
* 名称: Write_PCA9555_Reg
* 描述: 向PCA9555写入命令和数据
* 创建: 赖晓芳 2006年12月19日
* 最后修订: 2006年12月19日 11:20:40
* 调用: None
* 输入参数: 寄存器(命令)、数据
* 返回值: None
* 特殊说明: RVMDK 3.05 + RTL-ARM 3.05
*=============================================================================*/
void Write_PCA9555_Reg( u8 cmd, u8 dat )
{
u32 i = 10000;
I2C_STARTGenerate( I2C0, ENABLE ); // I2C总线开始条件
while ( !( I2C0->SR1 & I2C_SB ) )
{
I2C_ERR_EXIT(i);
}
I2C0->DR = (PCA9555_I2C_ADDR | (PCA9555_ADDR << 1)) & 0xfe; // 发送器件地址
while ( !( I2C0->SR2 & 0x20 ) ) // ENDAD
{
I2C_ERR_EXIT(i);
}
I2C0->CR |= 0x20; // Set PE
while ( !( I2C0->SR1 & I2C_BTF ) ) // 发送命令
{
I2C_ERR_EXIT(i);
}
I2C0->DR = cmd;
while ( !( I2C0->SR1 & I2C_BTF ) ) // 发送数据
{
I2C_ERR_EXIT(i);
}
I2C0->DR = dat;
while ( !( I2C0->SR1 & I2C_BTF ) )
{
I2C_ERR_EXIT(i);
}
I2C_STOPGenerate( I2C0, ENABLE ); // 停止I2C总线
while ( I2C0->CR & I2C_STOP_Mask )
{
I2C_ERR_EXIT(i);
}
}
/*=============================================================================
* 名称: Initial_PCA9555
* 描述: 初始化PCA9555
* 创建: 赖晓芳 2006年12月19日
* 最后修订: 2006年12月19日 11:26:13
* 调用: None
* 输入参数: None
* 返回值: None
* 特殊说明: RVMDK 3.05 + RTL-ARM 3.05
*=============================================================================*/
void Initial_PCA9555(void)
{
os_mut_wait( MUT_i2c, 0xffff );
GPIO_Config( GPIO1, 0x0800, GPIO_IPUPD_WP ); //将P1.11配置为上拉输入用于PCA9555的IRQ线
GPIO_Config( GPIO1, I2C_SCL | I2C_SDA, GPIO_AF_OD );
I2C_Init( I2C0 );
I2C_FCLKConfig( I2C0 );
I2C_OnOffConfig( I2C0, ENABLE );
I2C_SpeedConfig( I2C0, 400000 );
I2C_AcknowledgeConfig( I2C0, ENABLE );
Write_PCA9555_Reg(0x02, 0xff); // 所有P0输出置为高电平
Write_PCA9555_Reg(0x03, 0xff); // 所有P1输出置为高电平
Write_PCA9555_Reg(0x04, 0x00); // 所有P0输入均不反转
Write_PCA9555_Reg(0x05, 0x00); // 所有P1输入均不反转
Write_PCA9555_Reg(0x06, 0x00); // 配置输入输出P0.0/1/2/3/4/5/6/7输出
Write_PCA9555_Reg(0x07, 0xf0); // 配置输入输出P1.0/1/2/3输出、4/5/6/7输入
os_mut_release( MUT_i2c );
}
/*=============================================================================
* 名称: Read_PCA9555_Reg
* 描述: 读取数据
* 创建: 赖晓芳 2006年12月19日
* 最后修订: 2006年12月19日 11:25:00
* 调用: None
* 输入参数: 寄存器号(命令)
* 返回值: 读取的数据
* 特殊说明: RVMDK 3.05 + RTL-ARM 3.05
*=============================================================================*/
u8 Read_PCA9555_Reg( u8 RegAddr )
{
u8 c;
u32 i = 10000;
I2C_STARTGenerate( I2C0, ENABLE ); // I2C总线开始条件
while ( !( I2C0->SR1 & I2C_SB ) )
{
I2C_ERR_RETURN(i, 0x00);
}
I2C0->DR = (PCA9555_I2C_ADDR | (PCA9555_ADDR << 1)) & 0xfe; // 发送器件地址
while ( !( I2C0->SR2 & 0x20 ) ) // ENDAD
{
I2C_ERR_RETURN(i, 0x00);
}
I2C0->CR |= 0x20; // Set PE
while ( !( I2C0->SR1 & I2C_BTF ) ) //发送命令
{
I2C_ERR_RETURN(i, 0x00);
}
I2C0->DR = RegAddr;
while ( !( I2C0->SR1 & I2C_BTF ) )
{
I2C_ERR_RETURN(i, 0x00);
}
I2C_AcknowledgeConfig( I2C0, DISABLE );
I2C_STARTGenerate( I2C0, ENABLE ); // 二次启动I2C总线
while ( !( I2C0->SR1 & I2C_SB ) )
{
I2C_ERR_RETURN(i, 0x00);
}
I2C0->DR = (PCA9555_I2C_ADDR | (PCA9555_ADDR << 1)) | 0x01; // 发送器件地址
while ( !( I2C0->SR2 & 0x20 ) ) // ENDAD
{
I2C_ERR_RETURN(i, 0x00);
}
I2C0->CR |= 0x20; // Set PE
while ( !( I2C0->SR1 & I2C_BTF ) ) // 接收数据
{
I2C_ERR_RETURN(i, 0x00);
}
I2C_STOPGenerate( I2C0, ENABLE );
c = I2C0->DR;
while ( I2C0->CR & I2C_STOP_Mask )
{
I2C_ERR_RETURN(i, 0x00);
}
return c;
}
/*=============================================================================
* 名称: OUT_PCA9555_IO
* 描述: 从PCA9555指定端口输出
* 创建: 赖晓芳 2006年12月19日
* 最后修订: 2006年12月19日 11:42:55
* 调用: None
* 输入参数: 要控制IO的位置,要控制IO的值
* 返回值: None
* 特殊说明: RVMDK 3.05 + RTL-ARM 3.05
*=============================================================================*/
void OUT_PCA9555_IO(u8 bit_pot, u8 bit_value)
{
u8 port_value;
os_mut_wait( MUT_i2c, 0xffff );
if(bit_pot < 8)
{
port_value = Read_PCA9555_Reg(0x02);
port_value &= (~(0x01 << bit_pot));
port_value |= (bit_value << bit_pot);
Write_PCA9555_Reg(0x02, port_value);
}
else
{
port_value = Read_PCA9555_Reg(0x03);
port_value &= (~(0x01 << (bit_pot - 8)));
port_value |= (bit_value << (bit_pot - 8));
Write_PCA9555_Reg(0x03, port_value);
}
os_mut_release( MUT_i2c );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -