#include "I2C.h"
#include "bsp.h"
#include "stm32f10x_i2c.h"
u8 I2C_MODE = I2C_HardMode;
u8 I2C_ADDR = I2C_ADDR_DEF;
int SDA_DELAY= 8; //SDA数据保持时间
int SCL_DELAY= 8; //SCL沿变之后,延时SCL_DEALY,SDA再变
int STA_DELAY= 8; //SDA在产生STA时序后,SCL保持STA_DELAY
int STO_DELAY= 8; //SDA在产生STO时序后,SCL保持STA_DELAY
/****************************************************************
* 函数名:I2C_START
* 功能说明:发送Start命令
* 入口参数:N/A
* 出口参数:N/A
****************************************************************/
void I2C_START(void)
{
u16 i;
//I2C_SDA_ON; //SDA = 1
I2C_SCL_ON; //SCL = 1;
for(i=SCL_DELAY;i>0;i--);
I2C_SDA_OFF; //SDA = 0;
for(i=STA_DELAY;i>0;i--);
}
/****************************************************************
* 函数名:I2C_STOP
* ¹功能说明:发送Stop命令
* 入口参数:N/A
* 出口参数:N/A
****************************************************************/
void I2C_STOP(void)
{
u16 i;
I2C_SCL_OFF;
I2C_SDA_OFF;
I2C_SCL_ON;
for(i=SCL_DELAY;i>0;i--);
I2C_SDA_ON;
for(i=STO_DELAY;i>0;i--);
}
/****************************************************************
* 函数名:I2C_SEND_DATA
* 功能说明:I2C发送一个数据
* 入口参数:i2cdata:要发送的数据
* 出口参数:N/A
****************************************************************/
void I2C_SEND_DATA(u8 i2cdata)
{
u16 i;
u16 j;
u8 temp;
for (i = 0; i < 8; i++) // 8 λÊý¾Ý£¬High Bit First£»
{
I2C_SCL_OFF;
for(j= SCL_DELAY;j>0;j--);
temp = i2cdata & 0x80;
if(temp == 0)
I2C_SDA_OFF;
else
I2C_SDA_ON;
i2cdata = i2cdata << 1;
I2C_SCL_ON;
for(j= SDA_DELAY;j>0;j--);
}
I2C_SCL_OFF;
// I2C_SDA_ON; //SDA高,释放总线
}
/****************************************************************
* 函数名:I2C_RECV_ACK
* 功能说明:I2C接收ACK数据
* 入口参数:N/A
* 出口参数:ack:0/1
****************************************************************/
u8 I2C_RECV_ACK(void)
{
u16 i;
u8 ack;
// I2C_SCL_OFF;
// I2C_SDA_ON;
for(i= SCL_DELAY;i>0;i--); //Áô¸øSlaveÏìӦʱ¼ä
I2C_SCL_ON;
for(i= SDA_DELAY;i>0;i--);
ack = Get_SDA_Status;
I2C_SCL_OFF;
I2C_SDA_ON; //SDA¸ß£¬ÊÍ·Å×ÜÏß
return ack;
}
/****************************************************************
* 函数名:I2C_RECV_DATA
* 功能说明:I2C接收数据
* 入口参数:N/A
* 出口参数:i2c_data
****************************************************************/
u8 I2C_RECV_DATA(void)
{
int i,j;
u8 i2cdata=0x00;
u8 dsda;
I2C_SCL_OFF;
// SET_SDA_IN();
//I2C_SDA_ON;
for(i= SCL_DELAY;i>0;i--);
for (i = 7; i >= 0; i--)
{
I2C_SCL_ON;
__nop(); __nop(); __nop(); __nop(); __nop();
i2cdata|=(Get_SDA_Status<<i);
for(j= SDA_DELAY;j>0;j--);
I2C_SCL_OFF;
for(j= SCL_DELAY;j>0;j--);
}
I2C_SDA_ON; //SDA¸ß£¬ÊÍ·Å×ÜÏß
return i2cdata;
}
/****************************************************************
* 函数名:I2C_SEND_ACK
* 功能说明:I2C发送ACK响应
* 入口参数:ack:0/1
* 出口参数:N/A
****************************************************************/
void I2C_SEND_ACK(u8 ack)
{
u16 i;
I2C_SCL_OFF;
if(ack == 0)
I2C_SDA_OFF;
else
I2C_SDA_ON;
for(i= SCL_DELAY;i>0;i--);
I2C_SCL_ON;
for(i= SDA_DELAY;i>0;i--);
I2C_SCL_OFF;
I2C_SDA_ON; //SDA高,释放总线
}
/****************************************************************
* 函数名:I2C_START_HS
* 功能说明:发送Start命令
* 入口参数:N/A
* 出口参数:N/A
****************************************************************/
void I2C_START_HS(void)
{
u16 i;
//I2C_SCL_OFF; //SCL = 0;
//I2C_SDA_ON; //SDA = 1
I2C_SCL_ON; //SCL = 1;
for(i=SCL_DELAY;i>0;i--);
I2C_SDA_OFF; //SDA = 0;
for(i=STA_DELAY;i>0;i--);
}
/****************************************************************
* 函数名:I2C_STOP_HS
* 功能说明:发送Stop命令
* 入口参数:N/A
* 出口参数:N/A
****************************************************************/
void I2C_STOP_HS(void)
{
u16 i;
I2C_SCL_OFF;
I2C_SDA_OFF;
I2C_SCL_ON;
for(i=SCL_DELAY;i>0;i--);
I2C_SDA_ON;
for(i=STO_DELAY;i>0;i--);
}
/****************************************************************
* 函数名:I2C_SEND_DATA_HS
* 功能说明:I2C发送一个数据
* 入口参数:i2cdata:要发送的数据
* 出口参数:N/A
****************************************************************/
void I2C_SEND_DATA_HS(u8 i2cdata)
{
u16 i;
for (i = 0; i < 8; i++) // 8 位数据,High Bit First
{
I2C_SCL_OFF;
if(i2cdata&(0x80>>i))
I2C_SDA_ON;
else
I2C_SDA_OFF;
I2C_SCL_ON;
}
I2C_SCL_OFF;
// I2C_SDA_ON; //SDA高,释放总线
// //´此处是否需要立即将SDA配置才输入?或者直接拉高就可以了?
for (i = 0; i < 2; i++); //just to delay,wait for SDA to Low .yzx
}
/****************************************************************
* 函数名:I2C_RECV_ACK
* 功能说明:I2C接收ACK数据
* 入口参数:N/A
* 出口参数:ack:0/1
****************************************************************/
u8 I2C_RECV_ACK_HS(void)
{
u8 ack;
// I2C_SCL_OFF;
// I2C_SDA_ON;
//SET_SDA_IN();
I2C_SCL_ON;
//__nop();__nop();__nop();__nop();
//__nop();__nop();__nop();__nop();
//__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
ack = Get_SDA_Status;
I2C_SCL_OFF;
I2C_SDA_ON; //SDA高,释放总线
return ack;
}
/****************************************************************
* 函数名:I2C_RECV_DATA_HS
* 功能说明:I2C接收数据
* 入口参数:N/A
* 出口参数:i2c_data
****************************************************************/
u8 I2C_RECV_DATA_HS(void)
{
int i;
u8 i2cdata=0x00;
for (i = 7; i >= 0; i--) // 8 位数据,High Bit First
{
I2C_SCL_OFF;
__nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop();
// for (j = 0; j < 1; j++); //just to delay,wait for SDA to Low .yzx
// SET_SDA_IN();
I2C_SCL_ON;
i2cdata|=(Get_SDA_Status<<i);
}
I2C_SCL_OFF;
I2C_SDA_ON; //SDA高,释放总线
return i2cdata;
}
/****************************************************************
* 函数名:I2C_SEND_ACK_HS
* 功能说明:I2C发送ACK响应
* 入口参数:ack:0/1
* 出口参数:N/A
****************************************************************/
void I2C_SEND_ACK_HS(u8 ack)
{
u16 i;
I2C_SCL_OFF;
if(ack)
I2C_SDA_ON;
else
I2C_SDA_OFF;
for(i= 1;i>0;i--);
I2C_SCL_ON;
for(i= 2;i>0;i--);
I2C_SCL_OFF;
I2C_SDA_ON; //SDA高,释放总线
}
/****************************************************************
* 函数名:I2C_Read_Byte_Soft
* 功能说明:I2C读字节(软件模拟方式)
* 入口参数:N/A
* 出口参数:N/A
****************************************************************/
uint8_t I2C_Read_Byte_Soft(uint8_t SlaveAddress,uint8_t REG_Address)
{
uint8_t REG_data,temp;
if(I2C_MODE == I2C_HSMode)
{
I2C_START();
I2C_SEND_DATA(I2C_MASTERCODE); //MasterCode
if(I2C_RECV_ACK()) //接收,但不判断
{
I2C_STOP();
return 0x10;
}
I2C_START(); //ReStart
I2C_SEND_DATA_HS(SlaveAddress&0xFE); //Addr+W
if(I2C_RECV_ACK_HS())
{
I2C_STOP();
return 0x1;
}
I2C_SEND_DATA_HS(REG_Address&0x7F); //Addr
if(I2C_RECV_ACK_HS())
{
I2C_STOP();
return 0x2;
}
I2C_START();
I2C_SEND_DATA_HS(SlaveAddress|0x01); //Addr+R
if(I2C_RECV_ACK_HS())
{
I2C_STOP();
return 0x3;
}
REG_data = I2C_RECV_DATA_HS();
I2C_SEND_ACK(1); //NACK
I2C_STOP();
}
else
{
I2C_START();
I2C_SEND_DATA(SlaveAddress&0xFE); //Addr+W
if(I2C_RECV_ACK())
{
I2C_STOP();
return 0x1;
}
I2C_SEND_DATA(REG_Address&0x7F); //Addr
if(I2C_RECV_ACK())
{
I2C_STOP();
return 0x2;
}
I2C_START();
I2C_SEND_DATA(SlaveAddress|0x01); //Addr+R
if(I2C_RECV_ACK())
{
I2C_STOP();
return 0x3;
}
REG_data = I2C_RECV_DATA();
I2C_SEND_ACK(1); //NACK
I2C_STOP();
}
return REG_data;
}
/****************************************************************
* 函数名:I2C_Write_Byte_Soft
* 功能说明:I2C写字节(软件模拟方式)
* 入口参数:N/A
* 出口参数:N/A
****************************************************************/
uint8_t I2C_Write_Byte_Soft(uint8_t SlaveAddress,uint8_t REG_Address,uint8_t REG_data)
{
if(I2C_MODE == I2C_HSMode)
{
I2C_START();
I2C_SEND_DATA(I2C_MASTERCODE); //MasterCode
if(I2C_RECV_ACK()) //接收,但不判断
{
I2C_STOP();
return 0x10;
}
I2C_START(); //ReStart
I2C_SEND_DATA_HS(SlaveAddress&0xFE); //Addr+W
if(I2C_RECV_ACK_HS())
{
I2C_STOP();
return 0x1;
}
I2C_SEND_DATA_HS(REG_Address&0x7F); //Addr
if(I2C_RECV_ACK_HS())
{
I2C_STOP();
return 0x2;
}
I2C_SEND_DATA_HS(REG_data); //data
if(I2C_RECV_ACK_HS())
{
I2C_STOP();
return 0x3;
}
I2C_STOP();
}
else
{
I2C_START();
I2C_SEND_DATA(SlaveAddress&0xFE); //Addr+W
if(I2C_RECV_ACK())
{
I2C_STOP();
return 0x1;
}
I2C_SEND_DATA(REG_Address&0x7F); //Addr
if(I2C_RECV_ACK())
{
I2C_STOP();
return 0x2;
}
I2C_SEND_DATA(REG_data); //data
if(I2C_RECV_ACK())
{
I2C_STOP();
return 0x3;
}
I2C_STOP();
}
return 0x00;
}
/****************************************************************
* 函数名:I2C_Cont_Read_Byte_Soft
* 功能说明:I2C连续读字节(软件模拟方式)
* 入口参数:N/A
* 出口参数:N/A
****************************************************************/
uint8_t I2C_Cont_Read_Byte_Soft(uint8_t SlaveAddress,uint8_t REG_Address,int Read_Num,uint8_t* REG_data)
{
uint8_t temp;
int i;
if(I2C_MODE == I2C_HSMode)
{
I2C_START(); //ReStart
I2C_SEND_DATA_HS(SlaveAddress&0xFE); //Addr+W
if(I2C_RECV_ACK_HS())
{
I2C_STOP();
return 0x01;
}
I2C_SEND_DATA_HS(REG_Address&0x7F); //Addr
if(I2C_RECV_ACK_HS())
{
I2C_STOP();
return 0x02;
}
I2C_START();
I2C_SEND_DATA_HS(SlaveAddress|0x01); //Addr+R
if(I2C_RECV_ACK_HS())
{
I2C_STOP();
return 0x03;
}
for(i=0;i<(Read_Num-1);i++)
{
*(REG_data+i)= I2C_RECV_DATA_HS();//读出数据
I2C_SEND_ACK_HS(0); //ACK
}
*(REG_data+i)= I2C_RECV_DATA_HS(); //读出最后一个数据
I2C_SEND_ACK_HS(1); //NACK
I2C_STOP();
}
else
{
I2C_START();
I2C_SEND_DATA(SlaveAddress&0xFE); //Addr+W
if(I2C_RECV_ACK())
{
I2C_STOP();
return 0x01;
}
I2C_SEND_DATA(REG_Address&0x7F); //Addr
if(I2C_RECV_ACK())
{
I2C_STOP();
return 0x02;
}
I2C_START();
I2C_SEND_DATA(SlaveAddress|0x01); //Addr+R
if(I2C_RECV_ACK())
{
I2C_STOP();
return 0x03;
}
for(i=0;i<(Read_Num-1);i++)
{
*(REG_data+i)= I2C_RECV_DATA();//读出数据
I2C_SEND_ACK(0); //ACK
}
*(REG_data+i)= I2C_RECV_DATA(); //读出最后一个数据
I2C_SEND_ACK(1); //NACK
I2C_STOP();
}
return 0x00;
}
/****************************************************************
* 函数名:I2C_Cont_Write_Byte_Soft
* 功能说明:I2C连续写字节(软件模拟方式)
* 入口参数:N/A
* 出口参数:N/A
****************************************************************/
uint8_t I2C_Cont_Write_Byte_Soft(uint8_t SlaveAddress,uint8_t REG_Address,int Write_Num,uint8_t* REG_data)
{
int i;
if(I2C_MODE == I2C_HSMode)
{
I2C_START(); //ReStart
I2C_SEND_DATA_HS(SlaveAddress&0xFE); //Addr+W
if(I2C_RECV_ACK_HS())
{
I2C_STOP();
return 0x01;
}
I2C_SEND_DATA_HS(REG_Address&0x7F); //Addr
if(I2C_RECV_ACK_HS())
{
I2C_STOP();
return 0x02;
}
for(i=0;i<Write_Num;i++)
{
I2C_SEND_DATA_HS(*(REG_data+i)); //data
if(I2C_RECV_ACK_HS())
{
I2C_STOP();
return 0x03;
}
}
I2C_STOP();
}
else
{
I2C_START();
I2C_SEND_DATA(SlaveAddress&0xFE); //Addr+W
if(I2C_RECV_ACK())
{
I2C_STOP();
return 0x01;
}
I2C_SEND_DATA(REG_Address&0x7F); //Addr
if(I2C_RECV_ACK())
{
I2C_STOP();
return 0x02;
}
for(i=0;i<Write_Num;i++)
{
I2C_SEND_DATA(*(REG_data+i)); //data
if(I2C_RECV_ACK())
{
I2C_STOP();
return 0x03;
}
}
I2C_STOP();
}
return 0x00;
}
/****************************************************************
* 函数名:I2C_Config
* 功能说明:I2C配置
* 入口参数:N/A
* 出口参数:N/A
****************************************************************/
void I2C_Config(void)
{
//I2C_Cmd(I2C1, DISABLE);
I2C_InitTypeDef I2C_InitStructure;
I2C_Cmd(I2C2, DISABLE);
I2C_InitStructure.I2C_Mode=I2C_Mode_I2C;
I2C_InitStructure.I2C_OwnAddress1=0x0A;
I2C_InitStructure.I2C_Ack=I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress=I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed=400000;
I2C_InitStructure.I2C_DutyCycle=I2C_DutyCycle_2;
I2C2->CR1 |=0x8000;
I2C2->CR1 &=0x7fff;
I2C_Init(I2C2,&I2C_InitStructure);
I2C_Cmd(I2C2, ENABLE);
I2C_Init(I2C1,&I2C_InitStructure);
I2C_Cmd(I2C1, ENABLE);
}
/****************************************************************
* 函数名:I2C_Read_Byte_Hard
* 功能说明:I2C读字节
* 入口参数:N/A
* 出口参数:N/A
****************************************************************/
uint8_t I2C_Read_Byte_Hard(uint8_t SlaveAddress,uint8_t REG_Address)
{
uint8_t REG_data;
while(I2C_GetFlagStatus(I2C2, I2C_FLAG_BUSY));
I2C_GenerateSTART(I2C2, ENABLE); //起始信号
while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2C2,SlaveAddress,I2C_Direction_Transmitter);//发送设备地址+写信号
while(!I2C_CheckEvent(I2C2,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
I2C_SendData(I2C2,REG_Address); //发送存储单元地址,从0开始
while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_GenerateSTART(I2C2, ENABLE); //起始信号
while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2C2,SlaveAddress,I2C_Direction_Receiver); //发送设备地址+读信号
while(!I2C_CheckEvent(I2C2,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
I2C_AcknowledgeConfig(I2C2, DISABLE);
I2C_GenerateSTOP(I2C2, ENABLE);
while(!(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_RECEIVED)));
REG_data=I2C_ReceiveData(I2C2); //读出寄存器数据
return REG_data;
}
/****************************************************************
* 函数名:I2C_Write_Byte_Hard
* 功能说明:I2C写字节
* 入口参数:N/A
* 出口参数:N/A
****************************************************************/
void I2C_Write_Byte_Hard(uint8_t SlaveAddress,uint8_t REG_Address,uint8_t REG_data)
{
I2C_GenerateSTART(I2C2, ENABLE);
while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2C2,SlaveAddress,I2C_Direction_Transmitter);
while(!I2C_CheckEvent(I2C2,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
I2C_SendData(I2C2, REG_Address);
while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_SendData(I2C2, REG_data);
while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_GenerateSTOP(I2C2, ENABLE);
}
/****************************************************************
* 函数名:I2C_Cont_Read_Byte_Hard
* 功能说明:I2C连续读字节
* 入口参数:N/A
* 出口参数:N/A
****************************************************************/
uint8_t I2C_Cont_Read_Byte_Hard(uint8_t SlaveAddress,uint8_t REG_Address,int Read_Num,uint8_t* REG_data)
{
int i;
while(I2C_GetFlagStatus(I2C2, I2C_FLAG_BUSY));
I2C_GenerateSTART(I2C2, ENABLE); //起始信号
while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2C2,SlaveAddress,I2C_Direction_Transmitter);//发送设备地址+写信号
while(!I2C_CheckEvent(I2C2,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
I2C_SendData(I2C2,REG_Address); //发送存储单元地址,从0开始
while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_GenerateSTART(I2C2, ENABLE); //起始信号
while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2C2,SlaveAddress,I2C_Direction_Receiver); //发送设备地址+读信号
while(!I2C_CheckEvent(I2C2,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
for(i=0;i<(Read_Num-1);i++)
{
I2C_AcknowledgeConfig(I2C2, ENABLE);
I2C_GenerateSTOP(I2C2, DISABLE);
while(!(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_RECEIVED)));
*(REG_data+i)=I2C_ReceiveData(I2C2); //¶读出寄存器数据
}
I2C_AcknowledgeConfig(I2C2, DISABLE);
I2C_GenerateSTOP(I2C2, ENABLE);
while(!(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_RECEIVED)));
*(REG_data+i)=I2C_ReceiveData(I2C2); //读出寄存器数据
return 0x00;
}
/****************************************************************
* 函数名:I2C_Cont_Write_Byte_Hard
* 功能说明:I2C连续写字节
* 入口参数:N/A
* 出口参数:N/A
****************************************************************/
uint8_t I2C_Cont_Write_Byte_Hard(uint8_t SlaveAddress,uint8_t REG_Address,int Write_Num,uint8_t* REG_data)
{
int i;
I2C_GenerateSTART(I2C2, ENABLE);
while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2C2,SlaveAddress,I2C_Direction_Transmitter);
while(!I2C_CheckEvent(I2C2,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
I2C_SendData(I2C2, REG_Address);
while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
for(i=0;i<Write_Num;i++)
{
I2C_SendData(I2C2,*(REG_data+i));
while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
}
I2C_GenerateSTOP(I2C2, ENABLE);
return 0x00;
}
/****************************************************************
* 函数名:I2C_Speed_Ctrl
* 功能说明:I2C速率切换
* 入口参数:I2CSpeed
* 出口参数:返回00表示修改成功,返回EE表示失败
****************************************************************/
u8 I2C_Speed_Ctrl(u8 I2CSpeed)
{
int DelayTemp;
I2C_InitTypeDef I2C_InitStructure;
if(I2CSpeed == 0xFF) //-1默认
{
I2C_MODE = I2C_HardMode;
GPIOPinxConfig(I2C_PORT,I2C_SCL, GPIO_Speed_50MHz, GPIO_Mode_AF_OD);
GPIOPinxConfig(I2C_PORT,I2C_SDA, GPIO_Speed_50MHz, GPIO_Mode_AF_OD);
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); //不需超频
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE); //使能I2C2时钟
I2C_InitStructure.I2C_Mode=I2C_Mode_I2C;
I2C_InitStructure.I2C_OwnAddress1=0x0A;
I2C_InitStructure.I2C_Ack=I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress=I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed=400000;
I2C_InitStructure.I2C_DutyCycle=I2C_DutyCycle_2;
I2C_Init(I2C2,&I2C_InitStructure);
DelayTemp = 8;
}
else if(I2CSpeed == 0xFE) //-2 HS模式 3.4MHz.【注】程序中无法超频,需要在运行之前配置 I2C_MODE = I2C_HSMode,且运行I2C_Speed_Ctrl(-2)
{
I2C_MODE = I2C_HSMode;
GPIOPinxConfig(I2C_PORT,I2C_SCL, GPIO_Speed_50MHz, GPIO_Mode_Out_OD);//软件模拟用
GPIOPinxConfig(I2C_PORT,I2C_SDA, GPIO_Speed_50MHz, GPIO_Mode_Out_OD);
// RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_16); //需超频
DelayTemp = 1;
}
else if(I2CSpeed&0x80) //Ó²¼þ
{
if((I2CSpeed&0x7F)<=40)//´óÓÚ400k
{
I2C_MODE = I2C_HardMode;
GPIOPinxConfig(I2C_PORT,I2C_SCL, GPIO_Speed_50MHz, GPIO_Mode_AF_OD);
GPIOPinxConfig(I2C_PORT,I2C_SDA, GPIO_Speed_50MHz, GPIO_Mode_AF_OD);
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); //不需超频
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE); //使能I2C2时钟
DelayTemp = 8;
I2C_InitStructure.I2C_Mode=I2C_Mode_I2C;
I2C_InitStructure.I2C_OwnAddress1=0x0A;
I2C_InitStructure.I2C_Ack=I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress=I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed=(I2CSpeed&0x7F)*10000;
I2C_InitStructure.I2C_DutyCycle=I2C_DutyCycle_2;
I2C_Init(I2C2,&I2C_InitStructure);
}
else
{
return 0xEE; //切换失败
}
}
else //软件
{
I2C_MODE = I2C_FSMode;
GPIOPinxConfig(I2C_PORT,I2C_SCL, GPIO_Speed_50MHz, GPIO_Mode_Out_OD);//Èí¼þÄ£ÄâÓÃ
GPIOPinxConfig(I2C_PORT,I2C_SDA, GPIO_Speed_50MHz, GPIO_Mode_Out_OD);
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); //²»Ð賬Ƶ
DelayTemp = I2CSpeed;
}
SDA_DELAY= DelayTemp; //SDA数据保持时间
SCL_DELAY= DelayTemp; //SCL沿变之后,延时SCL_DELAY,SDA再变
STA_DELAY= DelayTemp; //SDA在产生STA时序后,SCL保持STA_DELAY
STO_DELAY= DelayTemp; //SDA在产生STO时序后,SCL保持STA_DELAY
return 0x00; //切换成功
}
/****************************************************************
* 函数名:I2C_Slave_Addr_Ctrl
* 功能说明:I2C速率切换(通过改变延时实现)
* 入口参数:I2C_Addr
(1)I2C_Addr==0xFF,硬件实现400kHz (默认)
(2)否则,清除读写位(最低位)后配置
* 出口参数:NA
****************************************************************/
void I2C_Slave_Addr_Ctrl(u8 I2C_Addr)
{
if(I2C_Addr==0x00)
I2C_ADDR = I2C_ADDR_DEF;//00,配置成默认值
else
I2C_ADDR = I2C_Addr&0xFE; //否则,清除读写位(最低位)后配置
}
/****************************************************************
* 函数名:I2C_Cont_Read_Byte
* 功能说明:I2C连续读字节
* 入口参数:N/A
* 出口参数:N/A
****************************************************************/
uint8_t I2C_Cont_Read_Byte(uint8_t SlaveAddress,uint8_t REG_Address,int Read_Num,uint8_t* REG_data)
{
if(I2C_MODE==I2C_HardMode)
{
return I2C_Cont_Read_Byte_Hard(SlaveAddress,REG_Address,Read_Num,REG_data);
}
else
{
return I2C_Cont_Read_Byte_Soft(SlaveAddress,REG_Address,Read_Num,REG_data);
}
}
/****************************************************************
* 函数名:I2C_Cont_Write_Byte
* 功能说明:I2C连续写字节
* 入口参数:N/A
* 出口参数:N/A
****************************************************************/
uint8_t I2C_Cont_Write_Byte(uint8_t SlaveAddress,uint8_t REG_Address,int Write_Num,uint8_t* REG_data)
{
if(I2C_MODE==I2C_HardMode)
{
return I2C_Cont_Write_Byte_Hard(SlaveAddress,REG_Address,Write_Num,REG_data);
}
else
{
return I2C_Cont_Write_Byte_Soft(SlaveAddress,REG_Address,Write_Num,REG_data);
}
}