#include "myiic.h"
#include "delay.h"
u8 isBMI160=0, isPMU6050 =0;
void I2C_delay(void)
{
__NOP();
}
//初始化IIC
void IIC_Init(void)
{
RCC->APB2ENR|=1<<3;//先使能外设IO PORTB时钟
GPIOB->CRH&=0XFFFF00FF;//PB1/11 推挽输出
GPIOB->CRH|=0X00003300;
GPIOB->ODR|=3<<10; //PB10,11 输出高
}
//**************************************
//IIC起始信号
//**************************************
u8 IIC_Start(void)
{
#ifdef BMI160
SDA_H;
SCL_H;
I2C_delay();
if(!SDA_read)return FALSE; //SDA线为低电平则总线忙,退出
SDA_L;
I2C_delay();
if(SDA_read) return FALSE; //SDA线为高电平则总线出错,退出
SDA_L;
I2C_delay();
#else
SDA_OUT(); //sda线输出
IIC_SDA=1;
IIC_SCL=1;
Delay_us(I2C_Delayus);
IIC_SDA=0;//START:when CLK is high,DATA change form high to low
Delay_us(I2C_Delayus);
IIC_SCL=0;//钳住IIC总线,准备发送或接收数据
#endif
}
//**************************************
//IIC停止信号
//**************************************
void IIC_Stop(void)
{
#ifdef BMI160
SCL_L;
I2C_delay();
SDA_L;
I2C_delay();
SCL_H;
I2C_delay();
SDA_H;
I2C_delay();
#else
SDA_OUT();//sda线输出
IIC_SCL=0;
IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
Delay_us(I2C_Delayus);
IIC_SCL=1;
IIC_SDA=1;//发送IIC总线结束信号
Delay_us(I2C_Delayus);
#endif
}
/*******************************************************************************
* Function Name : I2C_NoAck
* Description : Master Send No Acknowledge Single
* Input : None
* Output : None
* Return : None
****************************************************************************** */
void I2C_NoAck(void)
{
#ifdef BMI160
SCL_L;
I2C_delay();
SDA_H;
I2C_delay();
SCL_H;
I2C_delay();
SCL_L;
I2C_delay();
#else
IIC_SCL = 0;
I2C_delay();
IIC_SDA = 1;
I2C_delay();
IIC_SCL = 1;
I2C_delay();
IIC_SCL = 0;
I2C_delay();
#endif
}
//**************************************
//IIC发送应答信号
//入口参数:ack (0:ACK 1:NAK)
//**************************************
void IIC_SendACK(void)
{
#ifdef BMI160
SCL_L;
I2C_delay();
SDA_L;
I2C_delay();
SCL_H;
I2C_delay();
SCL_L;
I2C_delay();
#else
IIC_SDA = 1; //写应答信号
IIC_SCL = 1; //拉高时钟线
Delay_us(5); //延时
IIC_SCL = 0; //拉低时钟线
Delay_us(5); //延时
#endif
}
//**************************************
//IIC接收应答信号
//**************************************
u8 IIC_RecvACK(void)
{
#ifdef BMI160
SCL_L;
I2C_delay();
SDA_H;
I2C_delay();
SCL_H;
I2C_delay();
if(SDA_read)
{
SCL_L;
I2C_delay();
return FALSE;
}
SCL_L;
I2C_delay();
return 0;
#else
u8 ucErrTime=0;
SDA_IN(); //SDA设置为输入
IIC_SDA=1;Delay_us(I2C_Delayus);
IIC_SCL=1;Delay_us(I2C_Delayus);
while(READ_SDA)
{
ucErrTime++;
if(ucErrTime>250)
{
IIC_Stop();
return 1;
}
}
IIC_SCL=0;//时钟输出0
return 0;
#endif
}
//**************************************
//向IIC总线发送一个字节数据
//**************************************
void IIC_SendByte(u8 dat)
{
#ifdef BMI160
u8 i=8;
while(i--)
{
SCL_L;
I2C_delay();
if(dat&0x80)
SDA_H;
else
SDA_L;
dat<<=1;
I2C_delay();
SCL_H;
I2C_delay();
}
SCL_L;
#else
u8 t;
SDA_OUT();
IIC_SCL=0;//拉低时钟开始数据传输
for(t=0;t<8;t++)
{
IIC_SDA=(dat&0x80)>>7;
dat<<=1;
Delay_us(I2C_Delayus); //对TEA5767这三个延时都是必须的
IIC_SCL=1;
Delay_us(I2C_Delayus);
IIC_SCL=0;
Delay_us(I2C_Delayus);
}
IIC_RecvACK();
#endif
}
//**************************************
//从IIC总线接收一个字节数据
//**************************************
u8 IIC_RecvByte(void)
{
#ifdef BMI160
u8 i=8;
u8 ReceiveByte=0;
SDA_H;
while(i--)
{
ReceiveByte<<=1;
SCL_L;
I2C_delay();
SCL_H;
I2C_delay();
if(SDA_read)
{
ReceiveByte|=0x01;
}
}
SCL_L;
return ReceiveByte;
#else
unsigned char i,receive=0;
SDA_IN();//SDA设置为输入
for(i=0;i<8;i++ )
{
IIC_SCL=0;
Delay_us(I2C_Delayus);
IIC_SCL=1;
receive<<=1;
if(READ_SDA)receive++;
Delay_us(I2C_Delayus);
}
return receive;
#endif
}
//**************************************
//向IIC设备写入一个字节数据
//**************************************
u8 Single_WriteIIC(u8 REG_Address,u8 REG_data)
{
#ifdef BMI160
if(!IIC_Start())return FALSE;
IIC_SendByte(SlaveAddress); //发送设备地址+写信号//I2C_SendByte(((REG_Address & 0x0700) >>7) | SlaveAddress & 0xFFFE);//设置高起始地址+器件地址
if(!IIC_RecvACK()){IIC_Stop(); return FALSE;}
IIC_SendByte(REG_Address ); //设置低起始地址
IIC_RecvACK();
IIC_SendByte(REG_data);
IIC_RecvACK();
IIC_Stop();
Delay_ms(5);
#else
IIC_Start(); //起始信号
IIC_SendByte(SlaveAddress); //发送设备地址+写信号
IIC_SendByte(REG_Address); //内部寄存器地址,
IIC_SendByte(REG_data); //内部寄存器数据,
IIC_Stop(); //发送停止信号
return 0;
#endif
}
//**************************************
//从IIC设备读取一个字节数据
//**************************************
u8 Single_ReadIIC(u8 REG_Address)
{
#ifdef BMI160
unsigned char REG_data;//i='A';
if(!IIC_Start())
{//UART1_Put_Char(1);
return FALSE;}
IIC_SendByte(SlaveAddress); //I2C_SendByte(((REG_Address & 0x0700) >>7) | REG_Address & 0xFFFE);//设置高起始地址+器件地址
if(!IIC_RecvACK()){IIC_Stop();return FALSE;}
IIC_SendByte((u8) REG_Address); //设置低起始地址
IIC_RecvACK();
IIC_Start();
IIC_SendByte(SlaveAddress+1);
IIC_RecvACK();
REG_data= IIC_RecvByte();
I2C_NoAck();
IIC_Stop();
//return TRUE;
return REG_data;
#else
u8 REG_data;
IIC_Start(); //起始信号
IIC_SendByte(SlaveAddress); //发送设备地址+写信号
IIC_SendByte(REG_Address); //发送存储单元地址,从0开始
IIC_Start(); //起始信号
IIC_SendByte(SlaveAddress+1); //发送设备地址+读信号
REG_data=IIC_RecvByte(); //读出寄存器数据
IIC_SendACK(); //接收应答信号
IIC_Stop(); //停止信号
return REG_data;
#endif
}
/*-------------------------------------------------------------------*
*
* This is a sample code for read and write the data by using I2C/SPI
* Use either I2C or SPI based on your need
* Configure the below code to your SPI or I2C driver
*
*-----------------------------------------------------------------------*/
/* \Brief: The function is used as I2C bus read
* \Return : Status of the I2C read
* \param dev_addr : The device address of the device
* \param reg_addr : Address of the register
* \param reg_data : The value of the register
* \param cnt : The no of data to be read */
s8 i2c_bus_read(u8 dev_addr, u8 reg_addr, u8 *reg_data, u8 cnt)
{
#ifdef BMI160
u8 i;
// 起始信号
IIC_Start();
// 发送设备地址
IIC_SendByte(dev_addr);
IIC_RecvACK();
//发送存储单元地址
IIC_SendByte(reg_addr);
IIC_RecvACK();
// 起始信号
IIC_Start();
//发送设备地址+读信号
IIC_SendByte(dev_addr+1);
IIC_RecvACK();
for (i=0; i<cnt; i++) //连续读取6个地址数据,存储中BUF
{
*(reg_data+i) = IIC_RecvByte(); //BUF[0]存储数据
if (i == cnt-1) I2C_NoAck(); //最后一个数据需要回NOACK
else IIC_SendACK(); //回应ACK
}
IIC_Stop(); //停止信号
I2C_delay();
return 0;
#else
s32 ierror = 0;
u8 st
评论1
最新资源