一、管脚初始化
由于STM32的硬件初始化比较复杂,这里我们采用软件初始化,选用端口PB6,PB7,以匿名的I2C初始化程序为例
/***************I2C GPIO定义******************/
#define ANO_GPIO_I2C GPIOB
#define I2C_Pin_SCL GPIO_Pin_6
#define I2C_Pin_SDA GPIO_Pin_7
#define ANO_RCC_I2C RCC_APB2Periph_GPIOB
/*********************************************/
#define SCL_H ANO_GPIO_I2C->BSRR = I2C_Pin_SCL
#define SCL_L ANO_GPIO_I2C->BRR = I2C_Pin_SCL
#define SDA_H ANO_GPIO_I2C->BSRR = I2C_Pin_SDA
#define SDA_L ANO_GPIO_I2C->BRR = I2C_Pin_SDA
#define SCL_read ANO_GPIO_I2C->IDR & I2C_Pin_SCL
#define SDA_read ANO_GPIO_I2C->IDR & I2C_Pin_SDA
void I2c_Soft_delay()
{
__NOP();
__NOP();
__NOP();
__NOP();
}
void I2c_Soft_Init()
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(ANO_RCC_I2C , ENABLE );
GPIO_InitStructure.GPIO_Pin = I2C_Pin_SCL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_Init(ANO_GPIO_I2C, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = I2C_Pin_SDA;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_Init(ANO_GPIO_I2C, &GPIO_InitStructure);
}
//以下是驱动MPU6050所需要的
int I2c_Soft_Start()
{
SDA_H;
SCL_H;
I2c_Soft_delay();
if(!SDA_read)return 0; //SDA线为低电平则总线忙,退出
SDA_L;
I2c_Soft_delay();
if(SDA_read) return 0; //SDA线为高电平则总线出错,退出
SDA_L;
I2c_Soft_delay();
return 1;
}
void I2c_Soft_Stop()
{
SCL_L;
I2c_Soft_delay();
SDA_L;
I2c_Soft_delay();
SCL_H;
I2c_Soft_delay();
SDA_H;
I2c_Soft_delay();
}
void I2c_Soft_Ask()
{
SCL_L;
I2c_Soft_delay();
SDA_L;
I2c_Soft_delay();
SCL_H;
I2c_Soft_delay();
SCL_L;
I2c_Soft_delay();
}
void I2c_Soft_NoAsk()
{
SCL_L;
I2c_Soft_delay();
SDA_H;
I2c_Soft_delay();
SCL_H;
I2c_Soft_delay();
SCL_L;
I2c_Soft_delay();
}
int I2c_Soft_WaitAsk(void) //返回为:=1有ASK,=0无ASK
{
u8 ErrTime = 0;
SCL_L;
I2c_Soft_delay();
SDA_H;
I2c_Soft_delay();
SCL_H;
I2c_Soft_delay();
if(SDA_read)
{
ErrTime++;
if(ErrTime>200)
{
I2c_Soft_Stop();
return 1;
}
}
SCL_L;
I2c_Soft_delay();
return 0;
}
void I2c_Soft_SendByte(u8 SendByte) //数据从高位到低位//
{
u8 i=8;
while(i--)
{
SCL_L;
I2c_Soft_delay();
if(SendByte&0x80)
SDA_H;
else
SDA_L;
SendByte<<=1;
I2c_Soft_delay();
SCL_H;
I2c_Soft_delay();
}
SCL_L;
}
//读1个字节,ack=1时,发送ACK,ack=0,发送nACK
u8 I2c_Soft_ReadByte(u8 ask) //数据从高位到低位//
{
u8 i=8;
u8 ReceiveByte=0;
SDA_H;
while(i--)
{
ReceiveByte<<=1;
SCL_L;
I2c_Soft_delay();
SCL_H;
I2c_Soft_delay();
if(SDA_read)
{
ReceiveByte|=0x01;
}
}
SCL_L;
if (ask)
I2c_Soft_Ask();
else
I2c_Soft_NoAsk();
return ReceiveByte;
}
// IIC写一个字节数据
u8 IIC_Write_1Byte(u8 SlaveAddress,u8 REG_Address,u8 REG_data)
{
I2c_Soft_Start();
I2c_Soft_SendByte(SlaveAddress<<1);
if(I2c_Soft_WaitAsk())
{
I2c_Soft_Stop();
return 1;
}
I2c_Soft_SendByte(REG_Address);
I2c_Soft_WaitAsk();
I2c_Soft_SendByte(REG_data);
I2c_Soft_WaitAsk();
I2c_Soft_Stop();
return 0;
}
// IIC读1字节数据
u8 IIC_Read_1Byte(u8 SlaveAddress,u8 REG_Address,u8 *REG_data)
{
I2c_Soft_Start();
I2c_Soft_SendByte(SlaveAddress<<1);
if(I2c_Soft_WaitAsk())
{
I2c_Soft_Stop();
return 1;
}
I2c_Soft_SendByte(REG_Address);
I2c_Soft_WaitAsk();
I2c_Soft_Start();
I2c_Soft_SendByte(SlaveAddress<<1 | 0x01);
I2c_Soft_WaitAsk();
*REG_data= I2c_Soft_ReadByte(0);
I2c_Soft_Stop();
return 0;
}
// IIC写n字节数据
u8 IIC_Write_nByte(u8 SlaveAddress, u8 REG_Address, u8 len, u8 *buf)
{
I2c_Soft_Start();
I2c_Soft_SendByte(SlaveAddress<<1);
if(I2c_Soft_WaitAsk())
{
I2c_Soft_Stop();
return 1;
}
I2c_Soft_SendByte(REG_Address);
I2c_Soft_WaitAsk();
while(len--)
{
I2c_Soft_SendByte(*buf++);
I2c_Soft_WaitAsk();
}
I2c_Soft_Stop();
return 0;
}
u8 mpu_test;
// IIC读n字节数据
u8 IIC_Read_nByte(u8 SlaveAddress, u8 REG_Address, u8 len, u8 *buf)
{
mpu_test = I2c_Soft_Start();
I2c_Soft_SendByte(SlaveAddress<<1);
if(I2c_Soft_WaitAsk())
{
I2c_Soft_Stop();
return 1;
}
I2c_Soft_SendByte(REG_Address);
I2c_Soft_WaitAsk();
I2c_Soft_Start();
I2c_Soft_SendByte(SlaveAddress<<1 | 0x01);
I2c_Soft_WaitAsk();
while(len)
{
if(len == 1)
{
*buf = I2c_Soft_ReadByte(0);
}
else
{
*buf = I2c_Soft_ReadByte(1);
}
buf++;
len--;
}
I2c_Soft_Stop();
return 0;
}