陈皮和橘子皮有什么区别| 全身痒是什么病| 低压高用什么药| 甲功三项查的是什么| 父亲生日送什么礼物| 缺维生素会有什么症状| 命大是什么意思| 仔仔是什么意思| 肠胃炎输液用什么药| 大肝功能是检查什么| 1985年属牛的是什么命| 猫咪飞机耳是什么意思| 什么药能治口臭| 痔疮吃什么药好| 0是什么| 什么的雪人| 栀子有什么功效| 免疫固定电泳查什么的| 什么看果园越看越少| 梦见蛀牙掉是什么预兆| 五蕴皆空是什么意思| 升血小板吃什么药| 阴历三月是什么星座| 体感温度是什么意思| 结婚50年是什么婚| 内痔用什么药| 头皮屑多用什么洗发水效果好| 度蜜月什么意思| llbean是什么牌子| 融合菜是什么意思| 金蝉脱壳什么意思| 商是什么| 中国的国酒是什么| 什么星| 猫不能吃什么| 银手镯为什么会变黑| 驾照c2能开什么车| 什么是危险期| 正痛片别名叫什么| 旅行的意义是什么| 撸什么意思| 白痰是什么原因| 政治家是什么意思| 羊奶粉有什么好处| 羊水穿刺是检查什么的| 北方五行属什么| 痔疮疼痛用什么药| 鼻子老流鼻涕是什么原因引起| 唇周围长痘痘是什么原因| 戒烟有什么方法| 检查梅毒挂什么科| 胆结石有什么治疗方法| 航班号是什么| 脑电图是检查什么的| 小孩脸肿是什么原因引起的| oba是什么意思| 顽固性失眠吃什么药| 为什么第一次进不去| 什么蛋不能吃| 老是吐是什么原因| 尿为什么是黄色的| 梦见找孩子什么预兆| 男性霉菌感染用什么药| 苦荞茶适合什么人喝| 凤凰代表什么生肖| choker是什么意思| 玟是什么意思| 溺水是什么意思| 婴儿拉肚子是什么原因造成的| 惊为天人是什么意思| 早餐吃什么比较好| 吃什么能消除脂肪瘤| 孙笑川是什么梗| 相宜的意思是什么| 都有什么瓜| aupres是什么牌子化妆品| 12月8号什么星座| 199年属什么生肖| 吹空调嗓子疼吃什么药| 白细胞计数偏高是什么原因| 零和游戏是什么意思| 强磁对人体有什么危害| 糖尿病筛查做什么检查| e站是什么| 激素药是什么意思| 星期三打喷嚏代表什么| 顺位是什么意思| 存在感是什么意思| vodka是什么酒| 狗属于什么科| 春天有什么花| 耽美剧是什么意思| 脑膜炎吃什么药| 什么叫脂溢性皮炎| 什么面膜好用| 鱼的偏旁部首是什么| 指什么生肖| 狗狗蛋蛋红肿是什么原因| 血尿是什么原因引起的男性| 白头翁是什么意思| leep术是什么手术| 逆商是什么意思| 月经推迟一个月不来什么原因| 恶露是什么东西| 氧分压是什么意思| ctm是什么意思| 女大一抱金鸡是什么意思| 吃什么水果降血压| 脂膜炎是什么病严重吗| 毛主席什么时候去世的| 内心独白什么意思| 一岁宝宝口臭是什么原因引起的| 69年属什么生肖| 六九是什么意思| kfc是什么| 省委副书记是什么级别| 身上有红色的小红点是什么原因| 梨是什么季节的水果| 慢慢地什么填词语| 月亮什么时候是圆的| aj和nike什么关系| 食物中毒挂什么科| lr是什么意思| 消化不良的症状吃什么药| 包皮过长是什么样的| 6月13日是什么日子| 省公安厅厅长什么级别| 饱经风霜是什么生肖| 鱼油什么时候吃最好| RH是什么| 什么身什么骨| 白蛋白是什么意思| 作揖是什么意思| 宝宝打嗝是什么原因引起的| 吃维生素b2有什么好处和副作用| 虾膏是什么| 什么是口交| 抽筋什么原因| 凉粉用什么做的| 空鼻症是什么症状| 小金人车标是什么车| 白糖和冰糖有什么区别| 小炒肉用什么肉| kb是什么意思| 九零年属什么生肖| 结膜炎滴什么眼药水| 什么私语| 武汉什么省| 千与千寻是什么意思| 疖肿是什么| 湿气重吃什么中药好| 覆水难收是什么意思| 清汤寡水是什么意思| 切屏是什么意思| 259是什么意思| 节点是什么意思| 塑造是什么意思| 什么化痰效果最好最快| 异性缘是什么意思| 跟单员是做什么的| 报喜鸟属于什么档次| 精神分裂症吃什么药| 西米是用什么做的| 发烧吃什么退烧药| w代表什么单位| 百合有什么功效| 查淋巴挂什么科| 什么茶减肥效果最好| 儿童感冒流鼻涕吃什么药好得快| 什么米好吃又香又软| 梦到吃梨是什么意思| 血管瘤长什么样子图片| 动脉硬化吃什么药最好| 月经期喝什么好| 结梁子什么意思| 什么是支气管扩张| 什么属于| 咳嗽有痰挂什么科| 牛蹄筋炖什么好吃| 眩晕症吃什么药| 阴道镜活检是什么意思| 杨梅是什么季节的水果| 不爽是什么意思| 小苏打是什么| 扁扁的鱼叫什么鱼| 鱼疗是什么鱼| 面部肌肉跳动是什么原因| 信徒什么意思| 睡眠不好总做梦是什么原因| 总蛋白偏低是什么原因| 膝盖小腿酸软无力是什么原因| 6代表什么| 今年23岁属什么生肖| 健身后应该吃什么| 醋泡葡萄干有什么功效和作用| 炭疽是什么| 尿白细胞弱阳性什么意思| 吃什么对肺最好| 黑脸娃娃有什么功效| 撒贝宁是什么族| 梦见僵尸是什么预兆| 瘆人是什么意思| 粉色裤子配什么上衣| 塬字五行属什么| 抗环瓜氨酸肽抗体高是什么意思| 老是吐是什么原因| 最近天气为什么这么热| 什么减肥最快不反弹| 淋巴细胞偏低是什么意思| 安罗替尼适合什么肿瘤| 心服口服是什么意思| 牙体牙髓科看什么| 香港脚是什么意思| 云南古代叫什么| 紫癜是什么病严重吗| 果是什么意思| 软装是什么| 看指甲挂什么科| 什么是贫血| 咖啡豆是什么动物粪便| 甲状腺结节是什么引起的| 甲减有什么症状表现| 老公是什么意思| 十二月十二日是什么星座| 七月份出生是什么星座| 尿酸高吃什么药降尿酸效果好| 什么鱼蛋白质含量高| 生物工程专业学什么| 耳垂后面疼是什么原因| 天雨粟鬼夜哭什么意思| 人尽可夫是什么意思| 小孩子睡觉磨牙是什么原因| 国际章是什么意思| 大虾炒什么菜好吃| 子午相冲是什么意思| 11月18日是什么星座| 中文是什么意思| 太平果是什么水果| 少年郎是什么意思| 什么时候普及高中| o什么意思| 为什么胸闷一吃丹参滴丸就好| 黄飞鸿是什么生肖| 喘不过气是什么原因| cd8高是什么原因| 治股癣用什么药最好| 阑尾炎吃什么消炎药| 阴骘是什么意思| 弥漫性病变是什么意思| 茉莉茶叶有什么功效和作用| 2006年是什么命| 屁股大什么原因| 买买提是什么意思| 人彘为什么还能活着| 加拿大签证需要什么材料| 凝血功能差有什么危害| 一心向阳下一句是什么| 吃醋对身体有什么好处| 胃幽门螺旋杆菌吃什么药| 轻食是什么| 被银环蛇咬了有什么症状| 嘴紫是什么原因| 水嘴是什么| 老打嗝是什么原因引起的| 百度
打印
[RISC-V MCU 应用开发]

江苏坚持供给侧改革做好经济工作保持稳中有进向好

[复制链接]
638|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
点赞|  楼主 | 2025-7-27 20:28 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式



MPU6050是一个6轴姿态传感器(3轴加速度计和3轴陀螺仪传感器),可以测量芯片自身X、Y、Z轴的加速度、角度参数,通过数据融合,可以得到姿态角。
mpu6050在运动控制、车辆和飞行器控制等方面应用非常的多。


MPU6050作为一个6轴姿态传感器,其中3轴加速度计为x、y、z三个方向的加速度,3轴陀螺仪传感器为围绕x、y、z旋转的加速度。


在MPU6050中,X、Y、Z轴都具有一个加速度计,假设芯片里有6个测力的秤组成一个正方体,正方体内部放一个大小正好的单位质量小球,小球压在一个面上,就会产生对应轴的数据输出。如果压在上面为正值,压在下面为负值,6个面测的力就是3个轴的加速度值。



MPU6050芯片内部的陀螺仪测量的实时角速度,分别表示了此时芯片绕X、Y、Z轴旋转的角速度。对角速度进行积分,就可以得到角度。




相关帖子

沙发
点赞|  楼主 | 2025-7-27 20:30 | 只看该作者
本帖最后由 点赞 于 2025-7-27 20:34 编辑

MPU6050参数:

?一、加速度计?


量程:±2g、±4g、±8g、±16g(默认±2g)。????
分辨率:16位ADC。??


二、陀螺仪?
量程:±250°/s、±500°/s、±1000°/s、±2000°/s(默认±250°/s)。????
灵敏度误差:±1%。??


三、其他特性
?
内置温度传感器(用于漂移补偿)。??
数字运动处理器(DMP):支持四元数/欧拉角输出,减轻主控负担。??
采样率:加速度计1kHz,陀螺仪8kHz(DMP融合输出200Hz)。??


?四、电气特性?


工作电压:2.375V~3.46V(模块支持3.3V/5V输入)。??

功耗:6轴模式≤3mA,睡眠模式5μA。??

接口:I2C(400kHz,默认地址0x68/0x69),SPI(仅MPU6000支持)









板凳
点赞|  楼主 | 2025-7-27 20:43 | 只看该作者
电路原理图


MPU6050 模块内部自带稳压电路,可兼容 3.3V/5V 的供电电压,采用先进的数字滤波技术,提高精度同时抑制了测量噪声。通讯方面,MPU6050 保留了 IIC 接口,高级用户能够采样底层测量数据。值得一提的是,芯片集成了 DMP (Digital Motion Processor)数字动态处理器(以后会用到,实现平衡小车姿体平衡)从陀螺仪、加速度计以及外接的传感器接收并处理数据,处理结果可以从 DMP 寄存器读出,或通过 FIFO(First In First Out) 缓冲。下图为模块的原理图:


地板
点赞|  楼主 | 2025-7-27 20:49 | 只看该作者
本帖最后由 点赞 于 2025-7-27 20:52 编辑

HPM5361与MPU6050的连接:

使用的HPM5361开发板P1接口有两组I2C接口,这里使用I2C0接口,及PB03和PB02引脚。



这两个引脚,在开发板上已经有了10K的上拉电阻,使用的mpu6050上也有4.7k的上拉电阻,这里可以共存,不需要特殊处理。

5
点赞|  楼主 | 2025-7-27 20:52 | 只看该作者
本帖最后由 点赞 于 2025-7-27 21:16 编辑

工程创建及资源配置:
一、新建工程

打开RT-Thread Studio,在菜单选:文件-->新建-->RT-Thread 项目,在打开的“新建项目”选项卡,填写项目名称,选择“基于开发板”,其他选项默认,点“完成”按钮。



二、配置工程资源

双击工程下的“RT-Thread Setting”,打开RT-Thread Setting选项卡。
在软件包项目下,点“添加软件包”,在打开的搜索页面搜索“mpu”,在出现的项目中点“mpu6xxx“软件包的”添加“按钮。


我这里已经添加完毕。
在”软件包“标签页,配置mpu6xxx软件包:


在”组件“标签页打开”使用I2C设备驱动程序“

在”硬件“标签页,打开”Enable I2C“选项,并打开I2C0。

671356886268f0cbe5.png (101.02 KB )

671356886268f0cbe5.png
6
点赞|  楼主 | 2025-7-27 20:56 | 只看该作者
本帖最后由 点赞 于 2025-7-27 21:34 编辑

主要代码:
mpu6xxx.c文件:
写寄存器:

static rt_err_t mpu6xxx_write_reg(struct mpu6xxx_device *dev, rt_uint8_t reg, rt_uint8_t data)
{
    rt_int8_t res = 0;
#ifdef RT_USING_I2C
    struct rt_i2c_msg msgs;
    rt_uint8_t buf[2] = {reg, data};
#endif
    if (dev->bus->type == RT_Device_Class_I2CBUS)
    {
#ifdef RT_USING_I2C
        msgs.addr  = dev->i2c_addr;    /* slave address */
        msgs.flags = RT_I2C_WR;        /* write flag */
        msgs.buf   = buf;              /* Send data pointer */
        msgs.len   = 2;

        if (rt_i2c_transfer((struct rt_i2c_bus_device *)dev->bus, &msgs, 1) == 1)
        {
            res = RT_EOK;
        }
        else
        {
            res = -RT_ERROR;
        }
#endif
    }
    else
    {
#ifdef RT_USING_SPI
        res = rt_spi_send_then_send((struct rt_spi_device *)dev->bus, ?, 1, &data, 1);
#endif
    }
    return res;
}
读寄存器:

static rt_err_t mpu6xxx_read_regs(struct mpu6xxx_device *dev, rt_uint8_t reg, rt_uint8_t len, rt_uint8_t *buf)
{
    rt_int8_t res = 0;
#ifdef RT_USING_I2C
    struct rt_i2c_msg msgs[2];
#endif
#ifdef RT_USING_SPI
    rt_uint8_t tmp;
#endif
    if (dev->bus->type == RT_Device_Class_I2CBUS)
    {
#ifdef RT_USING_I2C
        msgs[0].addr  = dev->i2c_addr;    /* Slave address */
        msgs[0].flags = RT_I2C_WR;        /* Write flag */
        msgs[0].buf   = ?             /* Slave register address */
        msgs[0].len   = 1;                /* Number of bytes sent */

        msgs[1].addr  = dev->i2c_addr;    /* Slave address */
        msgs[1].flags = RT_I2C_RD;        /* Read flag */
        msgs[1].buf   = buf;              /* Read data pointer */
        msgs[1].len   = len;              /* Number of bytes read */

        if (rt_i2c_transfer((struct rt_i2c_bus_device *)dev->bus, msgs, 2) == 2)
        {
            res = RT_EOK;
        }
        else
        {
            res = -RT_ERROR;
        }
#endif
    }
    else
    {
#ifdef RT_USING_SPI
        //The first bit of the first byte contains the Read/Write bit and indicates the Read (1) or Write (0) operation.
        tmp = reg | 0x80;

        res = rt_spi_send_then_recv((struct rt_spi_device *)dev->bus, &tmp, 1, buf, len);
#endif
    }
    return res;
}
写寄存器的bit位:

static rt_err_t mpu6xxx_write_bit(struct mpu6xxx_device *dev, rt_uint8_t reg, rt_uint8_t bit, rt_uint8_t data)
{
    rt_uint8_t byte;
    rt_err_t res;

    res = mpu6xxx_read_regs(dev, reg, 1, &byte);
    if (res != RT_EOK)
    {
        return res;
    }

    byte = (data != 0) ? (byte | (1 << bit)) : (byte & ~(1 << bit));

    return mpu6xxx_write_reg(dev, reg, byte);
}
读寄存器的bit位:

static rt_err_t mpu6xxx_read_bit(struct mpu6xxx_device *dev, rt_uint8_t reg, rt_uint8_t bit, rt_uint8_t *data)
{
    rt_uint8_t byte;
    rt_err_t res;

    res = mpu6xxx_read_regs(dev, reg, 1, &byte);
    if (res != RT_EOK)
    {
        return res;
    }

    *data = byte & (1 << bit);

    return RT_EOK;
}
写寄存器的多个bit位:

static rt_err_t mpu6xxx_write_bits(struct mpu6xxx_device *dev, rt_uint8_t reg, rt_uint8_t start_bit, rt_uint8_t len, rt_uint8_t data)
{
    rt_uint8_t byte, mask;
    rt_err_t res;

    res = mpu6xxx_read_regs(dev, reg, 1, &byte);
    if (res != RT_EOK)
    {
        return res;
    }

    mask = ((1 << len) - 1) << (start_bit - len + 1);
    data <<= (start_bit - len + 1); // shift data into correct position
    data &= mask; // zero all non-important bits in data
    byte &= ~(mask); // zero all important bits in existing byte
    byte |= data; // combine data with existing byte

    return mpu6xxx_write_reg(dev, reg, byte);
}
读寄存器的多个bit位:

static rt_err_t mpu6xxx_read_bits(struct mpu6xxx_device *dev, rt_uint8_t reg, rt_uint8_t start_bit, rt_uint8_t len, rt_uint8_t *data)
{
    rt_uint8_t byte, mask;
    rt_err_t res;

    res = mpu6xxx_read_regs(dev, reg, 1, &byte);
    if (res != RT_EOK)
    {
        return res;
    }

    mask = ((1 << len) - 1) << (start_bit - len + 1);
    byte &= mask;
    byte >>= (start_bit - len + 1);
    *data = byte;

    return RT_EOK;
}
获取加速度原始数据:

static rt_err_t mpu6xxx_get_accel_raw(struct mpu6xxx_device *dev, struct mpu6xxx_3axes *accel)
{
    rt_uint8_t buffer[6];
    rt_err_t res;

    res = mpu6xxx_read_regs(dev, MPU6XXX_RA_ACCEL_XOUT_H, 6, buffer);
    if (res != RT_EOK)
    {
        return res;
    }

    accel->x = ((rt_uint16_t)buffer[0] << 8) + buffer[1];
    accel->y = ((rt_uint16_t)buffer[2] << 8) + buffer[3];
    accel->z = ((rt_uint16_t)buffer[4] << 8) + buffer[5];

    return RT_EOK;
}
获取陀螺仪原始数据:

static rt_err_t mpu6xxx_get_gyro_raw(struct mpu6xxx_device *dev, struct mpu6xxx_3axes *gyro)
{
    rt_uint8_t buffer[6];
    rt_err_t res;

    res = mpu6xxx_read_regs(dev, MPU6XXX_RA_GYRO_XOUT_H, 6, buffer);
    if (res != RT_EOK)
    {
        return res;
    }

    gyro->x = ((rt_uint16_t)buffer[0] << 8) + buffer[1];
    gyro->y = ((rt_uint16_t)buffer[2] << 8) + buffer[3];
    gyro->z = ((rt_uint16_t)buffer[4] << 8) + buffer[5];

    return RT_EOK;
}
获取mpu6050内部温度传感器原始数据:

static rt_err_t mpu6xxx_get_temp_raw(struct mpu6xxx_device *dev, rt_int16_t *temp)
{
    rt_uint8_t buffer[2];
    rt_err_t res;

    res = mpu6xxx_read_regs(dev, MPU6XXX_RA_TEMP_OUT_H, 2, buffer);
    if (res != RT_EOK)
    {
        return res;
    }

    *temp = ((rt_uint16_t)buffer[0] << 8) + buffer[1];

    return RT_EOK;
}
获取mpu6050的配置参数:

static rt_err_t mpu6xxx_get_param(struct mpu6xxx_device *dev, enum mpu6xxx_cmd cmd, rt_uint16_t *param)
{
    rt_uint8_t data = 0;
    rt_err_t res = RT_EOK;

    RT_ASSERT(dev);

    switch (cmd)
    {
    case MPU6XXX_GYRO_RANGE:  /* Gyroscope full scale range */
        res = mpu6xxx_read_bits(dev, MPU6XXX_RA_GYRO_CONFIG, MPU6XXX_GCONFIG_FS_SEL_BIT, MPU6XXX_GCONFIG_FS_SEL_LENGTH, &data);
        *param = data;
        break;
    case MPU6XXX_ACCEL_RANGE: /* Accelerometer full scale range */
        res = mpu6xxx_read_bits(dev, MPU6XXX_RA_ACCEL_CONFIG, MPU6XXX_ACONFIG_AFS_SEL_BIT, MPU6XXX_ACONFIG_AFS_SEL_LENGTH, &data);
        *param = data;
        break;
    case MPU6XXX_DLPF_CONFIG: /* Digital Low Pass Filter */
        res = mpu6xxx_read_bits(dev, MPU6XXX_RA_CONFIG, MPU6XXX_CFG_DLPF_CFG_BIT, MPU6XXX_CFG_DLPF_CFG_LENGTH, &data);
        *param = data;
        break;
    case MPU6XXX_SAMPLE_RATE: /* Sample Rate */
        /* Sample Rate = Gyroscope Output Rate / (1 + SMPLRT_DIV) */
        res = mpu6xxx_read_bits(dev, MPU6XXX_RA_CONFIG, MPU6XXX_CFG_DLPF_CFG_BIT, MPU6XXX_CFG_DLPF_CFG_LENGTH, &data);
        if (res != RT_EOK)
        {
            break;
        }

        if (data == 0 || data == 7) /* dlpf is disable */
        {
            res = mpu6xxx_read_regs(dev, MPU6XXX_RA_SMPLRT_DIV, 1, &data);
            *param = 8000 / (data + 1);
        }
        else /* dlpf is enable */
        {
            res = mpu6xxx_read_regs(dev, MPU6XXX_RA_SMPLRT_DIV, 1, &data);
            *param = 1000 / (data + 1);
        }
        break;
    case MPU6XXX_SLEEP: /* sleep mode */
        res = mpu6xxx_read_bit(dev, MPU6XXX_RA_PWR_MGMT_1, MPU6XXX_PWR1_SLEEP_BIT, &data);
        *param = data;
        break;
    }

    return res;
}
配置mpu6050参数:

rt_err_t mpu6xxx_set_param(struct mpu6xxx_device *dev, enum mpu6xxx_cmd cmd, rt_uint16_t param)
{
    rt_uint8_t data = 0;
    rt_err_t res = RT_EOK;

    RT_ASSERT(dev);

    switch (cmd)
    {
    case MPU6XXX_GYRO_RANGE:  /* Gyroscope full scale range */
        res = mpu6xxx_write_bits(dev, MPU6XXX_RA_GYRO_CONFIG, MPU6XXX_GCONFIG_FS_SEL_BIT, MPU6XXX_GCONFIG_FS_SEL_LENGTH, param);
        dev->config.gyro_range = param;
        break;
    case MPU6XXX_ACCEL_RANGE: /* Accelerometer full scale range */
        res = mpu6xxx_write_bits(dev, MPU6XXX_RA_ACCEL_CONFIG, MPU6XXX_ACONFIG_AFS_SEL_BIT, MPU6XXX_ACONFIG_AFS_SEL_LENGTH, param);
        dev->config.accel_range = param;
        break;
    case MPU6XXX_DLPF_CONFIG: /* Digital Low Pass Filter */
        res = mpu6xxx_write_bits(dev, MPU6XXX_RA_CONFIG, MPU6XXX_CFG_DLPF_CFG_BIT, MPU6XXX_CFG_DLPF_CFG_LENGTH, param);
        break;
    case MPU6XXX_SAMPLE_RATE: /* Sample Rate = 16-bit unsigned value.
                                 Sample Rate = [1000 -  4]HZ when dlpf is enable
                                 Sample Rate = [8000 - 32]HZ when dlpf is disable */

        //Sample Rate = Gyroscope Output Rate / (1 + SMPLRT_DIV)
        res = mpu6xxx_read_bits(dev, MPU6XXX_RA_CONFIG, MPU6XXX_CFG_DLPF_CFG_BIT, MPU6XXX_CFG_DLPF_CFG_LENGTH, &data);
        if (res != RT_EOK)
        {
            break;
        }

        if (data == 0 || data == 7) /* dlpf is disable */
        {
            if (param > 8000)
                data = 0;
            else if (param < 32)
                data = 0xFF;
            else
                data = 8000 / param - 1;
        }
        else /* dlpf is enable */
        {
            if (param > 1000)
                data = 0;
            else if (param < 4)
                data = 0xFF;
            else
                data = 1000 / param - 1;
        }
        res = mpu6xxx_write_reg(dev, MPU6XXX_RA_SMPLRT_DIV, data);
        break;
    case MPU6XXX_SLEEP: /* Configure sleep mode */
        res = mpu6xxx_write_bit(dev, MPU6XXX_RA_PWR_MGMT_1, MPU6XXX_PWR1_SLEEP_BIT, param);
        break;
    }

    return res;
}
获取加速度值:

rt_err_t mpu6xxx_get_accel(struct mpu6xxx_device *dev, struct mpu6xxx_3axes *accel)
{
    struct mpu6xxx_3axes tmp;
    rt_uint16_t sen;
    rt_err_t res;

    res = mpu6xxx_get_accel_raw(dev, &tmp);
    if (res != RT_EOK)
    {
        return res;
    }

    sen = MPU6XXX_ACCEL_SEN >> dev->config.accel_range;

    accel->x = (rt_int32_t)tmp.x * 1000 / sen;
    accel->y = (rt_int32_t)tmp.y * 1000 / sen;
    accel->z = (rt_int32_t)tmp.z * 1000 / sen;

    return RT_EOK;
}
获取陀螺仪数据:

rt_err_t mpu6xxx_get_gyro(struct mpu6xxx_device *dev, struct mpu6xxx_3axes *gyro)
{
    struct mpu6xxx_3axes tmp;
    rt_uint16_t sen;
    rt_err_t res;

    res = mpu6xxx_get_gyro_raw(dev, &tmp);
    if (res != RT_EOK)
    {
        return res;
    }

    sen = MPU6XXX_GYRO_SEN >> dev->config.gyro_range;

    gyro->x = (rt_int32_t)tmp.x * 100 / sen;
    gyro->y = (rt_int32_t)tmp.y * 100 / sen;
    gyro->z = (rt_int32_t)tmp.z * 100 / sen;

    return RT_EOK;
}
获取温度:

rt_err_t mpu6xxx_get_temp(struct mpu6xxx_device *dev, float *temp)
{
    rt_int16_t tmp;
    rt_err_t res;

    res = mpu6xxx_get_temp_raw(dev, &tmp);
    if (res != RT_EOK)
    {
        return res;
    }

    if (dev->id == MPU6050_WHO_AM_I)
    {
        /* mpu60x0: Temperature in degrees C = (TEMP_OUT Register Value as a signed quantity)/340 + 36.53 */
        *temp = (double)tmp / MPU60X0_TEMP_SEN + MPU60X0_TEMP_OFFSET;
    }
    else
    {
        /* mpu6500:  ((TEMP_OUT - RoomTemp_Offset)/Temp_Sensitivity)+ 21degC */
        *temp = (double)tmp / MPU6500_TEMP_SEN + MPU6500_TEMP_OFFSET;
    }

    return RT_EOK;
}
mpu6050初始化:

struct mpu6xxx_device *mpu6xxx_init(const char *dev_name, rt_uint8_t param)
{
    struct mpu6xxx_device *dev = RT_NULL;
    rt_uint8_t reg = 0xFF, res = RT_EOK;

    RT_ASSERT(dev_name);

    dev = rt_calloc(1, sizeof(struct mpu6xxx_device));
    if (dev == RT_NULL)
    {
        LOG_E("Can't allocate memory for mpu6xxx device on '%s' ", dev_name);
        goto __exit;
    }

    dev->bus = rt_device_find(dev_name);
    if (dev->bus == RT_NULL)
    {
        LOG_E("Can't find device:'%s'", dev_name);
        goto __exit;
    }

    if (dev->bus->type == RT_Device_Class_I2CBUS)
    {
        if (param != RT_NULL)
        {
            dev->i2c_addr = param;
        }
        else
        {
            /* find mpu6xxx device at address: 0x68 */
            dev->i2c_addr = MPU6XXX_ADDRESS_AD0_LOW;
            if (mpu6xxx_read_regs(dev, MPU6XXX_RA_WHO_AM_I, 1, ?) != RT_EOK)
            {
                /* find mpu6xxx device at address 0x69 */
                dev->i2c_addr = MPU6XXX_ADDRESS_AD0_HIGH;
                if (mpu6xxx_read_regs(dev, MPU6XXX_RA_WHO_AM_I, 1, ?) != RT_EOK)
                {
                    LOG_E("Can't find device at '%s'!", dev_name);
                    goto __exit;
                }
            }
            LOG_D("Device i2c address is:'0x%x'!", dev->i2c_addr);
        }
    }
    else if (dev->bus->type == RT_Device_Class_SPIDevice)
    {
#ifdef RT_USING_SPI
        struct rt_spi_configuration cfg;

        cfg.data_width = 8;
        cfg.mode = RT_SPI_MASTER | RT_SPI_MODE_0 | RT_SPI_MSB;
        cfg.max_hz = MPU60X0_SPI_MAX_SPEED; /* Set spi max speed */

        rt_spi_configure((struct rt_spi_device *)dev->bus, &cfg);
#endif
    }
    else
    {
        LOG_E("Unsupported device:'%s'!", dev_name);
        goto __exit;
    }

    if (mpu6xxx_read_regs(dev, MPU6XXX_RA_WHO_AM_I, 1, ?) != RT_EOK)
    {
        LOG_E("Failed to read device id!");
        goto __exit;
    }

    dev->id = reg;

    switch (dev->id)
    {
    case MPU6050_WHO_AM_I:
        LOG_I("Find device: mpu6050!");
        break;
    case MPU6500_WHO_AM_I:
        LOG_I("Find device: mpu6500!");
        break;
    case MPU9250_WHO_AM_I:
        LOG_I("Find device: mpu9250!");
        break;
    case ICM20608G_WHO_AM_I:
    case ICM20608D_WHO_AM_I:
        LOG_I("Find device: icm20608!");
        break;
    case 0xFF:
        LOG_E("No device connection!");
        goto __exit;
    default:
        LOG_W("Unknown device id: 0x%x!", reg);
    }

    res += mpu6xxx_get_param(dev, MPU6XXX_ACCEL_RANGE, &dev->config.accel_range);
    res += mpu6xxx_get_param(dev, MPU6XXX_GYRO_RANGE, &dev->config.gyro_range);

    res += mpu6xxx_write_bits(dev, MPU6XXX_RA_PWR_MGMT_1, MPU6XXX_PWR1_CLKSEL_BIT, MPU6XXX_PWR1_CLKSEL_LENGTH, MPU6XXX_CLOCK_PLL_XGYRO);
    res += mpu6xxx_set_param(dev, MPU6XXX_GYRO_RANGE, MPU6XXX_GYRO_RANGE_250DPS);
    res += mpu6xxx_set_param(dev, MPU6XXX_ACCEL_RANGE, MPU6XXX_ACCEL_RANGE_2G);
    res += mpu6xxx_set_param(dev, MPU6XXX_SLEEP, MPU6XXX_SLEEP_DISABLE);

#ifdef PKG_USING_MPU6XXX_MAG
    mpu6xxx_write_reg(dev, MPU6XXX_RA_USER_CTRL, 0x20);
    mpu92_mag_write_reg(dev, AK8963_REG_CNTL2, 0x01);      /* [0]  Reset Device                  */
    rt_thread_mdelay(1);
    mpu92_mag_write_reg(dev, AK8963_REG_CNTL1, 0x00);      /* [1]  Power-down mode               */
    mpu92_mag_write_reg(dev, AK8963_REG_CNTL1, 0x0F);      /* [2]  Fuse ROM access mode          */
    mpu92_mag_write_reg(dev, AK8963_REG_CNTL1, 0x00);      /* [3]  Power-down mode               */
    rt_thread_mdelay(1);    // 100us
    mpu92_mag_write_reg(dev, AK8963_REG_CNTL1, 0x16);      /* [4]  16bits and Continuous measurement mode 2 */

    /* config mpu9250 i2c */
    rt_thread_mdelay(2);
    mpu6xxx_write_reg(dev, MPU6XXX_RA_I2C_MST_CTRL, 0x5D);
    rt_thread_mdelay(2);
    mpu6xxx_write_reg(dev, MPU6XXX_RA_I2C_SLV0_ADDR, AK8963_I2C_ADDR | 0x80);
    rt_thread_mdelay(2);
    mpu6xxx_write_reg(dev, MPU6XXX_RA_I2C_SLV0_REG, AK8963_REG_ST1);
    rt_thread_mdelay(2);
    mpu6xxx_write_reg(dev, MPU6XXX_RA_I2C_SLV0_CTRL, MPU6500_I2C_SLVx_EN | 8);
    rt_thread_mdelay(2);
    mpu6xxx_write_reg(dev, MPU6XXX_RA_I2C_SLV4_CTRL, 0x09);
    rt_thread_mdelay(2);
    mpu6xxx_write_reg(dev, MPU6XXX_RA_I2C_MST_DELAY_CTRL, 0x81);
#endif

    if (res == RT_EOK)
    {
        LOG_I("Device init succeed!");
    }
    else
    {
        LOG_W("Error in device initialization!");
    }
    return dev;

__exit:
    if (dev != RT_NULL)
    {
        rt_free(dev);
    }
    return RT_NULL;
}


7
点赞|  楼主 | 2025-7-27 21:36 | 只看该作者
效果验证:
在串口调试工具,输入:
8
点赞|  楼主 | 2025-7-27 21:50 | 只看该作者
效果验证:
在串口调试工具,输入:
mpu6xxx_test
会打印mpu6050的加速度和陀螺仪数据如下:

3136868862bbe2bf6d.png (73.36 KB )

3136868862bbe2bf6d.png
9
ShimmeringDawn| | 2025-7-28 11:37 | 只看该作者
老哥求例程
10
fanzq2005| | 2025-7-28 19:38 | 只看该作者
谢谢分享,大家一起进步~!谢谢分享,大家一起进步~!
11
魔法森林精灵| | 2025-8-1 12:00 | 只看该作者
MPU6050的数据融合技术确实在很多领域都有应用,特别是在需要精确姿态控制的场合。
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

4

主题

19

帖子

0

粉丝
venes保温杯是什么品牌 什么食物好消化 中子是什么 什么东西越洗越脏 足内翻是什么样子的
卡罗莱手表是什么档次 慢慢张开你的眼睛是什么歌的歌词 darling是什么意思 两个土念什么 全血粘度低切偏高是什么意思
惨烈是什么意思 作奸犯科是什么意思 星巴克是什么 为什么割包皮 撕漫男什么意思
小孩肠胃感冒吃什么药比较好 小孩脚底脱皮是什么原因造成的 十二生肖本领强是什么生肖 摘环后需要注意什么 白内障什么症状
6月18日是什么星座0297y7.com 钧五行属什么hcv7jop6ns6r.cn 豆汁什么味道hcv8jop1ns9r.cn 食禄痣是什么意思hcv9jop1ns9r.cn 为什么不说话96micro.com
喝什么水好啊hcv9jop2ns7r.cn 梅花什么时候开hcv7jop4ns8r.cn 父亲的弟弟叫什么hcv8jop5ns7r.cn 猪儿虫是什么意思hcv9jop7ns4r.cn 谝是什么意思hcv8jop0ns9r.cn
什么门不能开hcv7jop9ns7r.cn 阅读有什么好处qingzhougame.com 皮肤晒伤用什么药inbungee.com 日语为什么怎么说mmeoe.com min是什么hcv9jop5ns8r.cn
网球肘吃什么药sanhestory.com 不想吃油腻的东西是什么原因hcv8jop7ns7r.cn 花是什么意思hanqikai.com 宝字五行属什么hcv8jop9ns1r.cn 颇丰是什么意思hcv8jop0ns6r.cn
百度