Lelin_8013 2023-06-27 04:21 采纳率: 0%
浏览 39

STM32C8T6,MPU6050串口输出不了数据

MPU6050的使用
本程序用CubeMX来配置,采用软件模拟I2C的方式来完成MPU6050的数据接受。但在CubeMX的配置图中发现,模拟的GPIO口好像可以直接设置成I2C,于是直接在软件上配置成了I2C来使用,速率设置成了40000,不知道这样是否可行。如图所示:

img

运行最终结果出现了问题,无法进行数据的读取,尚不清楚是哪一方面出现了问题,顺带提一句配置了FREERTOS,恳请给位热心人帮忙,如若可以,可以加我的QQ549978204,记得打个备注,已经写了5天了,实在想不出原因,望各位帮忙。

程序停滞在inv_mpu_user.c文件中的

while(1)
    {
        if(mpu_dmp_get_data(&pitch,&roll,&yaw)==0)
        {
            printf("pitch:%f\t,roll:%f\t,yaw:%f\r\n",pitch,roll,yaw);
        }    
    }

串口输出结果为

img

电路原理图:

img

芯片为STTM32C8T6,引脚口为PB8、PB9(具体如图所示)

img

"inv_mpu_user.h"代码如下:


#ifndef _INV_MPU_USER_H_
#define _INV_MPU_USER_H_

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "inv_mpu.h"
#include "inv_mpu_dmp_motion_driver.h"
#include "mpu6050.h"
#include "usart.h"


unsigned char mpu_dmp_get_data(float *pitch,float *roll,float *yaw);
unsigned char mpu_dmp_init(void);
int DMP_test(void);

#endif

"inv_mpu_user.c"代码如下:

#include "inv_mpu_user.h"


#define PRINT_ACCEL     (0x01)
#define PRINT_GYRO      (0x02)
#define PRINT_QUAT      (0x04)

#define ACCEL_ON        (0x01)
#define GYRO_ON         (0x02)

#define MOTION          (0)
#define NO_MOTION       (1)

/* Starting sampling rate. */
#define DEFAULT_MPU_HZ  (100)

#define FLASH_SIZE      (512)
#define FLASH_MEM_START ((void*)0x1800)

//q30格式,long转float时的除数.
#define q30  1073741824.0f

//struct mpu6050_data OutMpu;

//陀螺仪方向设置
static signed char gyro_orientation[9] = { 1, 0, 0,
                                           0, 1, 0,
                                           0, 0, 1};

                                                                                     
//方向转换
unsigned short inv_row_2_scale(const signed char *row)
{
    unsigned short b;

    if (row[0] > 0)
        b = 0;
    else if (row[0] < 0)
        b = 4;
    else if (row[1] > 0)
        b = 1;
    else if (row[1] < 0)
        b = 5;
    else if (row[2] > 0)
        b = 2;
    else if (row[2] < 0)
        b = 6;
    else
        b = 7;      // error
    return b;
}

//陀螺仪方向控制
unsigned short inv_orientation_matrix_to_scalar(
    const signed char *mtx)
{
    unsigned short scalar; 
    /*
       XYZ  010_001_000 Identity Matrix
       XZY  001_010_000
       YXZ  010_000_001
       YZX  000_010_001
       ZXY  001_000_010
       ZYX  000_001_010
     */

    scalar = inv_row_2_scale(mtx);
    scalar |= inv_row_2_scale(mtx + 3) << 3;
    scalar |= inv_row_2_scale(mtx + 6) << 6;
    return scalar;
}

unsigned char mpu_dmp_init(void)
{
    unsigned char res=0;
    struct int_param_s *p = 0;
    if(mpu_init()==0)    //初始化MPU6050
    {     
        res=mpu_set_sensors(INV_XYZ_GYRO|INV_XYZ_ACCEL);//设置所需要的传感器
        if(res)return 1; 
        res=mpu_configure_fifo(INV_XYZ_GYRO | INV_XYZ_ACCEL);//设置FIFO
        if(res)return 2; 
        res=mpu_set_sample_rate(DEFAULT_MPU_HZ);    //设置采样率
        if(res)return 3; 
        res=dmp_load_motion_driver_firmware();        //加载dmp固件
        if(res)return 4; 
        res=dmp_set_orientation(inv_orientation_matrix_to_scalar(gyro_orientation));//设置陀螺仪方向
        if(res)return 5; 
        res=dmp_enable_feature(DMP_FEATURE_6X_LP_QUAT|DMP_FEATURE_TAP|    //设置dmp功能
            DMP_FEATURE_ANDROID_ORIENT|DMP_FEATURE_SEND_RAW_ACCEL|DMP_FEATURE_SEND_CAL_GYRO|
            DMP_FEATURE_GYRO_CAL);
        if(res)return 6; 
        res=dmp_set_fifo_rate(DEFAULT_MPU_HZ);    //设置DMP输出速率(最大不超过200Hz)
        if(res)return 7;   
//        res=run_self_test();        //自检
//        if(res)return 8;    
        res=mpu_set_dmp_state(1);    //使能DMP
        if(res)return 9;     
    }
    printf("init ok\n");
    return 0;
}
/***************************************************************************************************************
*函数名:mpu_dmp_get_data()
*功能:得到dmp处理后的数据(注意,本函数需要比较多堆栈,局部变量有点多)
*形参:(struct _out_angle *angle):DMP解算得到的姿态
*返回值:0:成功/1:DMP_FIFO读取失败/2:数据读取失败
***************************************************************************************************************/

//声明这些全局变量,外部好使用

float pitch,roll,yaw;
unsigned char mpu_dmp_get_data(float *pitch,float *roll,float *yaw)
{
    float q0=1.0f,q1=0.0f,q2=0.0f,q3=0.0f;

    short gyro_dmp[3], accel_dmp[3], sensors_dmp;
    unsigned long sensor_timestamp;
    unsigned char more;
    long quat[4]; 

    dmp_read_fifo(gyro_dmp, accel_dmp, quat, &sensor_timestamp, &sensors_dmp,&more);    

    if(sensors_dmp&INV_WXYZ_QUAT) 
    {
        q0 = quat[0] / q30;    //q30格式转换为浮点数
        q1 = quat[1] / q30;
        q2 = quat[2] / q30;
        q3 = quat[3] / q30; 
        //计算得到俯仰角/横滚角/航向角
        *roll = asin(-2 * q1 * q3 + 2 * q0* q2)* 57.3;                                                                    // pitch
        *pitch  = atan2(2 * q2 * q3 + 2 * q0 * q1, -2 * q1 * q1 - 2 * q2* q2 + 1)* 57.3;    // roll
        *yaw   = atan2(2*(q1*q2 + q0*q3),q0*q0+q1*q1-q2*q2-q3*q3) * 57.3;    //yaw
    
    }else return 2;

    return 0;
}

int DMP_test(void)
{
    unsigned char i;
    float pitch,roll,yaw;
    HAL_Delay(500);
    //根据MPU6050官方DMP库说明,初始化时,必须使得Z轴与竖直方向平行,即小车竖立。
    i = mpu_dmp_init();
    while(i)
    {
        HAL_Delay(500);
        i = mpu_dmp_init();    
        printf("MPU6050 init error:%d\r\n",i);
    }
        printf("MPU6050 init OK\r\n");
    
    while(1)
    {
        if(mpu_dmp_get_data(&pitch,&roll,&yaw)==0)
        {
            printf("pitch:%f\t,roll:%f\t,yaw:%f\r\n",pitch,roll,yaw);
        }    
    }
}
  • 写回答

1条回答 默认 最新

  • 电子阿星 2023-07-04 12:39
    关注

    可能是IIC获取了数据,但是你使用了freertos操作系统,操作系统和串口的中断优先级起了冲突,所以你需要调整一下

    评论

报告相同问题?

问题事件

  • 创建了问题 6月27日

悬赏问题

  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 有没有帮写代码做实验仿真的
  • ¥15 報錯:Person is not mapped,如何解決?
  • ¥30 vmware exsi重置后登不上
  • ¥15 c++头文件不能识别CDialog
  • ¥15 Excel发现不可读取的内容
  • ¥15 关于#stm32#的问题:CANOpen的PDO同步传输问题
  • ¥20 yolov5自定义Prune报错,如何解决?
  • ¥15 电磁场的matlab仿真