#ifdef __cplusplus extern "C" { #endif #include "i2c.h" static void I2C_delay() { volatile int i = 17; while (i) i--; } static int HC_I2C_Start() { HC_SDA_H; HC_SCL_H; I2C_delay(); if (!SDA_read) return 0; HC_SDA_L; I2C_delay(); if (HC_SDA_read) return 0; HC_SDA_L; I2C_delay(); return 1; } static void HC_I2C_Stop() { HC_SCL_L; I2C_delay(); HC_SDA_L; I2C_delay(); HC_SCL_H; I2C_delay(); HC_SDA_H; I2C_delay(); } static void HC_I2C_NoAck() { HC_SCL_L; I2C_delay(); HC_SDA_H; I2C_delay(); HC_SCL_H; I2C_delay(); HC_SCL_L; I2C_delay(); } static int HC_I2C_WaitAck() { HC_SCL_L; I2C_delay(); HC_SDA_H; I2C_delay(); HC_SCL_H; I2C_delay(); if (HC_SDA_read) { HC_SCL_L; return 0; } HC_SCL_L; return 1; } static void HC_I2C_SendByte(uint8_t b) { uint8_t i = 8; while (i--) { HC_SCL_L; I2C_delay(); if (b & 0x80) HC_SDA_H; else HC_SDA_L; b <<= 1; I2C_delay(); HC_SCL_H; I2C_delay(); } HC_SCL_L; } static uint8_t HC_I2C_ReadByte() { uint8_t i = 8; uint8_t byte = 0; HC_SDA_H; while (i--) { byte <<= 1; HC_SCL_L; I2C_delay(); HC_SCL_H; I2C_delay(); if (HC_SDA_read) { byte |= 0x01; } } HC_SCL_L; return byte; } void HC_I2C_Init(void) { GPIO_InitTypeDef GPIO_InitStruct; // 使能GPIOB时钟 __HAL_RCC_GPIOB_CLK_ENABLE(); GPIO_InitStruct.Pin = GPIO_PIN_0; // SCL GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; // 开漏输出 GPIO_InitStruct.Pull = GPIO_PULLUP; // 使用上拉 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_1; // SDA GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; // 开漏输出 GPIO_InitStruct.Pull = GPIO_PULLUP; // 使用上拉 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); } void HC_I2C_Write() { HC_I2C_Start(); HC_I2C_SendByte(0xAE); HC_I2C_WaitAck(); HC_I2C_SendByte(0x01); HC_I2C_WaitAck(); HC_I2C_Stop(); } int HC_I2C_Read() { unsigned int BYTE_H=0, BYTE_M=0, BYTE_L=0; float distance=0;//测距距离 //读数据-地址为0xAF if (!HC_I2C_Start()) return 0; HC_I2C_SendByte(0xAF); if (!HC_I2C_WaitAck()) { HC_I2C_Stop(); return 0; } BYTE_H=HC_I2C_ReadByte();//读数据 HC_I2C_WaitAck(); BYTE_M=HC_I2C_ReadByte();//读数据 HC_I2C_WaitAck(); BYTE_L=HC_I2C_ReadByte();//读数据 HC_I2C_NoAck(); HC_I2C_Stop(); distance=((BYTE_H*65536)+(BYTE_M*256)+BYTE_L)/1000.0f;//单位mm return distance; }