I2C模拟
* Function Name : I2C_GPIO_Config
* Description : Configration Simulation IIC GPIO
* Input : None
* Output : None
* Return : None
****************************************************************************** */
void I2C_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOB,ENABLE );
GPIO_InitStructure.GPIO_Pin = SCL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_Init(SCL_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = SDA;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_Init(SDA_PORT, &GPIO_InitStructure);
}
/*******************************************************************************
* Function Name : I2C_delay
* Description : Simulation IIC Timing series delay
* Input : None
* Output : None
* Return : None
****************************************************************************** */
void I2C_delay(void)
{
u8 i=30; //这里可以优化速度,经测试最低到5还能写入
while(i)
{
i--;
}
}
/*******************************************************************************
* Function Name : I2C_Start
* Description : Master Start Simulation IIC Communication
* Input : None
* Output : None
* Return : Wheather Start
****************************************************************************** */
bool I2C_Start(void)
{
GPIO_SetBits(SDA_PORT,SDA);
GPIO_SetBits(SCL_PORT,SCL);
I2C_delay();
if(!GPIO_ReadInputDataBit(SDA_PORT, SDA))return FALSE;//SDA线为低电平则总线忙,退出
GPIO_ResetBits(SDA_PORT,SDA);
I2C_delay();
if(GPIO_ReadInputDataBit(SDA_PORT, SDA)) return FALSE;//SDA线为高电平则总线出错,退出
GPIO_ResetBits(SDA_PORT,SDA);
I2C_delay();
return TRUE;
}
/*******************************************************************************
* Function Name : I2C_Stop
* Description : Master Stop Simulation IIC Communication
* Input : None
* Output : None
* Return : None
****************************************************************************** */
void I2C_Stop(void)
{
GPIO_ResetBits(SCL_PORT,SCL);
I2C_delay();
GPIO_ResetBits(SDA_PORT,SDA);
I2C_delay();
GPIO_SetBits(SCL_PORT,SCL);
I2C_delay();
GPIO_SetBits(SDA_PORT,SDA);
I2C_delay();
}
/*******************************************************************************
* Function Name : I2C_Ack
* Description : Master Send Acknowledge Single
* Input : None
* Output : None
* Return : None
****************************************************************************** */
void I2C_Ack(void)
{
GPIO_ResetBits(SCL_PORT,SCL);
I2C_delay();
GPIO_ResetBits(SDA_PORT,SDA);
I2C_delay();
GPIO_SetBits(SCL_PORT,SCL);
I2C_delay();
GPIO_ResetBits(SCL_PORT,SCL);
I2C_delay();
}
/*******************************************************************************
* Function Name : I2C_NoAck
* Description : Master Send No Acknowledge Single
* Input : None
* Output : None
* Return : None
****************************************************************************** */
void I2C_NoAck(void)
{
GPIO_ResetBits(SCL_PORT,SCL);
I2C_delay();
GPIO_SetBits(SDA_PORT,SDA);
I2C_delay();
GPIO_SetBits(SCL_PORT,SCL);
I2C_delay();
GPIO_ResetBits(SCL_PORT,SCL);
I2C_delay();
}
/*******************************************************************************
* Function Name : I2C_WaitAck
* Description : Master Reserive Slave Acknowledge Single
* Input : None
* Output : None
* Return : Wheather Reserive Slave Acknowledge Single
****************************************************************************** */
bool I2C_WaitAck(void) //返回为:=1有ACK,=0无ACK
{
GPIO_ResetBits(SCL_PORT,SCL);
I2C_delay();
GPIO_SetBits(SDA_PORT,SDA);
I2C_delay();
GPIO_SetBits(SCL_PORT,SCL);
I2C_delay();
if(GPIO_ReadInputDataBit(SDA_PORT, SDA))
{
GPIO_ResetBits(SCL_PORT,SCL);
I2C_delay();
return FALSE;
}
GPIO_ResetBits(SCL_PORT,SCL);
I2C_delay();
return TRUE;
}
/*******************************************************************************
* Function Name : I2C_SendByte
* Description : Master Send a Byte to Slave
* Input : Will Send Date
* Output : None
* Return : None
****************************************************************************** */
void I2C_SendByte(u8 SendByte) //数据从高位到低位//
{
u8 i=8;
while(i--)
{
GPIO_ResetBits(SCL_PORT,SCL);
I2C_delay();
if(SendByte&0x80)//测试第1位是否为高电平,并相应改变数据线的值
GPIO_SetBits(SDA_PORT,SDA);
else
GPIO_ResetBits(SDA_PORT,SDA);
SendByte<<=1; //数据左移1位
I2C_delay();
GPIO_SetBits(SCL_PORT,SCL); //每发送完1位,将数据线置高电平
I2C_delay();
}
GPIO_ResetBits(SCL_PORT,SCL);
}
/*******************************************************************************
* Function Name : I2C_ReceiveByte
* Description : Master Reserive a Byte From Slave
* Input : None
* Output : None
* Return : Date From Slave
****************************************************************************** */
unsigned char I2C_ReceiveByte(void) //数据从高位到低位//
{
u8 i=8;
u8 ReceiveByte=0;
GPIO_SetBits(SDA_PORT,SDA);
while(i--)
{
ReceiveByte<<=1;
GPIO_ResetBits(SCL_PORT,SCL); //SCL数据线置0,允许数据线改变
I2C_delay();
GPIO_SetBits(SCL_PORT,SCL); //SCL数据线置1,不允许数据线改变
I2C_delay();
if(GPIO_ReadInputDataBit(SDA_PORT, SDA)) //得到SDA数据线的值,如果为1,则将ReceiveByte最低位置1
{
ReceiveByte|=0x01;
}
}
GPIO_ResetBits(SCL_PORT,SCL);
return ReceiveByte;
}
//ZRX
//单字节写入*******************************************
bool Single_Write(unsigned char SlaveAddress,unsigned char REG_Address,unsigned char REG_data) //void
{u8 i=10;
if(!I2C_Start())return FALSE;
I2C_SendByte(SlaveAddress); //发送设备地址+写信号//I2C_SendByte(((REG_Address & 0x0700) >>7) | SlaveAddress & 0xFFFE);//设置高起始地址+器件地址
if(!I2C_WaitAck()){I2C_Stop(); return FALSE;}
I2C_SendByte(REG_Address ); //设置设备内部起始地址
I2C_WaitAck();
I2C_SendByte(REG_data);
I2C_WaitAck();
I2C_Stop();
while(i--){I2C_delay();}
return TRUE;
}
//单字节读取*****************************************
char Single_Read(unsigned char SlaveAddress,unsigned char REG_Address)
{ unsigned char REG_data;
if(!I2C_Start())return FALSE;
I2C_SendByte(SlaveAddress); //I2C_SendByte(((REG_Address & 0x0700) >>7) | REG_Address & 0xFFFE);//设置高起始地址+器件地址
if(!I2C_WaitAck()){I2C_Stop(); return FALSE;}
I2C_SendByte((u8) REG_Address); //设置低起始地址
I2C_WaitAck();
I2C_Start();
I2C_SendByte(SlaveAddress+1); //设置发送设备地址+读信号也可以用I2C_SendByte(SlaveAddress|0x01);
I2C_WaitAck();
REG_data= I2C_ReceiveByte();
I2C_NoAck();
I2C_Stop();
//return TRUE;
return REG_data;
}
void Init_ADXL345(void)
{
Single_Write(ADXL345_Addr,0x31,0x00); //测量范围,正负2g,10位模式
Single_Write(ADXL345_Addr,0x2C,0x0e); //速率设定为100hz 参考pdf13页
Single_Write(ADXL345_Addr,0x2D,0x08); //选择电源模式 参考pdf24页
Single_Write(ADXL345_Addr,0x2E,0x00); //guanbi DATA_READY 中断
//Single_Write(ADXL345_Addr,0x1E,0x00); //X 偏移量 根据测试传感器的状态写入pdf29页
// Single_Write(ADXL345_Addr,0x1F,0x00); //Y 偏移量 根据测试传感器的状态写入pdf29页
// Single_Write(ADXL345_Addr,0x20,0x05); //Z 偏移量 根据测试传感器的状态写入pdf29页
}
void read_ADXL345(void)
{
char H,L;
u16 tmp;
L=Single_Read(ADXL345_Addr,0x32);//Acc_x_L_A
H=Single_Read(ADXL345_Addr,0x33);//Acc_x_H_A
tmp=(H<<8)+L; //合成数据
Accel_x=(short)tmp;
L=Single_Read(ADXL345_Addr,0x34);//Acc_y_L_A
H=Single_Read(ADXL345_Addr,0x35);//Acc_y_H_A
tmp=(H<<8)+L; //合成数据
Accel_y=(short)tmp;
L=Single_Read(ADXL345_Addr,0x36);//Acc_z_L_A
H=Single_Read(ADXL345_Addr,0x37);//Acc_z_H_A
tmp=(H<<8)+L; //合成数据
Accel_z=(short)tmp;
}