TI中文支持网
TI专业的中文技术问题搜集分享网站

TM4C123GxL MPU6050读出陀螺仪和加速度计的值全为0

工程上传了附件,下面是主函数

int
main(void)
{
char a[2];
int_fast32_t i32IPart[16], i32FPart[16];
uint_fast32_t ui32Idx, ui32CompDCMStarted;
float pfData[13];
float *pfAccel, *pfGyro, *pfMag, *pfEulers, *pfQuaternion;

//
// Initialize convenience pointers that clean up and clarify the code
// meaning. We want all the data in a single contiguous array so that
// we can make our pretty printing easier later.
//
pfAccel = pfData;
pfGyro = pfData + 3;
pfEulers = pfData + 6;
pfQuaternion = pfData + 9;

//
//ÉèÖÃϵͳʱÖÓΪ40MHz
//
ROM_SysCtlClockSet(SYSCTL_SYSDIV_5 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ |
SYSCTL_OSC_MAIN);

//
// ʹÄÜGPIOBÖжÏ
//
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);

//
// ³õʼ»¯UART.
//
ConfigureUART();

//
// ´òӡʾÀýÐÅÏ¢
//
UARTprintf("\033[2JMPU6050 Raw Example\n");

//
// ÉèÖÃÄ¿±ê°åÑÕÉ«Ëã·¨
//
g_pui32Colors[RED] = 0x8000;
g_pui32Colors[BLUE] = 0x8000;
g_pui32Colors[GREEN] = 0x0000;

//
// ³õʼ»¯RGBÇý¶¯
//
RGBInit(0);
RGBColorSet(g_pui32Colors);
RGBIntensitySet(0.5f);
RGBEnable();

//
// ʹÄÜI2C3ÍâÉè
//
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C3);
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);

//
// ÅäÖÃI2C3µÄIOΪPD0ºÍPD1
//
ROM_GPIOPinConfigure(GPIO_PD0_I2C3SCL);
ROM_GPIOPinConfigure(GPIO_PD1_I2C3SDA);

//
// Ñ¡ÔñIO¸´Óù¦ÄܵÄÀà±ð
//
GPIOPinTypeI2CSCL(GPIO_PORTD_BASE, GPIO_PIN_0);
ROM_GPIOPinTypeI2C(GPIO_PORTD_BASE, GPIO_PIN_1);

//
// ÉèÖÃÖжÏÒý½Å£¬²¶×½MPU6050µÄÖжÏÐźŠ//
ROM_GPIOPinTypeGPIOInput(GPIO_PORTB_BASE, GPIO_PIN_2);
GPIOIntEnable(GPIO_PORTB_BASE, GPIO_PIN_2);
ROM_GPIOIntTypeSet(GPIO_PORTB_BASE, GPIO_PIN_2, GPIO_FALLING_EDGE);
ROM_IntEnable(INT_GPIOB);

//
// Keep only some parts of the systems running while in sleep mode.
// GPIOB is for the MPU6050 interrupt pin.
// UART0 is the virtual serial port
// TIMER0, TIMER1 and WTIMER5 are used by the RGB driver
// I2C3 is the I2C interface to the ISL29023
//
ROM_SysCtlPeripheralClockGating(true);
ROM_SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_GPIOB);
ROM_SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_UART0);
ROM_SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_TIMER0);
ROM_SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_TIMER1);
ROM_SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_I2C3);
ROM_SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_WTIMER5);

//
// ʹÄÜÖжϴ¦ÀíÆ÷
//
ROM_IntMasterEnable();

//
// ʹÄÜI2C3ÍâÉè
//
I2CMInit(&g_sI2CInst, I2C3_BASE, INT_I2C3, 0xff, 0xff,
ROM_SysCtlClockGet());

//
// ³õʶ»¯MPU6050Çý¶¯
//
MPU6050Init(&g_sMPU6050Inst, &g_sI2CInst, MPU6050_I2C_ADDRESS, MPU6050AppCallback, 0);
MPU6050AppI2CWait();
// g_sMPU6050Inst.pui8Data[0] = MPU6050_CONFIG_DLPF_CFG_94_98;
// g_sMPU6050Inst.pui8Data[1] = MPU6050_GYRO_CONFIG_FS_SEL_250;
// g_sMPU6050Inst.pui8Data[2] = MPU6050_ACCEL_CONFIG_AFS_SEL_2G;
// MPU6050Write(&g_sMPU6050Inst, MPU6050_O_CONFIG, g_sMPU6050Inst.pui8Data, 3,
// MPU6050AppCallback, 0);
// MPU6050AppI2CWait();
MPU6050ReadModifyWrite(&g_sMPU6050Inst, MPU6050_O_ACCEL_CONFIG,
~MPU6050_ACCEL_CONFIG_AFS_SEL_M,
MPU6050_ACCEL_CONFIG_AFS_SEL_4G, MPU6050AppCallback,
0);
MPU6050AppI2CWait();
//
// ʹÄÜÉÁ˸ָʾ³õʼ»¯Íê³É
//
RGBBlinkRateSet(1.0f);

ui32CompDCMStarted = 0;

while(1)
{
MPU6050DataRead(&g_sMPU6050Inst, MPU6050AppCallback, 0);
MPU6050AppI2CWait();
MPU6050DataAccelGetFloat(&g_sMPU6050Inst, pfAccel, pfAccel + 1, pfAccel + 2);
MPU6050DataGyroGetFloat(&g_sMPU6050Inst, pfGyro, pfGyro + 1, pfGyro + 2);
int_fast32_t fAccel[3], fGyro[3];
fAccel[0] = (int32_t)(pfAccel[0]);
fAccel[1] = (int32_t)(pfAccel[1]);
fAccel[2] = (int32_t)(pfAccel[2]);
fGyro[0] = (int32_t)(pfGyro[0]);
fGyro[1] = (int32_t)(pfGyro[1]);
fGyro[2] = (int32_t)(pfGyro[2]);
UARTprintf("\033[1;14H%010d %010d %010d\n\n", fAccel[0], fAccel[1],fAccel[2]);
UARTprintf("\033[2;14H%010d %010d %010d\n\n", fGyro[0], fGyro[1], fGyro[2]);
}
}

Wellin Zhang:

Pengyin

能否详细描述一下目前的状态。MCU与6050是否通信成功?

建议分步进行调试,可以参考sensorhub里面mpu9150的例程。

best regards

Wellin

pengyin huang:

回复 Wellin Zhang:

你好!

       IIC初始化应该没有问题,示波器能打出对应管脚的波形。 我是参考的sensorhub里面mpu9150的例程,只是对函数名稍作了修改,直接烧录MPU9150的示例的能读出陀螺仪和加速度值,但是函数名修改后对出的值全为0;不知是不是初始化6050是有问题初始化也是直接参考9150后的:

MPU6050Init(&g_sMPU6050Inst, &g_sI2CInst, MPU6050_I2C_ADDRESS, MPU6050AppCallback, 0); MPU6050AppI2CWait(); g_sMPU6050Inst.pui8Data[0] = MPU6050_CONFIG_DLPF_CFG_94_98; g_sMPU6050Inst.pui8Data[1] = MPU6050_GYRO_CONFIG_FS_SEL_250; g_sMPU6050Inst.pui8Data[2] = MPU6050_ACCEL_CONFIG_AFS_SEL_2G; MPU6050Write(&g_sMPU6050Inst, MPU6050_O_CONFIG, g_sMPU6050Inst.pui8Data, 3, MPU6050AppCallback, 0); MPU6050AppI2CWait();

// // Configure the data ready interrupt pin output of the MPU6050. // g_sMPU6050Inst.pui8Data[0] = MPU6050_INT_PIN_CFG_INT_LEVEL | MPU6050_INT_PIN_CFG_INT_RD_CLEAR | MPU6050_INT_PIN_CFG_LATCH_INT_EN; g_sMPU6050Inst.pui8Data[1] = MPU6050_INT_ENABLE_DATA_RDY_EN; MPU6050Write(&g_sMPU6050Inst, MPU6050_O_INT_PIN_CFG, g_sMPU6050Inst.pui8Data, 2, MPU6050AppCallback, &g_sMPU6050Inst); MPU6050AppI2CWait();

Wellin Zhang:

回复 pengyin huang:

pengyin

观察到你对程序还是有一些改动的比如初始化

MPU6050Init(&g_sMPU6050Inst, &g_sI2CInst, MPU6050_I2C_ADDRESS, MPU6050AppCallback, 0);

最后一个变量你传递的是0,实际上该变量应该传递一个指针,给callback函数的。

由于我手上没有MPU6050的demo,抱歉没法帮你调试。既然9150读数是正常的,建议在9150的基础上一步步进行修改。测试修改无问题后再进行下一步修改。谢谢

Best Regards

Wellin Zhang

pengyin huang:

回复 Wellin Zhang:

非常抱歉我这个程序实在看了传感器驱动程序手册的示例上做了修改,如果非常抱歉没有注意说明,还有

MDK5.1下提示非法字符说以也没有使用这两个产生,对使用这两个产生的地方进行了注释。

回调函数好航向有没有使用到传递的参数所以就照手册传递的为0

其他地方应该除了有个指令在6050中没有“MPU9150_ACCEL_CONFIG_ACCEL_HPF_5HZ ”,将其删除了。其他的我几乎原封不动只是修改了函数名称。现在手里只有6050,我现在的解决办法是直接使用的9150的库来操作6050。

因为调试时间比较紧,我会有空在详细看看库函数,待对库有了一定理解,后再尝试可能是自己在什么地方,传递的命令没能初始化6050,非常感谢

pengyin huang:

回复 Wellin Zhang:

Wellin Zhang:

          你好,非常感谢你之前对我的回复,我对照MPU9150简单的改写为MPU6050的代码直接使用是有问题的,下面我说说我调试过程以使后来者能少走弯路:

1、对于你的回答我开始怀疑是传感器的IIC库有问题(对于权威的质疑让我浪费了不少的时间,这也希望对我这样的小白能有所体谅),我开始自己写IIC的硬件驱动函数,但是发现也不能行通,用示波器查看是有不行输出,这让我很苦恼。这里我要反应一个问题,我写的是通过查询方式工作的,没有使用IIC中断,后来发现通过查询需要延时一段时间,但是没有在TM4C123的库文档,和相关手册中知道,我认为TI可以对一些需要特殊在程序启动流程注意的地方,单独写一个文档或加载元件文档或库文档举例中,这样能给使用者个好的使用体验,当然我觉TI在已经做的很好了关于用户使用体验上,这是值的肯定的,不过还是希望TI能做的更好。

2、我通过网上论坛和看MPU6050元件手册知道可以查看6050ID,通过自己的IIC能读出ID,用TI也能示例能读出ID,但发现多处6050的POWERMANAGEMENT 1这个寄存器发现芯片还是在休眠,也就是我的初始化没有被写进寄存器,这是由于初始化是TI给的是有一次复位,复位和上电6050都是在休眠状态的,这样是读不到值的。

3、在复位之后在次将6050唤醒,开始从串口传出我想要的数据了。

这是本人的调试过程和一些意见,希望TI做的愈来愈好。

对了还有之前 这个问题是我在阿莫论坛看到说要放在英文的路径下就不会有警告了,当然我实践发现放在中文路径下程序也能正常工作的!

Wellin Zhang:

回复 pengyin huang:

Hi Pengyin

非常感谢你的分享。同时也非常感谢您的意见。

X tank:

回复 pengyin huang:

您好,请问能不能让我看看您的最终成功的程序代码

CORY CHEN:

回复 pengyin huang:

 请问可以分享一下,正确的MPU6050的程序,最近也在diy四旋翼飞行器。谢谢

CORY CHEN:

回复 Wellin Zhang:

请问现在有9150或者6050的DEMO程序吗?

Best Regards

TiDany:

回复 pengyin huang:

感谢楼主的反馈,居然真的是设备休眠了,无法写入寄存器。

后来自己紧接着MPU6050初始化函数之后,写寄存器唤醒设备,之后,设备就可以正常读取值了。

可能是用其他单片机习惯了,之前只用过TI的430系列。

TM4Cxi列的库真的很多很强大,但是初次接触理解起来有点困难,一个MPU6050的示例居然那么多。从TI的整个库更接近于面向对象语言的思维模式,开发环境CCS也是用的eclipse这种框架。风格很不一样。但是应该长时间接触还是有好处的。只是现在不习惯而已,先赞一个。还有那些图形库真的很好用,赞一个。

然后就按照官方文档上写MPU6050的初始化,一开始是初始化不过去,发现是没有重新写IIC的中断函数,所以没有传递该中断函数中的tI2CMInstance实例,才导致这样的。

后来初始化成功了,设备号也可以读到,但是数据一值是0,后来发现是楼主说所的问题,官方库函数初始化里面,最后是复位设备。那么设备复位后默认是休眠。但是官方文档提供的初始化步骤又没有说这个。而且读写寄存器的函数也不易理解,文档说得也不清楚。所以希望TI在这方面能改进一下。

赞(0)
未经允许不得转载:TI中文支持网 » TM4C123GxL MPU6050读出陀螺仪和加速度计的值全为0
分享到: 更多 (0)