RobotHardware-UESTC/Hardware/银星机器人底盘/PiRobot-YH_Firmware v1.0/STM32/BSPLIB/i2c.c

227 lines
3.8 KiB
C
Raw Normal View History

2024-01-20 13:19:09 +08:00
#ifdef __cplusplus
extern "C" {
#endif
#include "i2c.h"
#include "nvic.h"
static void I2C_delay()
{
volatile int i = 7;
while (i)
i--;
}
static int I2C_Start()
{
SDA_H;
SCL_H;
I2C_delay();
if (!SDA_read)
return 0;
SDA_L;
I2C_delay();
if (SDA_read)
return 0;
SDA_L;
I2C_delay();
return 1;
}
static void I2C_Stop()
{
SCL_L;
I2C_delay();
SDA_L;
I2C_delay();
SCL_H;
I2C_delay();
SDA_H;
I2C_delay();
}
static void I2C_Ack()
{
SCL_L;
I2C_delay();
SDA_L;
I2C_delay();
SCL_H;
I2C_delay();
SCL_L;
I2C_delay();
}
static void I2C_NoAck()
{
SCL_L;
I2C_delay();
SDA_H;
I2C_delay();
SCL_H;
I2C_delay();
SCL_L;
I2C_delay();
}
static int I2C_WaitAck()
{
SCL_L;
I2C_delay();
SDA_H;
I2C_delay();
SCL_H;
I2C_delay();
if (SDA_read) {
SCL_L;
return 0;
}
SCL_L;
return 1;
}
static void I2C_SendByte(uint8_t b)
{
uint8_t i = 8;
while (i--) {
SCL_L;
I2C_delay();
if (b & 0x80)
SDA_H;
else
SDA_L;
b <<= 1;
I2C_delay();
SCL_H;
I2C_delay();
}
SCL_L;
}
static uint8_t I2C_ReadByte()
{
uint8_t i = 8;
uint8_t byte = 0;
SDA_H;
while (i--) {
byte <<= 1;
SCL_L;
I2C_delay();
SCL_H;
I2C_delay();
if (SDA_read) {
byte |= 0x01;
}
}
SCL_L;
return byte;
}
void PB_I2C_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
//已更改
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB , ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
int PB_I2C_Write_Byte(uint8_t addr, uint8_t reg, uint8_t data)
{
if (!I2C_Start())
return 0;
I2C_SendByte(addr << 1 | I2C_Direction_Transmitter);
if (!I2C_WaitAck()) {
I2C_Stop();
return 0;
}
I2C_SendByte(reg);
I2C_WaitAck();
I2C_SendByte(data);
if (!I2C_WaitAck()) {
I2C_Stop();
return 0;
}
I2C_Stop();
return 1;
}
int PB_I2C_Write_Buf(uint8_t addr, uint8_t reg, uint8_t *data , uint8_t size)
{
int i;
if (!I2C_Start())
return 0;
I2C_SendByte(addr << 1 | I2C_Direction_Transmitter);
if (!I2C_WaitAck()) {
I2C_Stop();
return 0;
}
I2C_SendByte(reg);
I2C_WaitAck();
for (i = 0; i < size; i++) {
I2C_SendByte(data[i]);
if (!I2C_WaitAck()) {
I2C_Stop();
return 0;
}
}
I2C_Stop();
return 1;
}
int PB_I2C_Read_Byte(uint8_t addr, uint8_t reg, uint8_t* data)
{
if (!I2C_Start())
return 0;
I2C_SendByte(addr << 1 | I2C_Direction_Transmitter);
if (!I2C_WaitAck()) {
I2C_Stop();
return 0;
}
I2C_SendByte(reg);
I2C_WaitAck();
I2C_Start();
I2C_SendByte(addr << 1 | I2C_Direction_Receiver);
I2C_WaitAck();
*data = I2C_ReadByte();
I2C_NoAck();
I2C_Stop();
return 1;
}
int PB_I2C_Read_Buf(uint8_t addr,uint8_t reg, uint8_t* data , uint8_t size)
{
if (!I2C_Start())
return 0;
I2C_SendByte(addr << 1 | I2C_Direction_Transmitter);
if (!I2C_WaitAck()) {
I2C_Stop();
return 0;
}
I2C_SendByte(reg);
I2C_WaitAck();
I2C_Start();
I2C_SendByte(addr << 1 | I2C_Direction_Receiver);
I2C_WaitAck();
while (size) {
*data = I2C_ReadByte();
if (size == 1)
I2C_NoAck();
else
I2C_Ack();
data++;
size--;
}
I2C_Stop();
return 1;
}
#ifdef __cplusplus
}
#endif