GeBalanceBot/4.WHEELTEC B570 平衡小车源码(库函数精.../MiniBalance_HARDWARE/IIC/IOI2C.c

442 lines
14 KiB
C
Raw Normal View History

2024-01-14 19:28:00 +08:00
/***********************************************
WHEELTEC
wheeltec.net
shop114407458.taobao.com
: https://minibalance.aliexpress.com/store/4455017
5.7
2021-04-29
Brand: WHEELTEC
Website: wheeltec.net
Taobao shop: shop114407458.taobao.com
Aliexpress: https://minibalance.aliexpress.com/store/4455017
Version:5.7
Update2021-04-29
All rights reserved
***********************************************/
#include "ioi2c.h"
#include "sys.h"
#include "delay.h"
/**************************************************************************
Function: IIC pin initialization
Input : none
Output : none
IIC
**************************************************************************/
void IIC_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // 使能PB端口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9; // 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 50M
GPIO_Init(GPIOB, &GPIO_InitStructure); // 根据设定参数初始化GPIOB
}
/**************************************************************************
Function: Simulate IIC start signal
Input : none
Output : 1
IIC
1
**************************************************************************/
int IIC_Start(void)
{
SDA_OUT(); // sda线输出
IIC_SDA = 1;
if (!READ_SDA)
return 0;
IIC_SCL = 1;
delay_us(1);
IIC_SDA = 0; // START:when CLK is high,DATA change form high to low
if (READ_SDA)
return 0;
delay_us(1);
IIC_SCL = 0; // 钳住I2C总线准备发送或接收数据
return 1;
}
/**************************************************************************
Function: Analog IIC end signal
Input : none
Output : none
IIC
**************************************************************************/
void IIC_Stop(void)
{
SDA_OUT(); // sda线输出
IIC_SCL = 0;
IIC_SDA = 0; // STOP:when CLK is high DATA change form low to high
delay_us(1);
IIC_SCL = 1;
IIC_SDA = 1; // 发送I2C总线结束信号
delay_us(1);
}
/**************************************************************************
Function: IIC wait the response signal
Input : none
Output : 0No response received1Response received
IIC
01
**************************************************************************/
int IIC_Wait_Ack(void)
{
u8 ucErrTime = 0;
SDA_IN(); // SDA设置为输入
IIC_SDA = 1;
delay_us(1);
IIC_SCL = 1;
delay_us(1);
while (READ_SDA)
{
ucErrTime++;
if (ucErrTime > 50)
{
IIC_Stop();
return 0;
}
delay_us(1);
}
IIC_SCL = 0; // 时钟输出0
return 1;
}
/**************************************************************************
Function: IIC response
Input : none
Output : none
IIC
**************************************************************************/
void IIC_Ack(void)
{
IIC_SCL = 0;
SDA_OUT();
IIC_SDA = 0;
delay_us(1);
IIC_SCL = 1;
delay_us(1);
IIC_SCL = 0;
}
/**************************************************************************
Function: IIC don't reply
Input : none
Output : none
IIC
**************************************************************************/
void IIC_NAck(void)
{
IIC_SCL = 0;
SDA_OUT();
IIC_SDA = 1;
delay_us(1);
IIC_SCL = 1;
delay_us(1);
IIC_SCL = 0;
}
/**************************************************************************
Function: IIC sends a byte
Input : txdByte data sent
Output : none
IIC
txd
**************************************************************************/
void IIC_Send_Byte(u8 txd)
{
u8 t;
SDA_OUT();
IIC_SCL = 0; // 拉低时钟开始数据传输
for (t = 0; t < 8; t++)
{
IIC_SDA = (txd & 0x80) >> 7;
txd <<= 1;
delay_us(1);
IIC_SCL = 1;
delay_us(1);
IIC_SCL = 0;
delay_us(1);
}
}
/**************************************************************************
Function: IIC write data to register
Input : addrDevice addressregRegister addresslen;Number of bytesdataData
Output : 0Write successfully1Failed to write
IIC
addrreglen;data
01
**************************************************************************/
int i2cWrite(uint8_t addr, uint8_t reg, uint8_t len, uint8_t *data)
{
int i;
if (!IIC_Start())
return 1;
IIC_Send_Byte(addr << 1);
if (!IIC_Wait_Ack())
{
IIC_Stop();
return 1;
}
IIC_Send_Byte(reg);
IIC_Wait_Ack();
for (i = 0; i < len; i++)
{
IIC_Send_Byte(data[i]);
if (!IIC_Wait_Ack())
{
IIC_Stop();
return 0;
}
}
IIC_Stop();
return 0;
}
/**************************************************************************
Function: IIC read register data
Input : addrDevice addressregRegister addresslen;Number of bytes*bufData read out
Output : 0Read successfully1Failed to read
IIC
addrreglen;*buf
01
**************************************************************************/
int i2cRead(uint8_t addr, uint8_t reg, uint8_t len, uint8_t *buf)
{
if (!IIC_Start())
return 1;
IIC_Send_Byte(addr << 1);
if (!IIC_Wait_Ack())
{
IIC_Stop();
return 1;
}
IIC_Send_Byte(reg);
IIC_Wait_Ack();
IIC_Start();
IIC_Send_Byte((addr << 1) + 1);
IIC_Wait_Ack();
while (len)
{
if (len == 1)
*buf = IIC_Read_Byte(0);
else
*buf = IIC_Read_Byte(1);
buf++;
len--;
}
IIC_Stop();
return 0;
}
/**************************************************************************
Function: IIC reads a byte
Input : ackSend response signal or not1Send0Do not send
Output : receiveData read
IIC
ack10
receive
**************************************************************************/
u8 IIC_Read_Byte(unsigned char ack)
{
unsigned char i, receive = 0;
SDA_IN(); // SDA设置为输入
for (i = 0; i < 8; i++)
{
IIC_SCL = 0;
delay_us(2);
IIC_SCL = 1;
receive <<= 1;
if (READ_SDA)
receive++;
delay_us(2);
}
if (ack)
IIC_Ack(); // 发送ACK
else
IIC_NAck(); // 发送nACK
return receive;
}
/**************************************************************************
Function: IIC reads a byte
Input : I2C_AddrDevice IIC addressaddr:Register address
Output : resData read
I2C_AddrIICaddr:
res
**************************************************************************/
unsigned char I2C_ReadOneByte(unsigned char I2C_Addr, unsigned char addr)
{
unsigned char res = 0;
IIC_Start();
IIC_Send_Byte(I2C_Addr); // 发送写命令
res++;
IIC_Wait_Ack();
IIC_Send_Byte(addr);
res++; // 发送地址
IIC_Wait_Ack();
// IIC_Stop();//产生一个停止条件
IIC_Start();
IIC_Send_Byte(I2C_Addr + 1);
res++; // 进入接收模式
IIC_Wait_Ack();
res = IIC_Read_Byte(0);
IIC_Stop(); // 产生一个停止条件
return res;
}
/**************************************************************************
Function: IIC continuous reading data
Input : devTarget device IIC addressreg:Register address
lengthNumber of bytes*data:The pointer where the read data will be stored
Output : countNumber of bytes read out-1
IIC
devIICreg:length
*data:
count-1
**************************************************************************/
u8 IICreadBytes(u8 dev, u8 reg, u8 length, u8 *data)
{
u8 count = 0;
IIC_Start();
IIC_Send_Byte(dev); // 发送写命令
IIC_Wait_Ack();
IIC_Send_Byte(reg); // 发送地址
IIC_Wait_Ack();
IIC_Start();
IIC_Send_Byte(dev + 1); // 进入接收模式
IIC_Wait_Ack();
for (count = 0; count < length; count++)
{
if (count != length - 1)
data[count] = IIC_Read_Byte(1); // 带ACK的读数据
else
data[count] = IIC_Read_Byte(0); // 最后一个字节NACK
}
IIC_Stop(); // 产生一个停止条件
return count;
}
/**************************************************************************
Function: Writes multiple bytes to the specified register of the specified device
Input : devTarget device IIC addressregRegister addresslengthNumber of bytes
*dataThe pointer where the read data will be stored
Output : 1
devreglength
*data
1
**************************************************************************/
u8 IICwriteBytes(u8 dev, u8 reg, u8 length, u8 *data)
{
u8 count = 0;
IIC_Start();
IIC_Send_Byte(dev); // 发送写命令
IIC_Wait_Ack();
IIC_Send_Byte(reg); // 发送地址
IIC_Wait_Ack();
for (count = 0; count < length; count++)
{
IIC_Send_Byte(data[count]);
IIC_Wait_Ack();
}
IIC_Stop(); // 产生一个停止条件
return 1; // status == 0;
}
/**************************************************************************
Function: Reads a byte of the specified register of the specified device
Input : devTarget device IIC addressregRegister address*dataThe pointer where the read data will be stored
Output : 1
devreg*data
1
**************************************************************************/
u8 IICreadByte(u8 dev, u8 reg, u8 *data)
{
*data = I2C_ReadOneByte(dev, reg);
return 1;
}
/**************************************************************************
Function: Write a byte to the specified register of the specified device
Input : devTarget device IIC addressregRegister addressdataData to be writtenwill be stored
Output : 1
devregdata
1
**************************************************************************/
unsigned char IICwriteByte(unsigned char dev, unsigned char reg, unsigned char data)
{
return IICwriteBytes(dev, reg, 1, &data);
}
/**************************************************************************
Function: Read, modify, and write multiple bits in a byte of the specified device specified register
Input : devTarget device IIC addressregRegister addresslengthNumber of bytes
bitStartStart bit of target bytedataStores the value of the target byte bit to be changed
Output : 1success0fail
devregbitStart
data
10
**************************************************************************/
u8 IICwriteBits(u8 dev, u8 reg, u8 bitStart, u8 length, u8 data)
{
u8 b;
if (IICreadByte(dev, reg, &b) != 0)
{
u8 mask = (0xFF << (bitStart + 1)) | 0xFF >> ((8 - bitStart) + length - 1);
data <<= (8 - length);
data >>= (7 - bitStart);
b &= mask;
b |= data;
return IICwriteByte(dev, reg, b);
}
else
{
return 0;
}
}
/**************************************************************************
Function: Read, modify, and write one bit in a byte of the specified device specified register
Input : devTarget device IIC addressregRegister address
bitNumTo modify the bitnum bit of the target bytedataWhen it is 0, the target bit will be cleared, otherwise it will be set
Output : 1success0fail
1
devregbitNumbitNum
data0
10
**************************************************************************/
u8 IICwriteBit(u8 dev, u8 reg, u8 bitNum, u8 data)
{
u8 b;
IICreadByte(dev, reg, &b);
b = (data != 0) ? (b | (1 << bitNum)) : (b & ~(1 << bitNum));
return IICwriteByte(dev, reg, b);
}