移直MPU9250,在程序执行到res=dmp_load_motion_driver_firmware(); //加载dmp固件
程序出现错误;当单步执行后,将问题定位到下面语句
for (ii = 0; ii < length; ii += this_write) {
this_write = min(LOAD_CHUNK, length - ii);
if (mpu_write_mem(ii, this_write, (unsigned char*)&firmware[ii]))
return -1;
firmware[ii];
if (mpu_read_mem(ii, this_write, cur))
return -1;
if (memcmp(firmware+ii, cur, this_write)) //
return -2;
解决过程,搜了大量的资料,将问题的关键定位到MPU9250IIC的连续写和连续读的驱动程序上,并且延时函数直接使用cpu延时而不使用定时器中断延时,通过多方的寻找,使用了野火的相应读写驱动,解决了该问题,将代码贴下来
(1条消息) MPU9250,DMP、IIC驱动资源-CSDN文库
点击上面链接直接下载
cpu延时函数
//粗延时函数,微秒
void delay_us(u32 nus)
{
u16 i=0;
while(nus--)
{
i=1; //自己定义
while(i--) ;
}
}
//毫秒级的延时
void delay_ms(u16 nms)
{
u16 i=0;
while(nms--)
{
i=12000; //自己定义
while(i--) ;
}
}
1、移植时先更改 头文件中的宏定义
inv_mpu.c文件下,第55行
#define i2c_write Sensors_I2C_WriteRegister
#define i2c_read Sensors_I2C_ReadRegister
#define delay_ms delay_ms
#define get_ms mget_ms
2、增加 int Sensors_I2C_WriteRegister(unsigned char slave_addr,unsigned char reg_addr,unsigned short len,const unsigned char *data_ptr)函数
/**
* @func Sensors_I2C_WriteRegister
* @brief 向I2C设备的寄存器连续写入数据,带超时重试设置,为Motion Driver提供接口
* @param
@arg slave_addr : I2C设备地址
@arg reg_addr : 寄存器地址
@arg len : 要写入数据的长度
@arg data_ptr : 指向要写入数据的指针
* @retval 0:正常,非0:异常
**/
int Sensors_I2C_WriteRegister(unsigned char slave_addr,unsigned char reg_addr,unsigned short len,const unsigned char *data_ptr)
{
char retries=0;
int ret = 0;
unsigned short retry_in_mlsec = Get_I2C_Retry();
tryWriteAgain:
ret = 0;
ret = SI2C_WriteReg( slave_addr, reg_addr, len, ( unsigned char *)data_ptr);
if(ret && retry_in_mlsec)
{
if( retries++ > 4 )
return ret;
mdelay(retry_in_mlsec);
goto tryWriteAgain;
}
return ret;
}
3、增加 int Sensors_I2C_ReadRegister(unsigned char slave_addr,unsigned char reg_addr,unsigned short len, unsigned char *data_ptr) 函数
/**
* @func Sensors_I2C_ReadRegister
* @brief 向I2C设备的寄存器连续读出数据,带超时重试设置,为Motion Driver提供接口
* @param
@arg slave_addr : I2C设备地址
@arg reg_addr : 寄存器地址
@arg len : 要读取数据的长度
@arg data_ptr : 指向存储读出数据的指针
* @retval 0:正常,非0:异常
**/
int Sensors_I2C_ReadRegister(unsigned char slave_addr,unsigned char reg_addr,unsigned short len, unsigned char *data_ptr)
{
char retries=0;
int ret = 0;
unsigned short retry_in_mlsec = Get_I2C_Retry();
tryReadAgain:
ret = 0;
ret = SI2C_ReadReg( slave_addr, reg_addr, len, ( unsigned char *)data_ptr);
if(ret && retry_in_mlsec)
{
if( retries++ > 4 )
return ret;
mdelay(retry_in_mlsec);
goto tryReadAgain;
}
return ret;
}
4、增加 static uint8_t SI2C_WriteReg(uint8_t dev_addr, uint8_t reg_addr, uint8_t reg_len,unsigned char *reg_data)函数
/**
* @func SI2C_WriteReg
* @brief 写寄存器
* @param
@arg dev_addr : 设备地址
@arg reg_addr : 寄存器地址
@arg reg_len : 数据长度
@arg reg_data : 待发送数据
* @retval 0:正常,非0:异常
**/
static uint8_t SI2C_WriteReg(uint8_t dev_addr, uint8_t reg_addr, uint8_t reg_len,unsigned char *reg_data)
{
uint8_t i, result=0;
SI2C_Start(); // 发送启动信号
result = SI2C_SendByte(dev_addr << 1 | I2C_Direction_Transmitter);
if(result != 0) return result;
result = SI2C_SendByte(reg_addr);
if(result != 0) return result;
for (i=0;i<reg_len;i++)
{
result = SI2C_SendByte(reg_data[i]);
if (result != 0) return result;
}
SI2C_Stop(); // 发送停止信号
return 0x00;
}
5、增加 static uint8_t SI2C_ReadReg(uint8_t dev_addr, uint8_t reg_addr, uint8_t reg_len,unsigned char *reg_data)函数
/**
* @func SI2C_ReadReg
* @brief 读寄存器
* @param
@arg dev_addr : 设备地址
@arg reg_addr : 寄存器地址
@arg reg_len : 数据长度
@arg reg_data : 读取到的数据
* @retval 0:正常,非0:异常
**/
static uint8_t SI2C_ReadReg(uint8_t dev_addr, uint8_t reg_addr, uint8_t reg_len,unsigned char *reg_data)
{
uint8_t result;
SI2C_Start(); // 发送启动信号
result = SI2C_SendByte(dev_addr << 1 | I2C_Direction_Transmitter);
if(result != 0) return result;
result = SI2C_SendByte(reg_addr);
if(result != 0) return result;
SI2C_Start(); // 发送启动信号
result = SI2C_SendByte(dev_addr << 1 | I2C_Direction_Receiver);
if(result != 0) return result;
while (reg_len)
{
if (reg_len==1) *reg_data = SI2C_ReadByte(0);
else *reg_data =SI2C_ReadByte(1);
reg_data++;
reg_len--;
}
SI2C_Stop(); // 发送停止信号
return 0x00;
}