STM32 軟件IIC接口,支持虛擬多個(gè)IIC接口
STM32 軟件IIC接口,支持虛擬多個(gè)IIC接口,需要自己對(duì)底層進(jìn)行移植,比如IO口時(shí)鐘使能,初始化,寫1,寫0,讀取進(jìn)行移植,移植到自己的硬件平臺(tái)。
//SoftwareIIC.c
/*************************************************************************************************************
?*?文件名: SoftwareIIC.c
?*?功能: STM32?軟件IIC接口
?*?作者: cp1300@139.com
?*?創(chuàng)建時(shí)間: 2017-07-10
?*?最后修改時(shí)間: 2017-07-10
?*?詳細(xì): 軟件IIC接口
*************************************************************************************************************/
#include?"system.h"
#include?"GPIO_INIT.h"
#include?"delay.h"
#include?"SoftwareIIC.h"
//調(diào)試宏開關(guān)
#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
//相關(guān)底層操作接口
#define?SIIC_DelayUS(x) Delay_US(x) //延時(shí)US
#define?SDA_OUT_MODE(GPIOx,bit) GPIOx_OneInit(GPIOx,bit,OUT_PP,SPEED_2M) //SDA輸出模式
#define?SDA_IN_MODE(GPIOx,bit) GPIOx_OneInit(GPIOx,bit,IN_IPU,IN_IN) //SDA輸入模式
#define?SCL_OUT_MODE(GPIOx,bit) GPIOx_OneInit(GPIOx,bit,OUT_PP,SPEED_2M) //SCL輸出模式
#define?SDA_OUT_H(GPIOx,bit) (GPIOx->ODR|=(1<ODR&=~(1<ODR|=(1<ODR&=~(1<IDR&(1<<bit))?1:0) //SDA輸入
/*************************************************************************************************************************
*函數(shù)???????? : 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初始化
*參數(shù)???????? : pHandle:句柄;SDA_GPIOx:SDA?IO;SCL_GPIOx:SCL?GPIO;SDA_GPIO_BITx:SDA?IO位數(shù);SCL_GPIO_BITx:SCL?IO位數(shù);DelayUS:通信延時(shí),單位us(1-100us)
*返回???????? : TRUE:初始化成功;FALSE:初始化失敗
*依賴 :? 底層宏定義
*作者??????? : cp1300@139.com
*時(shí)間????? : 2017-07-10
*最后修改時(shí)間 : 2017-07-10
*說明???????? : 無(wú)
*************************************************************************************************************************/
bool?SIIC_Init(SIIC_HANDLE?*pHandle,?GPIO_TypeDef?*SDA_GPIOx,?GPIO_TypeDef?*SCL_GPIOx,u8?SDA_GPIO_BITx,?u8?SCL_GPIO_BITx,u8?DelayUS)
{
u8?DEV_GPION;
if(pHandle?==?NULL)?
{
SIIC_Debug("初始化軟件IIC失敗,pHandle句柄為空rn");
return?FALSE;
}
if(DelayUS?<?1)?DelayUS?=?1;
if(DelayUS?>100)?DelayUS?=?100;
pHandle->DelayUS?=?DelayUS;
pHandle->SDA_GPIOx?=?SDA_GPIOx; //SDA數(shù)據(jù)線IO
pHandle->SCL_GPIOx?=?SCL_GPIOx; //SCL時(shí)鐘線IO
if(SDA_GPIO_BITx?>?15)?
{
SIIC_Debug("初始化軟件IIC失敗,SDA_GPIO_BITx不能超過15rn");
return?FALSE;
}
pHandle->SDA_GPIO_BITx?=?SDA_GPIO_BITx; //SDA數(shù)據(jù)線位,0-15
if(SCL_GPIO_BITx?>?15)?
{
SIIC_Debug("初始化軟件IIC失敗,SCL_GPIO_BITx不能超過15rn");
return?FALSE;
}
pHandle->SCL_GPIO_BITx?=?SCL_GPIO_BITx; //SCL時(shí)鐘線位,0-15
//判斷SDA?IO組,進(jìn)行時(shí)鐘初始化
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;
default:?
{
SIIC_Debug("初始化軟件IIC失敗,SDA_GPIOx無(wú)效rn");
return?FALSE;
}
}
DeviceClockEnable(DEV_GPION,?ENABLE); //使能SDA?IO時(shí)鐘
//判斷SCL?IO組,進(jìn)行時(shí)鐘初始化
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;
default:
{
SIIC_Debug("初始化軟件IIC失敗,SCL_GPIOx無(wú)效rn");
return?FALSE;
}
}
DeviceClockEnable(DEV_GPION,?ENABLE); //使能SCL?IO時(shí)鐘
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
return?TRUE;
}
/*************************************************************************************************************************
*函數(shù)???????? : void?SIIC_Start(SIIC_HANDLE?*pHandle)
*功能???????? : 產(chǎn)生IIC起始信號(hào)
*參數(shù)???????? : pHandle:句柄
*返回???????? : 無(wú)
*依賴 :? 底層宏定義
*作者??????? : cp1300@139.com
*時(shí)間????? : 2017-07-10
*最后修改時(shí)間 : 2017-07-10
*說明???????? : 無(wú)
*************************************************************************************************************************/
void?SIIC_Start(SIIC_HANDLE?*pHandle)
{
SDA_OUT_MODE(pHandle->SDA_GPIOx,?pHandle->SDA_GPIO_BITx); //SDA設(shè)置為輸出
SDA_OUT_H(pHandle->SDA_GPIOx,?pHandle->SDA_GPIO_BITx); //SDA=1
SCL_OUT_H(pHandle->SCL_GPIOx,?pHandle->SCL_GPIO_BITx); //SCL=1
SIIC_DelayUS(pHandle->DelayUS); //延時(shí)
? 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); //延時(shí)
SCL_OUT_L(pHandle->SCL_GPIOx,?pHandle->SCL_GPIO_BITx); //SCL=0,鉗住I2C總線,準(zhǔn)備發(fā)送或接收數(shù)據(jù)?
SIIC_DelayUS(pHandle->DelayUS); //延時(shí)
}
/*************************************************************************************************************************
*函數(shù)???????? : void?SIIC_Stop(SIIC_HANDLE?*pHandle)
*功能???????? : 產(chǎn)生IIC停止信號(hào)
*參數(shù)???????? : pHandle:句柄
*返回???????? : 無(wú)
*依賴 :? 底層宏定義
*作者??????? : cp1300@139.com
*時(shí)間????? : 2017-07-10
*最后修改時(shí)間 : 2017-07-10
*說明???????? : 無(wú)
*************************************************************************************************************************/
void?SIIC_Stop(SIIC_HANDLE?*pHandle)
{
SDA_OUT_MODE(pHandle->SDA_GPIOx,?pHandle->SDA_GPIO_BITx); //SDA設(shè)置為輸出
SCL_OUT_L(pHandle->SCL_GPIOx,?pHandle->SCL_GPIO_BITx); //SCL=0
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); //延時(shí)
SCL_OUT_H(pHandle->SCL_GPIOx,?pHandle->SCL_GPIO_BITx); //SCL=1
SDA_OUT_H(pHandle->SDA_GPIOx,?pHandle->SDA_GPIO_BITx); //SDA=1
SIIC_DelayUS(pHandle->DelayUS); //延時(shí) ???
}
/*************************************************************************************************************************
*函數(shù)???????? : bool?SIIC_WaitAck(SIIC_HANDLE?*pHandle)
*功能???????? : IIC等待應(yīng)答信號(hào)到來
*參數(shù)???????? : pHandle:句柄
*返回???????? : TRUE:應(yīng)答成功;FALSE:應(yīng)答失敗
*依賴 :? 底層宏定義
*作者??????? : cp1300@139.com
*時(shí)間????? : 2017-07-10
*最后修改時(shí)間 : 2017-07-10
*說明???????? : 無(wú)
*************************************************************************************************************************/
bool?SIIC_WaitAck(SIIC_HANDLE?*pHandle)
{
u8?ucErrTime=0;
SDA_IN_MODE(pHandle->SDA_GPIOx,?pHandle->SDA_GPIO_BITx); //SDA設(shè)置為輸入
SDA_OUT_H(pHandle->SDA_GPIOx,?pHandle->SDA_GPIO_BITx); //SDA=1
SIIC_DelayUS(pHandle->DelayUS); //延時(shí)
SCL_OUT_H(pHandle->SCL_GPIOx,?pHandle->SCL_GPIO_BITx); //SCL=1
SIIC_DelayUS(pHandle->DelayUS); //延時(shí) ?
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 ???
return?TRUE;??
}?
/*************************************************************************************************************************
*函數(shù)???????? : void?SIIC_Ack(SIIC_HANDLE?*pHandle)
*功能???????? : IIC產(chǎn)生ACK應(yīng)答
*參數(shù)???????? : pHandle:句柄
*返回???????? : 無(wú)
*依賴 :? 底層宏定義
*作者??????? : cp1300@139.com
*時(shí)間????? : 2017-07-10
*最后修改時(shí)間 : 2017-07-10
*說明???????? : 無(wú)
*************************************************************************************************************************/
void?SIIC_Ack(SIIC_HANDLE?*pHandle)
{
SCL_OUT_L(pHandle->SCL_GPIOx,?pHandle->SCL_GPIO_BITx); //SCL=0 ???
SDA_OUT_MODE(pHandle->SDA_GPIOx,?pHandle->SDA_GPIO_BITx); //SDA設(shè)置為輸出
SDA_OUT_L(pHandle->SDA_GPIOx,?pHandle->SDA_GPIO_BITx); //SDA=0
SIIC_DelayUS(pHandle->DelayUS); //延時(shí) ?
SCL_OUT_H(pHandle->SCL_GPIOx,?pHandle->SCL_GPIO_BITx); //SCL=1
SIIC_DelayUS(pHandle->DelayUS); //延時(shí)
SCL_OUT_L(pHandle->SCL_GPIOx,?pHandle->SCL_GPIO_BITx); //SCL=0 ?
SIIC_DelayUS(pHandle->DelayUS); //延時(shí)
}
/*************************************************************************************************************************
*函數(shù)???????? : void?SIIC_NAck(SIIC_HANDLE?*pHandle)
*功能???????? : SIIC產(chǎn)生NACK應(yīng)答
*參數(shù)???????? : pHandle:句柄
*返回???????? : 無(wú)
*依賴 :? 底層宏定義
*作者??????? : cp1300@139.com
*時(shí)間????? : 2017-07-10
*最后修改時(shí)間 : 2017-07-10
*說明???????? : 無(wú)
*************************************************************************************************************************/ ????
void?SIIC_NAck(SIIC_HANDLE?*pHandle)
{
SCL_OUT_L(pHandle->SCL_GPIOx,?pHandle->SCL_GPIO_BITx); //SCL=0 ???
SDA_OUT_MODE(pHandle->SDA_GPIOx,?pHandle->SDA_GPIO_BITx); //SDA設(shè)置為輸出
SDA_OUT_H(pHandle->SDA_GPIOx,?pHandle->SDA_GPIO_BITx); //SDA=1
SIIC_DelayUS(pHandle->DelayUS); //延時(shí)
SCL_OUT_H(pHandle->SCL_GPIOx,?pHandle->SCL_GPIO_BITx); //SCL=1
SIIC_DelayUS(pHandle->DelayUS); //延時(shí)
SCL_OUT_L(pHandle->SCL_GPIOx,?pHandle->SCL_GPIO_BITx); //SCL=0 ??
SIIC_DelayUS(pHandle->DelayUS); //延時(shí)
}
/*************************************************************************************************************************
*函數(shù)???????? : bool?SIIC_SendByte(SIIC_HANDLE?*pHandle,?u8?data)
*功能???????? : SIIC發(fā)送一個(gè)字節(jié)
*參數(shù)???????? : pHandle:句柄;data:要發(fā)送的數(shù)據(jù)
*返回???????? : TRUE:有應(yīng)答;FALSE:無(wú)應(yīng)答
*依賴 :? 底層宏定義
*作者??????? : cp1300@139.com
*時(shí)間????? : 2017-07-10
*最后修改時(shí)間 : 2017-07-10
*說明???????? : 無(wú)
*************************************************************************************************************************/ ????
bool?SIIC_SendByte(SIIC_HANDLE?*pHandle,?u8?data)
{????????????????????????
????u8?t;?
SDA_OUT_MODE(pHandle->SDA_GPIOx,?pHandle->SDA_GPIO_BITx); //SDA設(shè)置為輸出 ????
????SCL_OUT_L(pHandle->SCL_GPIOx,?pHandle->SCL_GPIO_BITx); //SCL=0?拉低時(shí)鐘開始數(shù)據(jù)傳輸
????for(t=0;tSDA_GPIOx,?pHandle->SDA_GPIO_BITx); //SDA=1
}
else
{
SDA_OUT_L(pHandle->SDA_GPIOx,?pHandle->SDA_GPIO_BITx); //SDA=0
}
????????data?<DelayUS); //延時(shí)
SCL_OUT_H(pHandle->SCL_GPIOx,?pHandle->SCL_GPIO_BITx); //SCL=1
SIIC_DelayUS(pHandle->DelayUS); //延時(shí)
SCL_OUT_L(pHandle->SCL_GPIOx,?pHandle->SCL_GPIO_BITx); //SCL=0
SIIC_DelayUS(pHandle->DelayUS); //延時(shí)
????}
return?SIIC_WaitAck(pHandle); //等待應(yīng)答
}?
/*************************************************************************************************************************
*函數(shù)???????? : u8?SIIC_ReadByte(SIIC_HANDLE?*pHandle,bool?isAck)
*功能???????? : SIIC讀取一個(gè)字節(jié)
*參數(shù)???????? : pHandle:句柄;isAck:是否發(fā)送ACK
*返回???????? : 讀取到的數(shù)據(jù)
*依賴 :? 底層宏定義
*作者??????? : cp1300@139.com
*時(shí)間????? : 2017-07-10
*最后修改時(shí)間 : 2017-07-10
*說明???????? : 無(wú)
*************************************************************************************************************************/?
u8?SIIC_ReadByte(SIIC_HANDLE?*pHandle,bool?isAck)
{
u8?i,receive=0;
SDA_IN_MODE(pHandle->SDA_GPIOx,?pHandle->SDA_GPIO_BITx); //SDA設(shè)置為輸入
????for(i=0;iSCL_GPIOx,?pHandle->SCL_GPIO_BITx); //SCL=0
????????SIIC_DelayUS(pHandle->DelayUS); //延時(shí)
SCL_OUT_H(pHandle->SCL_GPIOx,?pHandle->SCL_GPIO_BITx); //SCL=1
????????receive<SDA_GPIOx,?pHandle->SDA_GPIO_BITx))receive++;???
SIIC_DelayUS(pHandle->DelayUS); //延時(shí)
????} ?
????if?(!isAck)
????????SIIC_NAck(pHandle);//發(fā)送nACK
????else
????????SIIC_Ack(pHandle);?//發(fā)送ACK??
????return?receive;
}
//SoftwareIIC.H
/*************************************************************************************************************
?*?文件名: SoftwareIIC.H
?*?功能: STM32?軟件IIC接口
?*?作者: cp1300@139.com
?*?創(chuàng)建時(shí)間: 2017-07-10
?*?最后修改時(shí)間: 2017-07-10
?*?詳細(xì): 軟件IIC接口
*************************************************************************************************************/
#ifndef?_SOFTWARE_IIC_H_
#define?_SOFTWARE_IIC_H_
#include?"system.h"
//軟件IIC接口句柄結(jié)構(gòu)
typedef?struct?
{
GPIO_TypeDef *SDA_GPIOx; //SDA數(shù)據(jù)線IO
GPIO_TypeDef *SCL_GPIOx; //SCL時(shí)鐘線IO
u8 SDA_GPIO_BITx; //SDA數(shù)據(jù)線位,0-15
u8 SCL_GPIO_BITx; //SCL時(shí)鐘線位,0-15
u8? DelayUS; //通信延時(shí)US
}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); //產(chǎn)生IIC起始信號(hào)
void?SIIC_Stop(SIIC_HANDLE?*pHandle); //產(chǎn)生IIC停止信號(hào)
bool?SIIC_WaitAck(SIIC_HANDLE?*pHandle); //IIC等待應(yīng)答信號(hào)到來
void?SIIC_Ack(SIIC_HANDLE?*pHandle); //IIC產(chǎn)生ACK應(yīng)答
void?SIIC_NAck(SIIC_HANDLE?*pHandle); //SIIC產(chǎn)生NACK應(yīng)答
bool?SIIC_SendByte(SIIC_HANDLE?*pHandle,?u8?data); //SIIC發(fā)送一個(gè)字節(jié)
u8?SIIC_ReadByte(SIIC_HANDLE?*pHandle,bool?isAck); //SIIC讀取一個(gè)字節(jié)
#endif?/*_SOFTWARE_IIC_H_*///初始化測(cè)試
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接口初始化失?。n");
return?FALSE;
}
//讀寫測(cè)試
SIIC_Start(&IIC_Handel); //發(fā)送起始信號(hào)
if(SIIC_SendByte(&IIC_Handel,?PCF8563_IIC_W_ADDR)==FALSE) //發(fā)送寫地址
{
PCF8563_Debug("PCF8563?發(fā)送寫地址?ACK錯(cuò)誤rn");
return?FALSE;
}
if(SIIC_SendByte(&IIC_Handel,?RegIndex)==FALSE) //發(fā)送要讀取的寄存器地址
{
PCF8563_Debug("PCF8563?發(fā)送要讀取的寄存器地址2?ACK錯(cuò)誤rn");
return?FALSE;
}
SIIC_Start(&IIC_Handel); //發(fā)送起始信號(hào) 




