MPU9250移植DMP出现的问题memcmp(firmware+ii, cur, this_write)

移直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;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值