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延时