STM32 軟件IIC接口,支持虛擬多個(gè)IIC接口
STM32 軟件IIC接口,支持虛擬多個(gè)IIC接口,需要自己對(duì)底層進(jìn)行移植,比如IO口時(shí)鐘使能,初始化,寫(xiě)1,寫(xiě)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)試宏開(kāi)關(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 *說(shuō)明???????? : 無(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不能超過(guò)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不能超過(guò)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 *說(shuō)明???????? : 無(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 *說(shuō)明???????? : 無(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)到來(lái) *參數(shù)???????? : pHandle:句柄 *返回???????? : TRUE:應(yīng)答成功;FALSE:應(yīng)答失敗 *依賴 :? 底層宏定義 *作者??????? : cp1300@139.com *時(shí)間????? : 2017-07-10 *最后修改時(shí)間 : 2017-07-10 *說(shuō)明???????? : 無(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 *說(shuō)明???????? : 無(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 *說(shuō)明???????? : 無(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 *說(shuō)明???????? : 無(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í)鐘開(kāi)始數(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 *說(shuō)明???????? : 無(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)到來(lái) 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; }
//讀寫(xiě)測(cè)試
SIIC_Start(&IIC_Handel); //發(fā)送起始信號(hào) if(SIIC_SendByte(&IIC_Handel,?PCF8563_IIC_W_ADDR)==FALSE) //發(fā)送寫(xiě)地址 { PCF8563_Debug("PCF8563?發(fā)送寫(xiě)地址?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)