STM32 软件IIC接口,支持虚拟多个IIC接口,需要自己对底层进行移植,比如IO口时钟使能,初始化,写1,写0,读取进行移植,移植到自己的硬件平台。
//2020-02-19:更新,增加寄存器读写操作
//SoftwareIIC.c
/*************************************************************************************************************
* 文件名: SoftwareIIC.c
* 功能: STM32 软件IIC接口
* 作者: cp1300@139.com
* 创建时间: 2017-07-10
* 最后修改时间: 2017-11-20
* 详细: 软件IIC接口
2017-11-20:移植到STM32F4
2020-02-09:增加更多的IO口支持
2020-02-16:修改输出为开漏输出,用于兼容WM8994(必须开漏输出);增加通用的寄存器读写函数支持;
*************************************************************************************************************/
#include "system.h"
#include "SoftwareIIC.h"
//调试宏开关
#define SIIC_DBUG 1
#if SIIC_DBUG
#include "system.h"
#define SIIC_Debug(format,...) uart_printf(format,##__VA_ARGS__)
#else
#define SIIC_Debug(format,...) /\
/
#endif //SIIC_DBUG
//相关底层操作接口
#define SIIC_DelayUS(x) Delay_US(x) //延时US
#define SDA_OUT_MODE(GPIOx,bit) SYS_GPIOx_OneInit(GPIOx,bit,OUT_OD_OPU,SPEED_25M) //SDA输出模式
#define SDA_IN_MODE(GPIOx,bit) SYS_GPIOx_OneInit(GPIOx,bit,IN_IPU,IN_NONE) //SDA输入模式
#define SCL_OUT_MODE(GPIOx,bit) SYS_GPIOx_OneInit(GPIOx,bit,OUT_OD_OPU,SPEED_25M) //SCL输出模式
#define SDA_OUT_H(GPIOx,bit) (GPIOx->ODR|=(1<<bit)) //SDA输出高电平
#define SDA_OUT_L(GPIOx,bit) (GPIOx->ODR&=~(1<<bit)) //SDA输出低电平
#define SCL_OUT_H(GPIOx,bit) (GPIOx->ODR|=(1<<bit)) //SCL输出高电平
#define SCL_OUT_L(GPIOx,bit) (GPIOx->ODR&=~(1<<bit)) //SCL输出低电平
#define SDA_IN(GPIOx,bit) ((GPIOx->IDR&(1<<bit))?1:0) //SDA输入
/*************************************************************************************************************************
*函数 : bool SIIC_Init(SIIC_HANDLE *pHandle, GPIO_TypeDef *SDA_GPIOx, GPIO_TypeDef *SCL_GPIOx,u8 SDA_GPIO_BITx, u8 SCL_GPIO_BITx,u8 DelayUS)
*功能 : 软件IIC初始化
*参数 : pHandle:句柄;SDA_GPIOx:SDA IO;SCL_GPIOx:SCL GPIO;SDA_GPIO_BITx:SDA IO位数;SCL_GPIO_BITx:SCL IO位数;DelayUS:通信延时,单位us(1-100us)
*返回 : TRUE:初始化成功;FALSE:初始化失败
*依赖 : 底层宏定义
*作者 : cp1300@139.com
*时间 : 2017-07-10
*最后修改时间 : 2017-07-10
*说明 : 2020-02-09:增加更多的IO口支持
*************************************************************************************************************************/
bool SIIC_Init(SIIC_HANDLE *pHandle, GPIO_TypeDef *SDA_GPIOx, GPIO_TypeDef *SCL_GPIOx,u8 SDA_GPIO_BITx, u8 SCL_GPIO_BITx,u8 DelayUS)
{
SYS_DEV_CLOCK DEV_GPION;
if(pHandle == NULL)
{
SIIC_Debug("初始化软件IIC失败,pHandle句柄为空\r\n");
return FALSE;
}
if(DelayUS < 1) DelayUS = 1;
if(DelayUS > 100) DelayUS = 100;
pHandle->DelayUS = DelayUS;
pHandle->SDA_GPIOx = SDA_GPIOx; //SDA数据线IO
pHandle->SCL_GPIOx = SCL_GPIOx; //SCL时钟线IO
if(SDA_GPIO_BITx > 15)
{
SIIC_Debug("初始化软件IIC失败,SDA_GPIO_BITx不能超过15\r\n");
return FALSE;
}
pHandle->SDA_GPIO_BITx = SDA_GPIO_BITx; //SDA数据线位,0-15
if(SCL_GPIO_BITx > 15)
{
SIIC_Debug("初始化软件IIC失败,SCL_GPIO_BITx不能超过15\r\n");
return FALSE;
}
pHandle->SCL_GPIO_BITx = SCL_GPIO_BITx; //SCL时钟线位,0-15
//判断SDA IO组,进行时钟初始化
switch((u32)SDA_GPIOx)
{
case (u32)GPIOA:
{
DEV_GPION = DEV_GPIOA;
}break;
case (u32)GPIOB:
{
DEV_GPION = DEV_GPIOB;
}break;
case (u32)GPIOC:
{
DEV_GPION = DEV_GPIOC;
}break;
case (u32)GPIOD:
{
DEV_GPION = DEV_GPIOD;
}break;
case (u32)GPIOE:
{
DEV_GPION = DEV_GPIOE;
}break;
case (u32)GPIOF:
{
DEV_GPION = DEV_GPIOF;
}break;
case (u32)GPIOG:
{
DEV_GPION = DEV_GPIOG;
}break;
case (u32)GPIOH:
{
DEV_GPION = DEV_GPIOH;
}break;
case (u32)GPIOI:
{
DEV_GPION = DEV_GPIOI;
}break;
case (u32)GPIOJ:
{
DEV_GPION = DEV_GPIOJ;
}break;
case (u32)GPIOK:
{
DEV_GPION = DEV_GPIOK;
}break;
default:
{
SIIC_Debug("初始化软件IIC失败,SDA_GPIOx无效\r\n");
return FALSE;
}
}
SYS_DeviceClockEnable(DEV_GPION, TRUE); //使能SDA IO时钟
//判断SCL IO组,进行时钟初始化
switch((u32)SCL_GPIOx)
{
case (u32)GPIOA:
{
DEV_GPION = DEV_GPIOA;
}break;
case (u32)GPIOB:
{
DEV_GPION = DEV_GPIOB;
}break;
case (u32)GPIOC:
{
DEV_GPION = DEV_GPIOC;
}break;
case (u32)GPIOD:
{
DEV_GPION = DEV_GPIOD;
}break;
case (u32)GPIOE:
{
DEV_GPION = DEV_GPIOE;
}break;
case (u32)GPIOF:
{
DEV_GPION = DEV_GPIOF;
}break;
case (u32)GPIOG:
{
DEV_GPION = DEV_GPIOG;
}break;
case (u32)GPIOH:
{
DEV_GPION = DEV_GPIOH;
}break;
case (u32)GPIOI:
{
DEV_GPION = DEV_GPIOI;
}break;
case (u32)GPIOJ:
{
DEV_GPION = DEV_GPIOJ;
}break;
case (u32)GPIOK:
{
DEV_GPION = DEV_GPIOK;
}break;
default:
{
SIIC_Debug("初始化软件IIC失败,SCL_GPIOx无效\r\n");
return FALSE;
}
}
SYS_DeviceClockEnable(DEV_GPION, TRUE); //使能SCL IO时钟
SDA_OUT_MODE(SDA_GPIOx,SDA_GPIO_BITx); //SDA输出模式
SCL_OUT_MODE(SCL_GPIOx,SCL_GPIO_BITx); //SCL输出模式
SDA_OUT_H(pHandle->SDA_GPIOx, pHandle->SDA_GPIO_BITx); //SDA=1
SCL_OUT_H(pHandle->SCL_GPIOx, pHandle->SCL_GPIO_BITx); //SCL=1
//接口函数初始化
pHandle->Start = (void (*)(void *))SIIC_Start; //产生IIC起始信号
pHandle->Stop = (void (*)(void *))SIIC_Stop; //产生IIC停止信号
pHandle->SendByte = (bool (*)(void *,u8))SIIC_SendByte; //SIIC发送一个字节
pHandle->ReadByte = (u8 (*)(void *, bool))SIIC_ReadByte; //SIIC读取一个字节
return TRUE;
}
/*************************************************************************************************************************
*函数 : void SIIC_Start(SIIC_HANDLE *pHandle)
*功能 : 产生IIC起始信号
*参数 : pHandle:句柄
*返回 : 无
*依赖 : 底层宏定义
*作者 : cp1300@139.com
*时间 : 2017-07-10
*最后修改时间 : 2020-02-16
*说明 : 结果:SDA输出模式,SDA=0,SCL=0
*************************************************************************************************************************/
void SIIC_Start(SIIC_HANDLE *pHandle)
{
SDA_OUT_MODE(pHandle->SDA_GPIOx, pHandle->SDA_GPIO_BITx); //SDA设置为输出
SDA_OUT_H(pHandle->SDA_GPIOx, pHandle->SDA_GPIO_BITx); //SDA=1
SIIC_DelayUS(1);
SCL_OUT_H(pHandle->SCL_GPIOx, pHandle->SCL_GPIO_BITx); //SCL=1
SIIC_DelayUS(pHandle->DelayUS); //延时
SDA_OUT_L(pHandle->SDA_GPIOx, pHandle->SDA_GPIO_BITx); //SDA=0 START:when CLK is high,DATA change form high to low
SIIC_DelayUS(pHandle->DelayUS); //延时
SCL_OUT_L(pHandle->SCL_GPIOx, pHandle->SCL_GPIO_BITx); //SCL=0,钳住I2C总线,准备发送或接收数据
}
/*************************************************************************************************************************
*函数 : void SIIC_Stop(SIIC_HANDLE *pHandle)
*功能 : 产生IIC停止信号
*参数 : pHandle:句柄
*返回 : 无
*依赖 : 底层宏定义
*作者 : cp1300@139.com
*时间 : 2017-07-10
*最后修改时间 : 2020-02-16
*说明 : 结果:SDA输出模式,SDA=1,SCL=1
*************************************************************************************************************************/
void SIIC_Stop(SIIC_HANDLE *pHandle)
{
SCL_OUT_L(pHandle->SCL_GPIOx, pHandle->SCL_GPIO_BITx); //SCL=0
SIIC_DelayUS(1);
SDA_OUT_L(pHandle->SDA_GPIOx, pHandle->SDA_GPIO_BITx); //SDA=0 //STOP:when CLK is high DATA change form low to high
SIIC_DelayUS(pHandle->DelayUS); //延时
SCL_OUT_H(pHandle->SCL_GPIOx, pHandle->SCL_GPIO_BITx); //SCL=1
SIIC_DelayUS(pHandle->DelayUS); //延时
SDA_OUT_H(pHandle->SDA_GPIOx, pHandle->SDA_GPIO_BITx); //SDA=1
SIIC_DelayUS(1); //延时
}
/*************************************************************************************************************************
*函数 : bool SIIC_WaitAck(SIIC_HANDLE *pHandle)
*功能 : IIC等待应答信号到来
*参数 : pHandle:句柄
*返回 : TRUE:应答成功;FALSE:应答失败
*依赖 : 底层宏定义
*作者 : cp1300@139.com
*时间 : 2017-07-10
*最后修改时间 : 2020-02-16
*说明 : 结果:SDA输出模式,SDA=X,SCL=0
*************************************************************************************************************************/
bool SIIC_WaitAck(SIIC_HANDLE *pHandle)
{
u8 ucErrTime=0;
SDA_IN_MODE(pHandle->SDA_GPIOx, pHandle->SDA_GPIO_BITx); //SDA设置为输入
SIIC_DelayUS(pHandle->DelayUS); //延时
SCL_OUT_H(pHandle->SCL_GPIOx, pHandle->SCL_GPIO_BITx); //SCL=1
SIIC_DelayUS(pHandle->DelayUS); //延时
while(SDA_IN(pHandle->SDA_GPIOx, pHandle->SDA_GPIO_BITx)) //等待低电平
{
ucErrTime++;
if(ucErrTime>50)
{
SIIC_Stop(pHandle);
return FALSE;
}
SIIC_DelayUS(1);
}
SCL_OUT_L(pHandle->SCL_GPIOx, pHandle->SCL_GPIO_BITx); //SCL=0
Delay_US(1);
SDA_OUT_MODE(pHandle->SDA_GPIOx, pHandle->SDA_GPIO_BITx); //SDA设置为输出
return TRUE;
}
/*************************************************************************************************************************
*函数 : void SIIC_Ack(SIIC_HANDLE *pHandle)
*功能 : IIC产生ACK应答
*参数 : pHandle:句柄
*返回 : 无
*依赖 : 底层宏定义
*作者 : cp1300@139.com
*时间 : 2017-07-10
*最后修改时间 : 2020-02-16
*说明 : 结果:SDA输出模式,SDA=0,SCL=0
*************************************************************************************************************************/
void SIIC_Ack(SIIC_HANDLE *pHandle)
{
SCL_OUT_L(pHandle->SCL_GPIOx, pHandle->SCL_GPIO_BITx); //SCL=0
SDA_OUT_L(pHandle->SDA_GPIOx, pHandle->SDA_GPIO_BITx); //SDA=0
SIIC_DelayUS(pHandle->DelayUS); //延时
SCL_OUT_H(pHandle->SCL_GPIOx, pHandle->SCL_GPIO_BITx); //SCL=1
SIIC_DelayUS(pHandle->DelayUS); //延时
SCL_OUT_L(pHandle->SCL_GPIOx, pHandle->SCL_GPIO_BITx); //SCL=0
}
/*************************************************************************************************************************
*函数 : void SIIC_NAck(SIIC_HANDLE *pHandle)
*功能 : SIIC产生NACK应答
*参数 : pHandle:句柄
*返回 : 无
*依赖 : 底层宏定义
*作者 : cp1300@139.com
*时间 : 2017-07-10
*最后修改时间 : 2020-02-16
*说明 : 结果:SDA输出模式,SDA=1,SCL=0
*************************************************************************************************************************/
void SIIC_NAck(SIIC_HANDLE *pHandle)
{
SCL_OUT_L(pHandle->SCL_GPIOx, pHandle->SCL_GPIO_BITx); //SCL=0
SDA_OUT_H(pHandle->SDA_GPIOx, pHandle->SDA_GPIO_BITx); //SDA=1
SIIC_DelayUS(pHandle->DelayUS); //延时
SCL_OUT_H(pHandle->SCL_GPIOx, pHandle->SCL_GPIO_BITx); //SCL=1
SIIC_DelayUS(pHandle->DelayUS); //延时
SCL_OUT_L(pHandle->SCL_GPIOx, pHandle->SCL_GPIO_BITx); //SCL=0
}
/*************************************************************************************************************************
*函数 : bool SIIC_SendByte(SIIC_HANDLE *pHandle, u8 data)
*功能 : SIIC发送一个字节
*参数 : pHandle:句柄;data:要发送的数据
*返回 : TRUE:有应答;FALSE:无应答
*依赖 : 底层宏定义
*作者 : cp1300@139.com
*时间 : 2017-07-10
*最后修改时间 : 2020-02-16
*说明 : 结果:SDA输出模式,SDA=X,SCL=0
*************************************************************************************************************************/
bool SIIC_SendByte(SIIC_HANDLE *pHandle, u8 data)
{
u8 t;
for(t=0;t<8;t++)
{
if(data & 0X80)
{
SDA_OUT_H(pHandle->SDA_GPIOx, pHandle->SDA_GPIO_BITx); //SDA=1
}
else
{
SDA_OUT_L(pHandle->SDA_GPIOx, pHandle->SDA_GPIO_BITx); //SDA=0
}
data <<= 1;
SIIC_DelayUS(pHandle->DelayUS); //延时
SCL_OUT_H(pHandle->SCL_GPIOx, pHandle->SCL_GPIO_BITx); //SCL=1
SIIC_DelayUS(pHandle->DelayUS); //延时
SCL_OUT_L(pHandle->SCL_GPIOx, pHandle->SCL_GPIO_BITx); //SCL=0
}
return SIIC_WaitAck(pHandle); //等待应答
}
/*************************************************************************************************************************
*函数 : u8 SIIC_ReadByte(SIIC_HANDLE *pHandle,bool isAck)
*功能 : SIIC读取一个字节
*参数 : pHandle:句柄;isAck:是否发送ACK
*返回 : 读取到的数据
*依赖 : 底层宏定义
*作者 : cp1300@139.com
*时间 : 2017-07-10
*最后修改时间 : 2020-02-16
*说明 : 结果:SDA输出模式,SDA=X,SCL=0
*************************************************************************************************************************/
u8 SIIC_ReadByte(SIIC_HANDLE *pHandle,bool isAck)
{
u8 i,receive=0;
SDA_IN_MODE(pHandle->SDA_GPIOx, pHandle->SDA_GPIO_BITx); //SDA设置为输入
for(i=0;i<8;i++ )
{
receive<<=1;
//产生时钟
SIIC_DelayUS(pHandle->DelayUS); //延时
SCL_OUT_H(pHandle->SCL_GPIOx, pHandle->SCL_GPIO_BITx); //SCL=1
SIIC_DelayUS(pHandle->DelayUS); //延时
if(SDA_IN(pHandle->SDA_GPIOx, pHandle->SDA_GPIO_BITx))
{
receive++;
}
nop;
SCL_OUT_L(pHandle->SCL_GPIOx, pHandle->SCL_GPIO_BITx); //SCL=0
}
nop;nop;nop;
SDA_OUT_MODE(pHandle->SDA_GPIOx, pHandle->SDA_GPIO_BITx); //SDA设置为输出
if (!isAck)
SIIC_NAck(pHandle);//发送nACK
else
SIIC_Ack(pHandle); //发送ACK
return receive;
}
/*************************************************************************************************************************
* 函数 : bool SIIC_ReadReg(SIIC_HANDLE *pHandle, u16 SlaveAddr, u16 RegAddr, bool is8bitRegAddr, u8 *pDataBuff, u16 ReadByteNum)
* 功能 : 软件IIC读取寄存器(可以读取1个或者多个寄存器)
* 参数 : pHandle:软件IIC句柄;SlaveAddr:从机地址;RegAddr:要读取的寄存器地址;is8bitRegAddr:TRUE:8BIT寄存器地址,FALSE:16bit寄存器地址;
pDataBuff:接收的字节数据缓冲区;ReadByteNum:要读取的寄存器数量;
* 返回 : IIC_ERROR
* 依赖 : 底层宏定义
* 作者 : cp1300@139.com
* 时间 : 2020-02-15
* 最后修改时间 : 2020-02-15
* 说明 : 读取的数据都是小端模式,如果是16bit的寄存器,请读取偶数个数据,并且需要另外进行高低字节对调最后组成16bit数据
*************************************************************************************************************************/
bool SIIC_ReadReg(SIIC_HANDLE *pHandle, u16 SlaveAddr, u16 RegAddr, bool is8bitRegAddr, u8 *pDataBuff, u16 ReadByteNum)
{
u16 i;
SIIC_Start(pHandle); //产生IIC起始信号
if(SIIC_SendByte(pHandle, SlaveAddr) == FALSE) //发送设备地址+写信号
{
DEBUG("[SIIC ERROR]:地址(写)响应NACK\r\n");
return FALSE;
}
if(is8bitRegAddr == FALSE) //16bit寄存器地址
{
if(SIIC_SendByte(pHandle, RegAddr>>8) == FALSE) //发送寄存器地址高位
{
DEBUG("[SIIC ERROR]:寄存器地址MSB发送响应NACK\r\n");
return FALSE;
}
}
if(SIIC_SendByte(pHandle, RegAddr) == FALSE) //发送寄存器地址低位
{
DEBUG("[SIIC ERROR]:寄存器地址LSB发送响应NACK\r\n");
return FALSE;
}
//发送读取
SIIC_Start(pHandle); //产生IIC起始信号
if(SIIC_SendByte(pHandle, SlaveAddr|BIT0) == FALSE) //发送设备地址+读信号
{
DEBUG("[SIIC ERROR]:地址(读)响应NACK\r\n");
return FALSE;
}
//循环读取
for(i = 0;i < ReadByteNum;i ++)
{
if(i == (ReadByteNum-1)) //最后一字节不响应ACK
{
pDataBuff[i] = SIIC_ReadByte(pHandle, FALSE); //SIIC读取一个字节-NAK
}
else
{
pDataBuff[i] = SIIC_ReadByte(pHandle, TRUE); //SIIC读取一个字节-ACK
}
}
SIIC_Stop(pHandle); //产生IIC停止信号
return TRUE;
}
/*************************************************************************************************************************
* 函数 : bool SIIC_WriteReg(IIC_CH_Type ch, u16 SlaveAddr, u16 RegAddr, bool is8bitRegAddr,
u8 *pDataBuff, u16 WriteByteNum)
* 功能 : 软件IIC写寄存器(可以写1个或者多个寄存器)
* 参数 : ch:IIC通道,见IIC_CH_Type;SlaveAddr:从机地址;RegAddr:要写入的寄存器地址;is8bitRegAddr:TRUE:8BIT寄存器地址,FALSE:16bit寄存器地址;
pDataBuff:写入的字节数据缓冲区;WriteByteNum:要写入的寄存器数量;
* 返回 : IIC_ERROR
* 依赖 : 底层宏定义
* 作者 : cp1300@139.com
* 时间 : 2020-02-16
* 最后修改时间 : 2020-02-16
* 说明 : 写入的数据都是小端模式,如果是16bit的寄存器,请写入偶数个数据,并且需要提前进行高低字节对调最后组成高字节在前的数据buff
*************************************************************************************************************************/
bool SIIC_WriteReg(SIIC_HANDLE *pHandle, u16 SlaveAddr, u16 RegAddr, bool is8bitRegAddr, u8 *pDataBuff, u16 WriteByteNum)
{
u16 i;
SIIC_Start(pHandle); //产生IIC起始信号
if(SIIC_SendByte(pHandle, SlaveAddr) == FALSE) //发送设备地址+写信号
{
DEBUG("[SIIC ERROR]:地址(写)响应NACK\r\n");
return FALSE;
}
if(is8bitRegAddr == FALSE) //16bit寄存器地址
{
if(SIIC_SendByte(pHandle, RegAddr>>8) == FALSE) //发送寄存器地址高位
{
DEBUG("[SIIC ERROR]:寄存器地址MSB发送响应NACK\r\n");
return FALSE;
}
}
if(SIIC_SendByte(pHandle, RegAddr) == FALSE) //发送寄存器地址低位
{
DEBUG("[SIIC ERROR]:寄存器地址LSB发送响应NACK\r\n");
return FALSE;
}
//循环写入
for(i = 0;i < WriteByteNum;i ++)
{
if(SIIC_SendByte(pHandle, pDataBuff[i]) == FALSE) //发送数据
{
DEBUG("[SIIC ERROR]:寄存器地址LSB发送响应NACK\r\n");
return FALSE;
}
}
SIIC_Stop(pHandle); //产生IIC停止信号
return TRUE;
}
//SoftwareIIC.H
/*************************************************************************************************************
* 文件名: SoftwareIIC.c
* 功能: STM32 软件IIC接口
* 作者: cp1300@139.com
* 创建时间: 2017-07-10
* 最后修改时间: 2017-07-10
* 详细: 软件IIC接口
*************************************************************************************************************/
#ifndef _SOFTWARE_IIC_H_
#define _SOFTWARE_IIC_H_
#include "system.h"
//软件IIC接口句柄结构
typedef struct
{
GPIO_TypeDef *SDA_GPIOx; //SDA数据线IO
GPIO_TypeDef *SCL_GPIOx; //SCL时钟线IO
u8 SDA_GPIO_BITx; //SDA数据线位,0-15
u8 SCL_GPIO_BITx; //SCL时钟线位,0-15
u8 DelayUS; //通信延时US
//接口函数
void (*Start)(void *pHandle); //产生IIC起始信号
void (*Stop)(void *pHandle); //产生IIC停止信号
bool (*SendByte)(void *pHandle, u8 data); //SIIC发送一个字节
u8 (*ReadByte)(void *pHandle,bool isAck); //SIIC读取一个字节
}SIIC_HANDLE;
bool SIIC_Init(SIIC_HANDLE *pHandle, GPIO_TypeDef *SDA_GPIOx, GPIO_TypeDef *SCL_GPIOx,u8 SDA_GPIO_BITx, u8 SCL_GPIO_BITx,u8 DelayUS); //软件IIC初始化
void SIIC_Start(SIIC_HANDLE *pHandle); //产生IIC起始信号
void SIIC_Stop(SIIC_HANDLE *pHandle); //产生IIC停止信号
bool SIIC_WaitAck(SIIC_HANDLE *pHandle); //IIC等待应答信号到来
void SIIC_Ack(SIIC_HANDLE *pHandle); //IIC产生ACK应答
void SIIC_NAck(SIIC_HANDLE *pHandle); //SIIC产生NACK应答
bool SIIC_SendByte(SIIC_HANDLE *pHandle, u8 data); //SIIC发送一个字节
u8 SIIC_ReadByte(SIIC_HANDLE *pHandle,bool isAck); //SIIC读取一个字节
bool SIIC_ReadReg(SIIC_HANDLE *pHandle, u16 SlaveAddr, u16 RegAddr, bool is8bitRegAddr, u8 *pDataBuff, u16 ReadByteNum); //软件IIC读取寄存器(可以读取1个或者多个寄存器)
bool SIIC_WriteReg(SIIC_HANDLE *pHandle, u16 SlaveAddr, u16 RegAddr, bool is8bitRegAddr, u8 *pDataBuff, u16 WriteByteNum); //软件IIC写寄存器(可以写1个或者多个寄存器)
#endif /*_SOFTWARE_IIC_H_*/
//初始化测试
static SIIC_HANDLE IIC_Handel;
#define PCF8563_SDA_GPIOx GPIOB
#define PCF8563_SCL_GPIOx GPIOB
#define PCF8563_SDA_Bit 9
#define PCF8563_SCL_Bit 8
if(SIIC_Init(&IIC_Handel,PCF8563_SDA_GPIOx, PCF8563_SCL_GPIOx, PCF8563_SDA_Bit, PCF8563_SCL_Bit, 1) == FALSE)
{
PCF8563_Debug("**********************PCF8563 初始化失败,IIC接口初始化失败!\r\n");
return FALSE;
}
//读写测试
SIIC_Start(&IIC_Handel); //发送起始信号
if(SIIC_SendByte(&IIC_Handel, PCF8563_IIC_W_ADDR)==FALSE) //发送写地址
{
PCF8563_Debug("PCF8563 发送写地址 ACK错误\r\n");
return FALSE;
}
if(SIIC_SendByte(&IIC_Handel, RegIndex)==FALSE) //发送要读取的寄存器地址
{
PCF8563_Debug("PCF8563 发送要读取的寄存器地址2 ACK错误\r\n");
return FALSE;
}
SIIC_Start(&IIC_Handel); //发送起始信号
//寄存器读写demo
//触摸屏IIC读取寄存器接口-8bit地址与8bit寄存器
bool TP_FT5336_IIC_ReadReg(u16 SlaveAddr, u8 RegAddr, u8 *pDataBuff, u16 ByteNum)
{
if(IIC_MasterReadReg(FT5336_IIC_CH, SlaveAddr, RegAddr, TRUE, pDataBuff, ByteNum) == IIC_OK)
{
return TRUE;
}
else
{
return FALSE;
}
}
//触摸屏IIC写寄存器接口-8bit地址与8bit寄存器
bool TP_FT5336_IIC_WriteReg(u16 SlaveAddr, u8 RegAddr, u8 *pDataBuff, u16 ByteNum)
{
if(IIC_MasterWriteReg(FT5336_IIC_CH, SlaveAddr, RegAddr, TRUE, pDataBuff, ByteNum) == IIC_OK)
{
return TRUE;
}
else
{
return FALSE;
}
}
//WM8994IIC读取寄存器接口-16bit地址与16bit寄存器
bool WM8994_IIC_ReadReg(u16 SlaveAddr, u16 RegAddr, u16 *pDataBuff, u16 RegNum)
{
u8 i;
if(IIC_MasterReadReg(FT5336_IIC_CH, SlaveAddr, RegAddr, FALSE, (u8 *)pDataBuff, RegNum*2) == IIC_OK)
{
for(i = 0;i < RegNum;i ++) //进行高低位对调
{
pDataBuff[i] = SWAP16(pDataBuff[i]);
}
return TRUE;
}
else
{
return FALSE;
}
}
//WM8994 IIC写寄存器接口-16bit地址与16bit寄存器
bool WM8994_IIC_WriteReg(u16 SlaveAddr, u16 RegAddr, u16 *pDataBuff, u16 RegNum)
{
u8 i;
for(i = 0;i < RegNum;i ++) //进行高低位对调
{
pDataBuff[i] = SWAP16(pDataBuff[i]);
}
if(IIC_MasterWriteReg(FT5336_IIC_CH, SlaveAddr, RegAddr, FALSE, (u8 *)pDataBuff, RegNum*2) == IIC_OK)
{
return TRUE;
}
else
{
return FALSE;
}
}