RobotHardware-UESTC/Hardware/RobotSensor/Core/Src/i2c.c

159 lines
2.8 KiB
C
Raw Normal View History

#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;
}