442 lines
14 KiB
C
442 lines
14 KiB
C
|
/***********************************************
|
|||
|
公司:轮趣科技(东莞)有限公司
|
|||
|
品牌: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
|
|||
|
Update:2021-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 : 0:No response received;1:Response received
|
|||
|
函数功能:IIC等待应答信号
|
|||
|
入口参数:无
|
|||
|
返回 值:0:没有收到应答;1:收到应答
|
|||
|
**************************************************************************/
|
|||
|
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 : txd:Byte 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 : addr:Device address;reg:Register address;len;Number of bytes;data:Data
|
|||
|
Output : 0:Write successfully;1:Failed to write
|
|||
|
函数功能:IIC写数据到寄存器
|
|||
|
入口参数:addr:设备地址;reg:寄存器地址;len;字节数;data:数据
|
|||
|
返回 值:0:成功写入;1:没有成功写入
|
|||
|
**************************************************************************/
|
|||
|
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 : addr:Device address;reg:Register address;len;Number of bytes;*buf:Data read out
|
|||
|
Output : 0:Read successfully;1:Failed to read
|
|||
|
函数功能:IIC读寄存器的数据
|
|||
|
入口参数:addr:设备地址;reg:寄存器地址;len;字节数;*buf:读出数据缓存
|
|||
|
返回 值:0:成功读出;1:没有成功读出
|
|||
|
**************************************************************************/
|
|||
|
|
|||
|
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 : ack:Send response signal or not;1:Send;0:Do not send
|
|||
|
Output : receive:Data read
|
|||
|
函数功能:IIC读取一个位
|
|||
|
入口参数:ack:是否发送应答信号;1:发送;0:不发送
|
|||
|
返回 值: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_Addr:Device IIC address;addr:Register address
|
|||
|
Output : res:Data read
|
|||
|
函数功能:读取指定设备指定寄存器的一个值
|
|||
|
入口参数:I2C_Addr:设备IIC地址;addr:寄存器地址
|
|||
|
返回 值: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 : dev:Target device IIC address;reg:Register address;
|
|||
|
length:Number of bytes;*data:The pointer where the read data will be stored
|
|||
|
Output : count:Number of bytes read out-1
|
|||
|
函数功能:IIC连续读数据
|
|||
|
入口参数:dev:目标设备IIC地址;reg:寄存器地址;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 : dev:Target device IIC address;reg:Register address;length:Number of bytes;
|
|||
|
*data:The pointer where the read data will be stored
|
|||
|
Output : 1
|
|||
|
函数功能:将多个字节写入指定设备指定寄存器
|
|||
|
入口参数:dev:目标设备地址;reg:寄存器地址;length:要写的字节数;
|
|||
|
*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 : dev:Target device IIC address;reg:Register address;*data:The pointer where the read data will be stored
|
|||
|
Output : 1
|
|||
|
函数功能:读取指定设备指定寄存器的一个值
|
|||
|
入口参数:dev:目标设备地址;reg:寄存器地址;*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 : dev:Target device IIC address;reg:Register address;data:Data to be writtenwill be stored
|
|||
|
Output : 1
|
|||
|
函数功能:写入指定设备指定寄存器一个字节
|
|||
|
入口参数:dev:目标设备地址;reg:寄存器地址;data:将要写的数据
|
|||
|
返回 值: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 : dev:Target device IIC address;reg:Register address;length:Number of bytes;
|
|||
|
bitStart:Start bit of target byte;data:Stores the value of the target byte bit to be changed
|
|||
|
Output : 1:success;0:fail
|
|||
|
函数功能:读 修改 写 指定设备 指定寄存器一个字节 中的多个位
|
|||
|
入口参数:dev:目标设备地址;reg:寄存器地址;bitStart:目标字节的起始位;
|
|||
|
data:存放改变目标字节位的值
|
|||
|
返回 值:1:成功;0:失败
|
|||
|
**************************************************************************/
|
|||
|
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 : dev:Target device IIC address;reg:Register address;
|
|||
|
bitNum:To modify the bitnum bit of the target byte;data:When it is 0, the target bit will be cleared, otherwise it will be set
|
|||
|
Output : 1:success;0:fail
|
|||
|
函数功能:读 修改 写 指定设备 指定寄存器一个字节 中的1个位
|
|||
|
入口参数:dev:目标设备地址;reg:寄存器地址;bitNum:要修改目标字节的bitNum位;
|
|||
|
data:为0时,目标位将被清,否则将被置位
|
|||
|
返回 值:1:成功;0:失败
|
|||
|
**************************************************************************/
|
|||
|
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);
|
|||
|
}
|