在移植正点原子mpu6050的工程代码后,初始失败,卡在while(MPU_Init()==1);里面。
当 MPU_Init()返回值为1时,初始化失败,0时成功
Debug进入MPU_Init(),发现程序卡在以下代码
if(res==MPU_ADDR)//器件ID正确
{
MPU_Write_Byte(MPU_PWR_MGMT1_REG,0X01); //设置CLKSEL,PLL X轴为参考
MPU_Write_Byte(MPU_PWR_MGMT2_REG,0X00); //加速度与陀螺仪都工作
MPU_Set_Rate(50); //设置采样率为50Hz
} else return 1;
由于读取的ID 不正确 跳过if 进入else return 1,返回值就为1,初始化失败
打印读取的ID
res=MPU_Read_Byte(MPU_DEVICE_ID_REG);
printf("mpu addr=%x\r\n",res);
打印出来发现不是0x68
//如果AD0脚(9脚)接地,IIC地址为0X68(不包含最低位).
//如果接V3.3,则IIC地址为0X69(不包含最低位).
所以问题就出现在读取ID上
解决方法
1.首先检查接线是否出问题
2.检查IIC
static void IIC_Delay(void)
{
// uint8_t i;
// /*
// 下面的时间是通过安富莱AX-Pro逻辑分析仪测试得到的。
// CPU主频72MHz时,在内部Flash运行, MDK工程不优化
// 循环次数为10时,SCL频率 = 205KHz
// 循环次数为7时,SCL频率 = 347KHz, SCL高电平时间1.5us,SCL低电平时间2.87us
// 循环次数为5时,SCL频率 = 421KHz, SCL高电平时间1.25us,SCL低电平时间2.375us
// IAR工程编译效率高,不能设置为7
// */
// for (i = 0; i < 20; i++);
uint32_t delay = (HAL_RCC_GetHCLKFreq() / 8000000 * 1.5); //使用HAL_RCC_GetHCLKFreq()函数获取主频值,经算法得到1微秒的循环次数
while (delay--); //循环delay次,达到1微秒延时
}
发现我移植的代码它的IIC的延时是以CPU主频72Mhz来写的,而我用的是168Mhz,导致SCL频率过快,重写延时函数后成功解决初始化失败的问题。
将for (i = 0; i < 20; i++);改为
uint32_t delay = (HAL_RCC_GetHCLKFreq() / 8000000 * 1.5); //使用HAL_RCC_ GetHCLKFreq()函数获取主频值,经算法得到1微秒的循环次数
while (delay--); //循环delay次,达到1微秒延时
这是一个以消耗mcu运行时间的us级延时函数 ,延时为1.5us,可将1.5改为其他数值,在不同场景中使用。