MPU6500驱动调试笔记(STM32F427+SPI2)

请加扣扣技术交流群:460189483 

1、由datasheet P34得知:CPOL=1,CPHA=1;

可以看到是在SCLK上升沿采样,SCLK下降沿改变数据,结合如下2张SPI时序图,不难发现

从上面可以得出,CPOL=0 CPHA=0与CPOL=1 CPHA=1都满足SPI时序要求,我们选择CPOL=1 CPHA=1的SPI时序  

2. SPI2初始化代码如下,是基于HAL库编写

SPI_HandleTypeDef SPI2_Handler;  //SPI¾ä±ú

//ÕâÀïÕëÊǶÔSPI2µÄ³õʼ»¯ CPOL=1 CPHA=1
void SPI2_Init(void)
{
    SPI2_Handler.Instance=SPI2;                         //SP2
    SPI2_Handler.Init.Mode=SPI_MODE_MASTER;             
    SPI2_Handler.Init.Direction=SPI_DIRECTION_2LINES;   
    SPI2_Handler.Init.DataSize=SPI_DATASIZE_8BIT;       
    SPI2_Handler.Init.CLKPolarity=SPI_POLARITY_HIGH;    
    SPI2_Handler.Init.CLKPhase=SPI_PHASE_2EDGE;         
    SPI2_Handler.Init.NSS=SPI_NSS_SOFT;                 
    SPI2_Handler.Init.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_256;
    SPI2_Handler.Init.FirstBit=SPI_FIRSTBIT_MSB;       
    SPI2_Handler.Init.TIMode=SPI_TIMODE_DISABLE;       
    SPI2_Handler.Init.CRCCalculation=SPI_CRCCALCULATION_DISABLE;
    SPI2_Handler.Init.CRCPolynomial=7;                  
    HAL_SPI_Init(&SPI2_Handler);
    
    __HAL_SPI_ENABLE(&SPI2_Handler);                   
	
}

void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi)
{
    GPIO_InitTypeDef GPIO_Initure;
    
		__HAL_RCC_GPIOD_CLK_ENABLE();       //ʹÄÜGPIODʱÖÓ
		__HAL_RCC_GPIOB_CLK_ENABLE();       //ʹÄÜGPIOBʱÖÓ
		__HAL_RCC_SPI2_CLK_ENABLE();        //ʹÄÜSPI3ʱÖÓ
		
		//PB14,15
		GPIO_Initure.Pin=GPIO_PIN_14|GPIO_PIN_15;
		GPIO_Initure.Mode=GPIO_MODE_AF_PP;              
		GPIO_Initure.Pull=GPIO_PULLUP;                  
		GPIO_Initure.Speed=GPIO_SPEED_HIGH;                     
		GPIO_Initure.Alternate=GPIO_AF5_SPI2;           
		HAL_GPIO_Init(GPIOB,&GPIO_Initure);
		
		//SPI2_SCK
		GPIO_Initure.Pin=GPIO_PIN_3;
		HAL_GPIO_Init(GPIOD,&GPIO_Initure);
}
void SPI2_SetSpeed(u16 SPI_BaudRatePrescaler)
{
    assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_BaudRatePrescaler));//ÅжÏÓÐЧÐÔ
    __HAL_SPI_DISABLE(&SPI2_Handler);            //¹Ø±ÕSPI
    SPI2_Handler.Instance->CR1&=0XFFC7;          //λ3-5ÇåÁ㣬ÓÃÀ´ÉèÖò¨ÌØÂÊ
    SPI2_Handler.Instance->CR1|=SPI_BaudRatePrescaler;//ÉèÖÃSPIËÙ¶È
    __HAL_SPI_ENABLE(&SPI2_Handler);             //ʹÄÜSPI
    
}
u8 SPI2_ReadWriteByte(u8 TxData)
{
    u8 Rxdata;
    HAL_SPI_TransmitReceive(&SPI2_Handler,&TxData,&Rxdata,1, 1000);       
 	return Rxdata;          		    //·µ»ØÊÕµ½µÄÊý¾Ý		
}

MPU6500的初始化及读取代码如下: 

u8 MPU6500_Init(void)
{
    u8 res=0;
	MPU6500_GPIO_Init();
	SPI2_Init();
	MPU_Write_Byte(MPU_PWR_MGMT1_REG,0X80);//¸´Î»MPU6500
    delay_ms(100);  //ÑÓʱ100ms
	MPU_Write_Byte(MPU_PWR_MGMT1_REG,0X00);//»½ÐÑMPU6500
    MPU_Set_Gyro_Fsr(3);					        	//ÍÓÂÝÒÇ´«¸ÐÆ÷,¡À2000dps
	MPU_Set_Accel_Fsr(0);					       	 	//¼ÓËٶȴ«¸ÐÆ÷,¡À2g
    MPU_Set_Rate(50);						       	 	//ÉèÖòÉÑùÂÊ50Hz
	MPU_Write_Byte(MPU_INT_EN_REG,0X00);   //¹Ø±ÕËùÓÐÖжÏ
	MPU_Write_Byte(MPU_USER_CTRL_REG,0X00);//I2CÖ÷ģʽ¹Ø±Õ
	MPU_Write_Byte(MPU_FIFO_EN_REG,0X00);	//¹Ø±ÕFIFO
	MPU_Write_Byte(MPU_INTBP_CFG_REG,0X82);//INTÒý½ÅµÍµçƽÓÐЧ£¬¿ªÆôbypassģʽ£¬¿ÉÒÔÖ±½Ó¶ÁÈ¡´ÅÁ¦¼Æ
	
	res=MPU_Read_Byte(MPU_DEVICE_ID_REG);  //¶ÁÈ¡MPU6500µÄID
    if(res==MPU6500_ID) //Æ÷¼þ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;

    return 0;
}

u8 MPU_Set_Gyro_Fsr(u8 fsr)
{
	return MPU_Write_Byte(MPU_GYRO_CFG_REG,fsr<<3);//ÉèÖÃÍÓÂÝÒÇÂúÁ¿³Ì·¶Î§  
}
//ÉèÖÃMPU6500¼ÓËٶȴ«¸ÐÆ÷ÂúÁ¿³Ì·¶Î§
//fsr:0,¡À2g;1,¡À4g;2,¡À8g;3,¡À16g
//·µ»ØÖµ:0,ÉèÖóɹ¦
//    ÆäËû,ÉèÖÃʧ°Ü 
u8 MPU_Set_Accel_Fsr(u8 fsr)
{
	return MPU_Write_Byte(MPU_ACCEL_CFG_REG,fsr<<3);//ÉèÖüÓËٶȴ«¸ÐÆ÷ÂúÁ¿³Ì·¶Î§  
}

//ÉèÖÃMPU6500µÄÊý×ÖµÍͨÂ˲¨Æ÷
//lpf:Êý×ÖµÍͨÂ˲¨ÆµÂÊ(Hz)
//·µ»ØÖµ:0,ÉèÖóɹ¦
//    ÆäËû,ÉèÖÃʧ°Ü 
u8 MPU_Set_LPF(u16 lpf)
{
	u8 data=0;
	if(lpf>=188)data=1;
	else if(lpf>=98)data=2;
	else if(lpf>=42)data=3;
	else if(lpf>=20)data=4;
	else if(lpf>=10)data=5;
	else data=6; 
	return MPU_Write_Byte(MPU_CFG_REG,data);//ÉèÖÃÊý×ÖµÍͨÂ˲¨Æ÷  
}

//ÉèÖÃMPU6500µÄ²ÉÑùÂÊ(¼Ù¶¨Fs=1KHz)
//rate:4~1000(Hz)
//·µ»ØÖµ:0,ÉèÖóɹ¦
//    ÆäËû,ÉèÖÃʧ°Ü 
u8 MPU_Set_Rate(u16 rate)
{
	u8 data;
	if(rate>1000)rate=1000;
	if(rate<4)rate=4;
	data=1000/rate-1;
	data=MPU_Write_Byte(MPU_SAMPLE_RATE_REG,data);	//ÉèÖÃÊý×ÖµÍͨÂ˲¨Æ÷
 	return MPU_Set_LPF(rate/2);	//×Ô¶¯ÉèÖÃLPFΪ²ÉÑùÂʵÄÒ»°ë
}

//µÃµ½Î¶ÈÖµ
//·µ»ØÖµ:ζÈÖµ(À©´óÁË100±¶)
short MPU_Get_Temperature(void)
{
    u8 buf[2]; 
    short raw;
	float temp;
	MPU_Read_Len(MPU_TEMP_OUTH_REG,2,buf); 
    raw=((u16)buf[0]<<8)|buf[1];  
    temp=21+((double)raw)/333.87;  
    return temp*100;;
}
//µÃµ½ÍÓÂÝÒÇÖµ(ԭʼֵ)
//gx,gy,gz:ÍÓÂÝÒÇx,y,zÖáµÄԭʼ¶ÁÊý(´ø·ûºÅ)
//·µ»ØÖµ:0,³É¹¦
//    ÆäËû,´íÎó´úÂë
u8 MPU_Get_Gyroscope(short *gx,short *gy,short *gz)
{
    u8 buf[6],res; 
	res=MPU_Read_Len(MPU_GYRO_XOUTH_REG,6,buf);
	if(res==0)
	{
		*gx=((u16)buf[0]<<8)|buf[1];  
		*gy=((u16)buf[2]<<8)|buf[3];  
		*gz=((u16)buf[4]<<8)|buf[5];
	} 	
    return res;;
}
//µÃµ½¼ÓËÙ¶ÈÖµ(ԭʼֵ)
//gx,gy,gz:ÍÓÂÝÒÇx,y,zÖáµÄԭʼ¶ÁÊý(´ø·ûºÅ)
//·µ»ØÖµ:0,³É¹¦
//    ÆäËû,´íÎó´úÂë
u8 MPU_Get_Accelerometer(short *ax,short *ay,short *az)
{
    u8 buf[6],res;  
	res=MPU_Read_Len(MPU_ACCEL_XOUTH_REG,6,buf);
	if(res==0)
	{
		*ax=((u16)buf[0]<<8)|buf[1];  
		*ay=((u16)buf[2]<<8)|buf[3];  
		*az=((u16)buf[4]<<8)|buf[5];
	} 	
    return res;;
}

//SPIдһ¸ö×Ö½Ú 
//devaddr:Æ÷¼þIICµØÖ·
//reg:¼Ä´æÆ÷µØÖ·
//data:Êý¾Ý
//·µ»ØÖµ:0,Õý³£
//    ÆäËû,´íÎó´úÂë
u8 MPU_Write_Byte(u8 reg,u8 data)
{
	__MPU6500_CS_ENABLE();
	SPI2_ReadWriteByte(reg&0x7F);  //w MSB must be 0
	SPI2_ReadWriteByte(data);
	__MPU6500_CS_DISABLE();
	return 0;
}

//SPI¶ÁÒ»¸ö×Ö½Ú 
//reg:¼Ä´æÆ÷µØÖ· 
//·µ»ØÖµ:¶Áµ½µÄÊý¾Ý
u8 MPU_Read_Byte(u8 reg)
{
	u8 data=0;
	__MPU6500_CS_ENABLE();
	SPI2_ReadWriteByte(reg|0x80);	//r msb must be 1
	data = SPI2_ReadWriteByte(0XFF);
	__MPU6500_CS_DISABLE();
	return data;
}


//ͬʱ¶Á¶à¸ö¼Ä´æÆ÷
//reg:Æðʼ¼Ä´æÆ÷µØÖ·
//len:¶Á¼Ä´æÆ÷µÄ×ܸöÊý
//*buf:´æ´¢ÄÚ´æÆðʼָÕë
u8 MPU_Read_Len(u8 reg, u8 len,u8 *buf)
{ 	
	__MPU6500_CS_ENABLE();
	while(len)
	{
		SPI2_ReadWriteByte(reg|0x80);	//r msb must be 1
		*buf=SPI2_ReadWriteByte(0x00);
		len--;
		buf++;
		reg++;
		delay_us(5); 
	}	
	__MPU6500_CS_DISABLE();
	return 0;
}

//SPIÁ¬Ðøд
//addr:Æ÷¼þµØÖ· 
//reg:¼Ä´æÆ÷µØÖ·
//len:дÈ볤¶È
//buf:Êý¾ÝÇø
//·µ»ØÖµ:0,Õý³£
//    ÆäËû,´íÎó´úÂë
u8 MPU_Write_Len(u8 reg,u8 len,u8 *buf)
{
	__MPU6500_CS_ENABLE();
    while(len)
	{
        SPI2_ReadWriteByte(reg&0x7F);  //w MSB must be 0
		SPI2_ReadWriteByte(*buf);
		len--;
		buf++;
		reg++;
		delay_us(5); 
    }
	__MPU6500_CS_DISABLE();
    return 0;
} 

2、采样频率200hz,陀螺仪量程正负250dps,加速度量程正负2g,16bit输出;注意yan延时

猜你喜欢

转载自blog.csdn.net/u014453443/article/details/83183598
今日推荐