/* @文件:AbsSoftIIC.c @作者:你遇了我 @联系:321640253@qq.com @描述:软件IIC @版本:v0.1.2 */ #include "AbsSoftIIC.h" #if(ABS_SOFT_IIC_ON) /**************************抽象实现区(BEGIN)********************************/ /* 实现SDA引脚改变为输入模式 */ void ABS_IIC_SDA_MODE_INPUT(void){ GPIO_InitTypeDef GPIO_InitStruct = {0}; GPIO_InitStruct.Pin = GPIO_PIN_8; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); } /* 实现SDA引脚改变为输出模式 */ void ABS_IIC_SDA_MODE_OUTPUT(void){ GPIO_InitTypeDef GPIO_InitStruct = {0}; GPIO_InitStruct.Pin = GPIO_PIN_8; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); } /**************************抽象实现区(END)**********************************/ /*简易延时*/ static void ABS_IIC_delay(uint16_t T){ while(T--); } /*起始信号*/ void ABS_I2C_Start(void) { ABS_IIC_SDA_Set(); ABS_IIC_SCL_Set(); ABS_IIC_delay(ABS_IIC_DELAY_TIME); ABS_IIC_SDA_Reset(); ABS_IIC_delay(ABS_IIC_DELAY_TIME); ABS_IIC_SCL_Reset(); ABS_IIC_delay(ABS_IIC_DELAY_TIME); } /*结束信号*/ void ABS_I2C_Stop(void) { ABS_IIC_SCL_Reset(); ABS_IIC_SDA_Reset(); ABS_IIC_SCL_Set(); ABS_IIC_delay(ABS_IIC_DELAY_TIME); ABS_IIC_SDA_Set(); } /*等待应答信号*/ ABS_SOFT_IIC_STATE ABS_I2C_WaitAck(void) { ABS_IIC_SDA_Set(); uint16_t timeout = 0; ABS_IIC_delay(ABS_IIC_DELAY_TIME); ABS_IIC_SDA_MODE_INPUT(); ABS_IIC_SCL_Set(); while(ABS_IIC_SDA_READ()){ ABS_IIC_delay(1); timeout++; if(timeout>ABS_IIC_Wait_OUTTime){ ABS_IIC_SCL_Reset(); ABS_IIC_SDA_MODE_OUTPUT(); return ABS_SOFT_IIC_TIMEOUT; } } ABS_IIC_SCL_Reset(); ABS_IIC_SDA_MODE_OUTPUT(); ABS_IIC_delay(ABS_IIC_DELAY_TIME); return ABS_SOFT_IIC_SUCCESS; } void ABS_I2C_Ack(void) { ABS_IIC_SDA_MODE_OUTPUT(); ABS_IIC_SCL_Reset(); ABS_IIC_SDA_Reset(); ABS_IIC_delay(ABS_IIC_DELAY_TIME); ABS_IIC_SCL_Set(); ABS_IIC_delay(ABS_IIC_DELAY_TIME); ABS_IIC_SCL_Reset(); ABS_IIC_delay(ABS_IIC_DELAY_TIME); } void ABS_I2C_NAck(void) { ABS_IIC_SDA_MODE_OUTPUT(); ABS_IIC_SCL_Reset(); ABS_IIC_SDA_Set(); ABS_IIC_delay(ABS_IIC_DELAY_TIME); ABS_IIC_SCL_Set(); ABS_IIC_delay(ABS_IIC_DELAY_TIME); ABS_IIC_SCL_Reset(); ABS_IIC_delay(ABS_IIC_DELAY_TIME); } /*发送一个字节*/ static void ABS_IIC_Send_Byte(uint8_t dat) { uint8_t i; for(i=0;i<8;i++) { if(dat&0x80) { ABS_IIC_SDA_Set(); } else { ABS_IIC_SDA_Reset(); } ABS_IIC_delay(ABS_IIC_DELAY_TIME); ABS_IIC_SCL_Set(); ABS_IIC_delay(ABS_IIC_DELAY_TIME); ABS_IIC_SCL_Reset(); dat<<=1; } ABS_IIC_delay(ABS_IIC_DELAY_TIME); } void ABS_I2C_Read_Byte(uint8_t address,uint8_t *dat) { uint8_t i; ABS_IIC_SCL_Reset(); ABS_IIC_SDA_Reset(); ABS_IIC_SDA_MODE_INPUT(); ABS_IIC_delay(ABS_IIC_DELAY_TIME); for(i=0;i<8;i++) { ABS_IIC_SCL_Set(); ABS_IIC_delay(ABS_IIC_DELAY_TIME); if(ABS_IIC_SDA_READ()) { *dat|=(0x1<<(7-i)); } else { *dat&=~(0x1<<(7-i)); } ABS_IIC_SCL_Reset(); ABS_IIC_delay(ABS_IIC_DELAY_TIME); } } ABS_SOFT_IIC_STATE ABS_I2C_WR_Byte(uint8_t address,uint8_t dat){ ABS_IIC_SCL_Set(); ABS_IIC_SDA_Set(); ABS_I2C_Start(); ABS_IIC_Send_Byte(address); if(ABS_I2C_WaitAck()==ABS_SOFT_IIC_SUCCESS); else { ABS_I2C_Stop(); return ABS_SOFT_IIC_ERROR; } ABS_IIC_Send_Byte(dat); ABS_I2C_WaitAck(); ABS_I2C_Stop(); return ABS_SOFT_IIC_SUCCESS; } /* *@函数:ABS_I2C_WR_Bytes *@功能:向指定的器件地址写入num个字节数据 *@参数: address:器件地址 *dat:需要写入数据的指针 num:数据的长度(不包括器件地址) */ ABS_SOFT_IIC_STATE ABS_I2C_WR_Bytes(uint8_t address,uint8_t *dat,uint8_t num){ ABS_IIC_SCL_Set(); ABS_IIC_SDA_Set(); ABS_I2C_Start(); ABS_IIC_Send_Byte(address); if(ABS_I2C_WaitAck()==ABS_SOFT_IIC_SUCCESS); else { ABS_I2C_Stop(); return ABS_SOFT_IIC_ERROR; } while(num--) { ABS_IIC_Send_Byte(*dat); ABS_I2C_WaitAck(); dat++; } ABS_I2C_Stop(); return ABS_SOFT_IIC_SUCCESS; } ABS_SOFT_IIC_STATE ABS_I2C_RD_Byte(uint8_t address,uint8_t *dat){ ABS_IIC_SCL_Set(); ABS_IIC_SDA_Set(); ABS_I2C_Start(); ABS_IIC_Send_Byte(address); if(ABS_I2C_WaitAck()==ABS_SOFT_IIC_SUCCESS); else { ABS_I2C_Stop(); return ABS_SOFT_IIC_ERROR; } ABS_I2C_Read_Byte(address,dat); ABS_I2C_Stop(); return ABS_SOFT_IIC_SUCCESS; } ABS_SOFT_IIC_STATE ABS_I2C_RD_Bytes(uint8_t address,uint8_t *dat,uint8_t num){ ABS_IIC_SCL_Set(); ABS_IIC_SDA_Set(); ABS_I2C_Start(); ABS_IIC_Send_Byte(address); if(ABS_I2C_WaitAck()==ABS_SOFT_IIC_SUCCESS); else { ABS_I2C_Stop(); return ABS_SOFT_IIC_ERROR; } while(num--) { ABS_I2C_Read_Byte(address,dat); if(num==0)ABS_I2C_NAck(); else ABS_I2C_Ack(); dat++; } ABS_I2C_Stop(); return ABS_SOFT_IIC_SUCCESS; } #endif