SoftI2C_HAL_Lib/softi2c.c

232 lines
4.8 KiB
C
Raw Permalink Normal View History

2021-10-12 23:33:44 +08:00
/**
* @file softi2c.c
* @author Myth
* @version 0.1
* @date 2021.10.12
* @brief STM32 SoftI2C Library
*/
#include "softi2c.h"
#define SDA_Mode_In SoftI2C_SDA_Mode_In(SoftI2Cx)
#define SDA_Mode_Out SoftI2C_SDA_Mode_Out(SoftI2Cx)
#define SDA_Set HAL_GPIO_WritePin(SoftI2Cx->SDA_GPIO, SoftI2Cx->SDA_Pin, GPIO_PIN_SET)
#define SDA_Clr HAL_GPIO_WritePin(SoftI2Cx->SDA_GPIO, SoftI2Cx->SDA_Pin, GPIO_PIN_RESET)
#define SDA_Read HAL_GPIO_ReadPin(SoftI2Cx->SDA_GPIO, SoftI2Cx->SDA_Pin)
#define SCL_Set HAL_GPIO_WritePin(SoftI2Cx->SCL_GPIO, SoftI2Cx->SCL_Pin, GPIO_PIN_SET)
#define SCL_Clr HAL_GPIO_WritePin(SoftI2Cx->SCL_GPIO, SoftI2Cx->SCL_Pin, GPIO_PIN_RESET)
#define Delay SoftI2C_Delay_us(SoftI2Cx->Delay_Time)
#define Delay_Double SoftI2C_Delay_us(SoftI2Cx->Delay_Time * 2)
uint8_t SoftI2C_GPIOx_Pin_Init(GPIO_TypeDef *GPIOx, uint32_t Pin, uint32_t Mode, uint32_t Pull);
void SoftI2C_SDA_Mode_In(SoftI2C_TypeDef *SoftI2Cx);
void SoftI2C_SDA_Mode_Out(SoftI2C_TypeDef *SoftI2Cx);
HAL_StatusTypeDef SoftI2C_Init(SoftI2C_TypeDef *SoftI2Cx)
{
if (!SoftI2C_GPIOx_Pin_Init(SoftI2Cx->SDA_GPIO, SoftI2Cx->SDA_Pin, GPIO_MODE_OUTPUT_OD, GPIO_NOPULL))
return HAL_ERROR;
if (!SoftI2C_GPIOx_Pin_Init(SoftI2Cx->SCL_GPIO, SoftI2Cx->SCL_Pin, GPIO_MODE_OUTPUT_PP, GPIO_NOPULL))
return HAL_ERROR;
return HAL_OK;
}
void SoftI2C_Start(SoftI2C_TypeDef *SoftI2Cx)
{
SDA_Set;
Delay_Double;
SCL_Set;
Delay_Double;
SDA_Clr;
Delay_Double;
SCL_Clr;
Delay_Double;
}
void SoftI2C_Stop(SoftI2C_TypeDef *SoftI2Cx)
{
SDA_Clr;
Delay_Double;
SCL_Set;
Delay_Double;
SDA_Set;
Delay_Double;
}
void SoftI2C_WriteByte(SoftI2C_TypeDef *SoftI2Cx, uint8_t byte)
{
SCL_Clr;
uint8_t i;
for (i = 0; i < 8; i++)
{
if (byte & 0x80)
SDA_Set;
else
SDA_Clr;
byte <<= 1;
Delay;
SCL_Set;
Delay;
SCL_Clr;
Delay;
}
}
uint8_t SoftI2C_ReadByte(SoftI2C_TypeDef *SoftI2Cx)
{
uint8_t i;
uint8_t data = 0;
SDA_Mode_In;
for (i = 0; i < 8; i++)
{
data <<= 1;
SCL_Clr;
Delay;
SCL_Set;
Delay;
if (SDA_Read == GPIO_PIN_SET)
data |= 0x01;
}
SDA_Mode_Out;
return data;
}
void SoftI2C_Ack(SoftI2C_TypeDef *SoftI2Cx)
{
2021-10-13 17:55:59 +08:00
SCL_Clr;
2021-10-12 23:33:44 +08:00
SDA_Clr;
Delay;
SCL_Set;
Delay;
SCL_Clr;
}
void SoftI2C_NAck(SoftI2C_TypeDef *SoftI2Cx)
{
SCL_Clr;
SDA_Set;
Delay;
SCL_Set;
Delay;
SCL_Clr;
}
uint8_t SoftI2C_WaitAck(SoftI2C_TypeDef *SoftI2Cx)
{
uint8_t i = 0;
SDA_Set;
Delay;
SCL_Set;
Delay;
SDA_Mode_In;
while (SDA_Read == GPIO_PIN_SET)
{
i++;
if (i > 250)
return 1;
}
SDA_Mode_Out;
SCL_Clr;
Delay;
return 0;
}
uint8_t SoftI2C_GPIOx_Pin_Init(GPIO_TypeDef *GPIOx, uint32_t Pin, uint32_t Mode, uint32_t Pull)
{
switch ((uint32_t)(GPIOx))
{
case (uint32_t)GPIOA:
{
GPIO_InitTypeDef GPIO_Initure;
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_Initure.Pin = Pin;
GPIO_Initure.Mode = Mode;
GPIO_Initure.Pull = Pull;
GPIO_Initure.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_Initure);
}
break;
case (uint32_t)GPIOB:
{
GPIO_InitTypeDef GPIO_Initure;
__HAL_RCC_GPIOB_CLK_ENABLE();
GPIO_Initure.Pin = Pin;
GPIO_Initure.Mode = Mode;
GPIO_Initure.Pull = Pull;
GPIO_Initure.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOB, &GPIO_Initure);
}
break;
case (uint32_t)GPIOC:
{
GPIO_InitTypeDef GPIO_Initure;
__HAL_RCC_GPIOC_CLK_ENABLE();
GPIO_Initure.Pin = Pin;
GPIO_Initure.Mode = Mode;
GPIO_Initure.Pull = Pull;
GPIO_Initure.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOC, &GPIO_Initure);
}
break;
case (uint32_t)GPIOD:
{
GPIO_InitTypeDef GPIO_Initure;
__HAL_RCC_GPIOD_CLK_ENABLE();
GPIO_Initure.Pin = Pin;
GPIO_Initure.Mode = Mode;
GPIO_Initure.Pull = Pull;
GPIO_Initure.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOD, &GPIO_Initure);
}
break;
default:
return 0;
}
return 1;
}
void SoftI2C_SDA_Mode_In(SoftI2C_TypeDef *SoftI2Cx)
{
GPIO_InitTypeDef GPIO_Initure;
GPIO_Initure.Pin = SoftI2Cx->SDA_Pin;
GPIO_Initure.Mode = GPIO_MODE_INPUT;
GPIO_Initure.Pull = GPIO_PULLUP;
HAL_GPIO_Init(SoftI2Cx->SDA_GPIO, &GPIO_Initure);
}
void SoftI2C_SDA_Mode_Out(SoftI2C_TypeDef *SoftI2Cx)
{
GPIO_InitTypeDef GPIO_Initure;
GPIO_Initure.Pin = SoftI2Cx->SDA_Pin;
GPIO_Initure.Mode = GPIO_MODE_OUTPUT_OD;
GPIO_Initure.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(SoftI2Cx->SDA_GPIO, &GPIO_Initure);
}