STM32 驱动MPU6050,模拟IIC读写24C02没问题,但是读MPU6050数据时返回总是257,,调试了两天了,还是一个样子,MPU没有坏,在51单片机上可以使用
但是到了STM32就不行了,模拟的那两个GPIO口没有连接其他器件,只有MPU6050,我是对照着那个可以使用的51的程序修改成STM32的,读MPU6050还是不可以,读写24C02就可以
void IIC_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOA,ENABLE);
// RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE); //失能I2C1时钟
// RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable,ENABLE); //失能SWJ引脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//这里设置成推挽输出,开漏模式的也尝试过还是不行
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure); //GPIOB6,7推挽输出
GPIO_SetBits(GPIOA,GPIO_Pin_5 | GPIO_Pin_7); //上拉
}
//**************************************
//I2C起始信号
//**************************************
void IIC_Start(void)
{
SDA_GPIO_OUT();
SDA_SET; //拉高数据线
SCL_SET; //拉高时钟线
delay_us(6); //延时
SDA_CLR; //产生下降沿
delay_us(6); //延时
SCL_CLR; //拉低时钟线
}
//**************************************
//I2C停止信号
//**************************************
void IIC_Stop(void)
{
SDA_GPIO_OUT();
SDA_CLR; //拉低数据线
SCL_CLR; //拉高时钟线
delay_us(6);
SCL_CLR; //延时
SDA_SET; //产生上升沿
delay_us(6); //延时
}
//**************************************
//I2C发送应答信号
//入口参数:NAK)
//**************************************
void IIC_NAck(void)
{
SDA_GPIO_OUT();
SDA_SET; //写应答信号
SCL_SET; //拉高时钟线
delay_us(6); //延时
SCL_CLR; //拉低时钟线
delay_us(6); //延时
}
/***发送应答信号**/
void IIC_ACK(void)
{
SDA_GPIO_OUT();
SDA_CLR;
SCL_SET; //拉高时钟线
delay_us(6); //延时
SCL_CLR; //拉低时钟线
delay_us(6); //延时
}
//**************************************
//I2C接收应答信号
//**************************************
u8 IIC_Wait_Ack(void)
{
u8 dat;
SDA_GPIO_IN(); //设置为输入
SCL_SET; //拉高时钟线
delay_us(6); //延时
if(READ_SDA)
dat=1;
else
dat=0; //读应答信号
SCL_CLR; //拉低时钟线
delay_us(6); //延时
return dat;
}
//**************************************
//向I2C总线发送一个字节数据
//**************************************
void IIC_Write_Byte(u8 Byte)
{
u8 i;
SDA_GPIO_OUT();
for (i=0; i<8; i++) //8位计数器
{
if(Byte&0x80)
SDA_SET;
else
SDA_CLR;
SCL_SET; //拉高时钟线
delay_us(6); //延时
SCL_CLR; //拉低时钟线
delay_us(6); //延时
Byte<<=1; //移出数据的最高位
}
IIC_Wait_Ack(); //接收应答信号
}
//**************************************
//从I2C总线接收一个字节数据
//**************************************
u8 IIC_Read_Byte(void)
{
u8 i;
u8 dat = 0;
SDA_GPIO_IN();
SDA_SET; //使能内部上拉,准备读取数据,
for (i=0; i<8; i++) //8位计数器
{
dat <<= 1;
SCL_SET; //拉高时钟线
delay_us(6); //延时
dat |= READ_SDA; //读数据
SCL_CLR; //拉低时钟线
delay_us(6); //延时
}
return dat;
}
void Single_WriteI2C(u8 REG_Address,u8 REG_data)
{
IIC_Start(); //起始信号
IIC_Write_Byte(SlaveAddress); //发送设备地址+写信号
IIC_Wait_Ack(); //等待应答信号
IIC_Write_Byte(REG_Address); //内部寄存器地址
IIC_Wait_Ack();
IIC_Write_Byte(REG_data); //内部寄存器数据
IIC_Wait_Ack();
IIC_Stop(); //发送停止信号
delay_ms(1);
}
//**************************************
//从I2C设备读取一个字节数据
//**************************************
u8 Single_ReadI2C(u8 REG_Address)
{
u8 REG_data;
IIC_Start();
IIC_Write_Byte(SlaveAddress); //AT24Cxx写命令,AT24CXX地址
IIC_Wait_Ack();
IIC_Write_Byte(REG_Address);
IIC_Wait_Ack();
IIC_Start();
IIC_Write_Byte(SlaveAddress+1); //AT24Cxx读命令,AT24CXX地址
IIC_Wait_Ack();
REG_data=IIC_Read_Byte();
IIC_NAck();
IIC_Stop();
return REG_data;
}
//**************************************
//初始化MPU6050
//**************************************
void InitMPU6050(void)
{
Single_WriteI2C(PWR_MGMT_1,0x00); //解除休眠状态
delay_ms(100);
Single_WriteI2C(GYRO_CONFIG,0x18); //陀螺仪不自检,配置陀螺仪满量程正负2000°/S
delay_ms(50);
Single_WriteI2C(ACCEL_CONFIG,0x01);//加速度计不自检,配置加速度计满量程2g
delay_ms(50);
Single_WriteI2C(SMPLRT_DIV,0x07); //采样频率分频器
delay_ms(50);
Single_WriteI2C(CONFIG,0x06); //低通滤波频率
delay_ms(50);
}
|