自己做课题做的一块板子,MCU选用的是stm32f103c8t6 集成MPU9250 和另外一个芯片
调试到mpu9250时候 ,在keil上调试 加速度、角速度以及磁力计是有数据的。用到的就是论坛里分享的开源代码-->
http://www.openedv.com/forum.php ... id=80200&page=1
接下来焊接上另外一个芯片后,这个芯片与stm32也调试通了的。
但是,回过头来 准备做mpu9250的九轴融合时候,加速度、角速度和磁力计的数据都变为零了......
不知道有没有人遇到过这种情况?
说明:mpu9250用spi2连接的
另外的那个芯片用的是spi1
另外那个芯片从焊接到调通用了1晚上的时间,第二天早上来调试mpu9250就没数据了
mpu9250的引脚已经测试过了 都是连接着的呀
mpu9250与stm32的程序 与 另外芯片和stm32程序 是放在两个文件夹下的 分开放的 还没有融合在一起
烦请各位大佬看下
这个是spi.c文件
[mw_shl_code=c,true]#include "spi.h"
typedef struct{
short Accel[3];//Accel X,Y,Z
short Gyro[3];//Gyro X,Y,Z
short Mag[3]; //Mag X,Y,Z
}MPU_value;
MPU_value mpu_value;
//MPU_value *mpu_value=NULL; //9轴数据--------------修改
unsigned char BUF[6]; //接收数据缓存区
short Data_Buf[9];
/***************************************************************/
void spi_Init()
{
SPI_InitTypeDef SPI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
// RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1|RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
//GPIO口配置设置//
// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
// GPIO_Init(GPIOA, &GPIO_InitStructure);
// GPIO_SetBits(GPIOA,GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7);
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_SetBits(GPIOB,GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15);
/*Configure PA.4(NSS)--------------------------------------------*/
// GPIO_InitStructure.GPIO_Pin =GPIO_Pin_0;
// GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
// GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
// GPIO_Init(GPIOA, &GPIO_InitStructure);
// GPIO_SetBits(GPIOA,GPIO_Pin_0);
/*片选设置 PB12*/
GPIO_InitStructure.GPIO_Pin =GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_SetBits(GPIOB,GPIO_Pin_12);
/* SPI2 configuration */
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;//全双工
SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //主机模式
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //8位数据
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;//SPI_CPOL_High=模式3,时钟空闲为高 //SPI_CPOL_Low=模式0,时钟空闲为低
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;//SPI_CPHA_2Edge;//SPI_CPHA_1Edge, SPI_CPHA_2Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;//SPI_NSS_Soft;//SPI_NSS_Hard
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;//SPI_BaudRatePrescaler_2=32M;//SPI_BaudRatePrescaler_4=18MHz
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;//数据从高位开始发送
SPI_InitStructure.SPI_CRCPolynomial = 7;
// SPI_Init(SPI1, &SPI_InitStructure); //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器
// SPI_Cmd(SPI1, ENABLE); //使能SPI外设
SPI_Init(SPI2, &SPI_InitStructure); //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器
SPI_Cmd(SPI2, ENABLE); //使能SPI外设
}
/***************************************************************/
//SPIx
//TxData:发送一个字节
//返回值:data
/***************************************************************/
static u8 SPI2_ReadWriteByte(u8 TxData)//static u8 SPI1_ReadWriteByte(u8 TxData)
{
u8 retry=0;
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET) //等待SPI发送标志位空 修改
{
retry++;
if(retry>200)return 0;
}
SPI_I2S_SendData(SPI2, TxData); //发送数据 修改
retry=0;
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET) //等待SPI接收标志位空 修改
{
retry++;
if(retry>200)return 0;
}
return SPI_I2S_ReceiveData(SPI2); //接收数据 修改
}
/***************************************************************/
//SPI发送
//reg: addr
//value:数据
/***************************************************************/
u8 MPU9250_Write_Reg(u8 reg,u8 value)
{
u8 status;
MPU_9250_ENABLE; // MPU9250_CS=0; //片选MPU9250
status=SPI2_ReadWriteByte(reg); //发送reg地址
SPI2_ReadWriteByte(value);//发送数据
MPU_9250_DISENABLE;// MPU9250_CS=1; //失能MPU9250
return(status);//
}
//---------------------------------------------------------------//
//SPI读取
//reg: addr
u8 MPU9250_Read_Reg(u8 reg)
{
u8 reg_val;
MPU_9250_ENABLE;// MPU9250_CS=0; //片选MPU9250
SPI2_ReadWriteByte(reg|0x80); //reg地址+读命令
reg_val=SPI2_ReadWriteByte(0xff);//任意数据
MPU_9250_DISENABLE;// MPU9250_CS=1; //失能MPU9250
return(reg_val);
}
/***************************************************************/
// MPU内部i2c 写入
//I2C_SLVx_ADDR: MPU9250_AK8963_ADDR
//I2C_SLVx_REG: reg
//I2C_SLVx_Data out: value
/***************************************************************/
static void i2c_Mag_write(u8 reg,u8 value)
{
u16 j=500;
MPU9250_Write_Reg(I2C_SLV0_ADDR ,MPU9250_AK8963_ADDR);//设置磁力计地址,mode: write
MPU9250_Write_Reg(I2C_SLV0_REG ,reg);//set reg addr
MPU9250_Write_Reg(I2C_SLV0_DO ,value);//send value
while(j--);//此处因为MPU内部I2C读取速度较慢,延时等待内部写完毕
}
/***************************************************************/
// MPU内部i2c 读取
//I2C_SLVx_ADDR: MPU9250_AK8963_ADDR
//I2C_SLVx_REG: reg
//return value: EXT_SENS_DATA_00 register value
/***************************************************************/
static u8 i2c_Mag_read(u8 reg)
{
u16 j=5000;
MPU9250_Write_Reg(I2C_SLV0_ADDR ,MPU9250_AK8963_ADDR|0x80); //设置磁力计地址,mode:read
MPU9250_Write_Reg(I2C_SLV0_REG ,reg);// set reg addr
MPU9250_Write_Reg(I2C_SLV0_DO ,0xff);//read
while(j--);//此处因为MPU内部I2C读取速度较慢,必须延时等待内部读取完毕
return MPU9250_Read_Reg(EXT_SENS_DATA_00);
}
//****************初始化MPU9250,根据需要请参考pdf进行修改************************
void Init_MPU9250(void)
{
MPU9250_Write_Reg(PWR_MGMT_1, 0x00); //解除休眠状态
MPU9250_Write_Reg(CONFIG, 0x07); //低通滤波频率,典型值:0x07(3600Hz)此寄存器内决定Internal_Sample_Rate==8K
/**********************Init SLV0 i2c**********************************/
//Use SPI-bus read slave0
MPU9250_Write_Reg(INT_PIN_CFG ,0x30);// INT Pin / Bypass Enable Configuration
MPU9250_Write_Reg(I2C_MST_CTRL,0x4d);//I2C MAster mode and Speed 400 kHz
MPU9250_Write_Reg(USER_CTRL ,0x20); // I2C_MST _EN
MPU9250_Write_Reg(I2C_MST_DELAY_CTRL ,0x01);//延时使能I2C_SLV0 _DLY_ enable
MPU9250_Write_Reg(I2C_SLV0_CTRL ,0x81); //enable IIC and EXT_SENS_DATA==1 Byte
/*******************Init GYRO and ACCEL******************************/
MPU9250_Write_Reg(SMPLRT_DIV, 0x07); //陀螺仪采样率,典型值:0x07(1kHz) (SAMPLE_RATE= Internal_Sample_Rate / (1 + SMPLRT_DIV) )
MPU9250_Write_Reg(GYRO_CONFIG, 0x18); //陀螺仪自检及测量范围,典型值:0x18(不自检,2000deg/s)
MPU9250_Write_Reg(ACCEL_CONFIG, 0x18);//加速计自检、测量范围及高通滤波频率,典型值:0x18(不自检,16G)
MPU9250_Write_Reg(ACCEL_CONFIG_2, 0x08);//加速计高通滤波频率 典型值 :0x08 (1.13kHz)
/**********************Init MAG **********************************/
i2c_Mag_write(AK8963_CNTL2_REG,AK8963_CNTL2_SRST); // Reset AK8963
i2c_Mag_write(AK8963_CNTL1_REG,0x12); // use i2c to set AK8963 working on Continuous measurement mode1 & 16-bit output
}
//************************加速度读取**************************--------修改/
//void READ_MPU9250_ACCEL(void)//
//{
// BUF[0]=MPU9250_Read_Reg(ACCEL_XOUT_L);
// BUF[1]=MPU9250_Read_Reg(ACCEL_XOUT_H);
// mpu_value.Accel[0]= (BUF[1]<<8)|BUF[0];
// mpu_value.Accel[0]/=164; //读取计算X轴数据
// BUF[2]=MPU9250_Read_Reg(ACCEL_YOUT_L);
// BUF[3]=MPU9250_Read_Reg(ACCEL_YOUT_H);
// mpu_value.Accel[1]= (BUF[3]<<8)|BUF[2];
// mpu_value.Accel[1]/=164; //读取计算Y轴数据
// BUF[4]=MPU9250_Read_Reg(ACCEL_ZOUT_L);
// BUF[5]=MPU9250_Read_Reg(ACCEL_ZOUT_H);
// mpu_value.Accel[2]= (BUF[5]<<8)|BUF[4];
// mpu_value.Accel[2]/=164; //读取计算Z轴数据
//}
void READ_MPU9250_ACCEL(void)
{
BUF[0]=MPU9250_Read_Reg(ACCEL_XOUT_L);
BUF[1]=MPU9250_Read_Reg(ACCEL_XOUT_H);
mpu_value.Accel[0]= (BUF[1]<<8)|BUF[0];
mpu_value.Accel[0]/=164; //读取计算X轴数据
Data_Buf[0] = mpu_value.Accel[0];
BUF[2]=MPU9250_Read_Reg(ACCEL_YOUT_L);
BUF[3]=MPU9250_Read_Reg(ACCEL_YOUT_H);
mpu_value.Accel[1]= (BUF[3]<<8)|BUF[2];
mpu_value.Accel[1]/=164; //读取计算Y轴数据
Data_Buf[1] = mpu_value.Accel[1];
BUF[4]=MPU9250_Read_Reg(ACCEL_ZOUT_L);
BUF[5]=MPU9250_Read_Reg(ACCEL_ZOUT_H);
mpu_value.Accel[2]= (BUF[5]<<8)|BUF[4];
mpu_value.Accel[2]/=164; //读取计算Z轴数据
Data_Buf[2] = mpu_value.Accel[2];
}
/**********************陀螺仪读取*****************************-----修改*/
//void READ_MPU9250_GYRO(void)
//{
// BUF[0]=MPU9250_Read_Reg(GYRO_XOUT_L);
// BUF[1]=MPU9250_Read_Reg(GYRO_XOUT_H);
// mpu_value.Gyro[0]= (BUF[1]<<8)|BUF[0];
// mpu_value.Gyro[0]/=16.4; //读取计算X轴数据
// BUF[2]=MPU9250_Read_Reg(GYRO_YOUT_L);
// BUF[3]=MPU9250_Read_Reg(GYRO_YOUT_H);
// mpu_value.Gyro[1]= (BUF[3]<<8)|BUF[2];
// mpu_value.Gyro[1]/=16.4; //读取计算Y轴数据
// BUF[4]=MPU9250_Read_Reg(GYRO_ZOUT_L);
// BUF[5]=MPU9250_Read_Reg(GYRO_ZOUT_H);
// mpu_value.Gyro[2]= (BUF[5]<<8)|BUF[4];
// mpu_value.Gyro[2]/=16.4; //读取计算Z轴数据
//}
void READ_MPU9250_GYRO(void)
{
BUF[0]=MPU9250_Read_Reg(GYRO_XOUT_L);
BUF[1]=MPU9250_Read_Reg(GYRO_XOUT_H);
mpu_value.Gyro[0]= (BUF[1]<<8)|BUF[0];
mpu_value.Gyro[0]/=16.4; //读取计算X轴数据
Data_Buf[3]=mpu_value.Gyro[0];
BUF[2]=MPU9250_Read_Reg(GYRO_YOUT_L);
BUF[3]=MPU9250_Read_Reg(GYRO_YOUT_H);
mpu_value.Gyro[1]= (BUF[3]<<8)|BUF[2];
mpu_value.Gyro[1]/=16.4; //读取计算Y轴数据
Data_Buf[4]=mpu_value.Gyro[1];
BUF[4]=MPU9250_Read_Reg(GYRO_ZOUT_L);
BUF[5]=MPU9250_Read_Reg(GYRO_ZOUT_H);
mpu_value.Gyro[2]= (BUF[5]<<8)|BUF[4];
mpu_value.Gyro[2]/=16.4; //读取计算Z轴数据
Data_Buf[5]=mpu_value.Gyro[2];
}
/**********************磁力计读取***************************/
//i2c_Mag_read(AK8963_ST2_REG) 此步读取不可省略
//数据读取结束寄存器,reading this register means data reading end
//AK8963_ST2_REG 同时具有数据非正常溢出检测功能
//详情参考 MPU9250 PDF
/**********************************************************/
//void READ_MPU9250_MAG(void)
void READ_MPU9250_MAG(void)
{
u8 x_axis,y_axis,z_axis;
x_axis=i2c_Mag_read(AK8963_ASAX);// X轴灵敏度调整值
y_axis=i2c_Mag_read(AK8963_ASAY);
z_axis=i2c_Mag_read(AK8963_ASAZ);
if((i2c_Mag_read(AK8963_ST1_REG)&AK8963_ST1_DOR)==0)//data ready
{
//读取计算X轴数据
BUF[0]=i2c_Mag_read(MAG_XOUT_L); //Low data
if((i2c_Mag_read(AK8963_ST2_REG)&AK8963_ST2_HOFL)==1)// data reading end register & check Magnetic sensor overflow occurred
{
BUF[0]=i2c_Mag_read(MAG_XOUT_L);//reload data
}
BUF[1]=i2c_Mag_read(MAG_XOUT_H); //High data
if((i2c_Mag_read(AK8963_ST2_REG)&AK8963_ST2_HOFL)==1)// data reading end register
{
BUF[1]=i2c_Mag_read(MAG_XOUT_H);
}
mpu_value.Mag[0]=((BUF[1]<<8)|BUF[0])*(((x_axis-128)>>8)+1); //灵敏度纠正 公式见/RM-MPU-9250A-00 PDF/ 5.13
Data_Buf[6]=mpu_value.Mag[0];
//读取计算Y轴数据
BUF[2]=i2c_Mag_read(MAG_YOUT_L); //Low data
if((i2c_Mag_read(AK8963_ST2_REG)&AK8963_ST2_HOFL)==1)// data reading end register
{
BUF[2]=i2c_Mag_read(MAG_YOUT_L);
}
BUF[3]=i2c_Mag_read(MAG_YOUT_H); //High data
if((i2c_Mag_read(AK8963_ST2_REG)&AK8963_ST2_HOFL)==1)// data reading end register
{
BUF[3]=i2c_Mag_read(MAG_YOUT_H);
}
mpu_value.Mag[1]=((BUF[3]<<8)|BUF[2])*(((y_axis-128)>>8)+1);
Data_Buf[7]=mpu_value.Mag[1];
//读取计算Z轴数据
BUF[4]=i2c_Mag_read(MAG_ZOUT_L); //Low data
if((i2c_Mag_read(AK8963_ST2_REG)&AK8963_ST2_HOFL)==1)// data reading end register
{
BUF[4]=i2c_Mag_read(MAG_ZOUT_L);
}
BUF[5]=i2c_Mag_read(MAG_ZOUT_H); //High data
if((i2c_Mag_read(AK8963_ST2_REG)&AK8963_ST2_HOFL)==1)// data reading end register
{
BUF[5]=i2c_Mag_read(MAG_ZOUT_H);
}
mpu_value.Mag[2]=((BUF[5]<<8)|BUF[4])*(((z_axis-128)>>8)+1);
Data_Buf[8]=mpu_value.Mag[2];
}
}
[/mw_shl_code]
这是 main.c
[mw_shl_code=c,true]//#include "stm32f10x.h"
/* --------------接收MPU9250数据 通过蓝牙发送到串口 加入姿态解算 -------------*/
#include "stm32f10x.h"
#include "spi.h"
#include "delay.h"
#include "led.h"
#include "usart.h"
#include "stdio.h"
#include <math.h>
#include "MahonyAHRS.h"
extern short Data_Buf[9];
short Data_Buf_H[9];
extern float Angle[3];
int main()
{
u8 t;
delay_init();
uart_init(115200);
LED_Init();
spi_Init();
Init_MPU9250();
while(1)
{
READ_MPU9250_ACCEL();
READ_MPU9250_GYRO();
READ_MPU9250_MAG();
Mahony_update((float)Data_Buf[3], (float)Data_Buf[4], (float)Data_Buf[5],(float)Data_Buf[0],(float)Data_Buf[1],(float)Data_Buf[2],(float)Data_Buf[6],(float)Data_Buf[7],(float)Data_Buf[8]);
for (t=0;t<9;t++)
{
USART_SendData(USART1,Data_Buf[t]);
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);//等待数据发送结束
Data_Buf_H[t]=Data_Buf[t]>>8 & 0x00FF; //右移八位 并且
USART_SendData(USART1,Data_Buf_H[t]);
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET); //等待数据发送结束
}
GPIO_SetBits(GPIOA,GPIO_Pin_2);
delay_ms(30);
GPIO_ResetBits(GPIOA,GPIO_Pin_2);
delay_ms(30);
// delay_ms(10);
}
}
[/mw_shl_code]
非常 非常 感谢
一周热门 更多>