forked from logzhan/RobotHardware-UESTC
159 lines
2.8 KiB
C
159 lines
2.8 KiB
C
|
|
||
|
#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;
|
||
|
}
|