什么是活珠子| 什么的腊梅| darling什么意思| 月经头疼是什么原因| 文理分科什么时候开始| 心脏房颤吃什么药最好| 卡马西平片是什么药| ra是什么| 大腿根部痛是什么原因| 血小板偏低是什么意思| 修为是什么意思| 甘油三酯高是什么病| 疱疹有什么症状表现| 什么硬币最值钱| 梦见骨灰盒是什么征兆| 乌鸡蛋什么颜色| 地壳是什么| 乙肝表面抗体阳性什么意思| 18kgp是什么金| 新生儿感冒是什么症状| 学医需要什么条件| 什么是头寸| 不作为是什么意思| ao是什么| 丝绦是什么意思| 嗜酸性粒细胞偏低是什么意思| 1954属什么生肖| 2001年是什么命| 嚷能组什么词| 胃不好的人吃什么养胃| kms是什么意思| 属相鸡与什么属相相合| 要不然是什么意思| 左眼皮跳代表什么| 胳膊上的花是打了什么疫苗| 下肢动脉硬化吃什么药| 微波炉不热是什么原因| 11月10号是什么星座| 厨娘是什么意思| 小孩睡觉张开嘴巴是什么原因| 复方氨酚烷胺片是什么药| 降结肠疼是什么原因| 白凉粉是什么做的| slay什么意思| 膝盖缝里面疼什么原因| 一抽一抽的打嗝叫什么| 5s是什么| 望远镜什么牌子好| 天上的星星为什么会发光| 寒露是什么季节| 胃不好吃什么药| 贲门炎吃什么药| 晚上看见黄鼠狼有什么预兆| 尿潜血1十是什么原因| 心理健康是什么| fdg是什么意思| 胃火重口臭吃什么药好| sanag是什么牌子| 午马是什么意思| 为什么叫基围虾| 随心而欲是什么意思| 戴玉有什么好处| 石榴什么时候成熟| 九月初三是什么星座| 胃溃疡吃什么药好得快| 六六大顺是什么生肖| 男性长期熬夜吃什么好| cartoon什么意思| 警察代表什么生肖| 磨砂膏是什么| 5月22号是什么星座| 阿尔茨海默症是什么病| 皱褶什么意思| 愤青是什么意思| 就读是什么意思| 二月份出生的是什么星座| 乙肝两对半定量是什么意思| 莲雾是什么| 罢免是什么意思| premier是什么牌子| 什么叫做缘分| 耳朵旁边长痘痘是什么原因| 尿频吃什么药效果最好| 高血糖吃什么药| 大便不规律是什么原因| 食管反流吃什么药最好| 什么是化石| 尿等待吃什么药最好| 胰腺上长瘤意味着什么| 补充微量元素吃什么| 减肥有什么方法| 囟门凹陷是什么原因| 生性多疑是什么意思| 派出所传唤是什么意思| 半干型黄酒是什么意思| 素毛肚是什么做的| 女人月经总是提前是什么原因| 金酒兑什么好喝| 新生儿屁多是什么原因| 牛肚是什么| 你为什么不说话歌词| tid是什么意思| 眼尖什么意思| 肺炎吃什么药| 垂爱是什么意思| 急性呼吸道感染是什么引起的| 积食吃什么食物帮助消化| 甲状腺查什么| 不什么不什么| 韩语阿西吧是什么意思| 拉肚子吃什么益生菌| AMI是什么病| 胆囊腺肌症是什么病| 本来无一物何处惹尘埃什么意思| 龙的三合生肖是什么| 知见是什么意思| 缓刑是什么意思| 杏花代表什么生肖| 什么的绽放| 姑婆的儿子叫什么| 金银花不能和什么一起吃| 肝脏钙化灶什么意思| 今年为什么闰六月| 一什么便什么造句| 什么叫血氧| 病灶是什么意思| 腺肌症是什么原因引起的| 手抽筋是什么原因| 小县城适合做什么生意| 乳腺结节和乳腺增生有什么区别| 烧仙草是什么东西| 花嫁是什么意思| 私处痒用什么药| 中意你是什么意思| 鱼水之欢是什么意思| 二氧化硅是什么| 什么是逻辑思维| 宫颈lsil是什么意思| 卫生间除臭用什么最好| 白玫瑰适合送什么人| 顶礼是什么意思| 洗衣粉和洗衣液有什么区别| 出片是什么意思| 阴虚和阳虚有什么区别的症状| 自汗是什么意思| 三轮体空什么意思| 中性粒细胞是什么| 吃了饭胃胀是什么原因| 固本培元是什么意思| 药物流产吃什么药| 下巴长痘痘用什么药| 什么情况会导致月经推迟不来| 技校是什么| 开火车什么意思| 为什么手淫很快就射| 上将相当于什么级别| 人参吃了有什么好处| alpha是什么意思| 扁桃体炎吃什么药最好| 惨无人道是什么意思| 鸡块炖什么好吃| 金牛女跟什么星座最配| 水军什么意思| 吹空调咳嗽是什么原因| rh血型阴性是什么意思| 0604是什么日子| 虚岁24岁属什么生肖| 彩虹旗是什么意思| 紫癜是一种什么病严重吗| 线雕是什么| 开五行属什么| 吃什么补铁快| 治前列腺炎吃什么药效果最好| 肺在五行中属什么| 阴虚便秘吃什么中成药| 空腹血糖高吃什么药| jeep是什么牌子| 腋下出汗多是什么原因| 鲁智深的绰号是什么| 绿对什么| 桃花开在什么季节| 大年初一是什么星座| 梦见摘豆角是什么预兆| 透疹是什么意思| 减肥期间适合吃什么| 为什么汤泡饭对胃不好| 如期而至是什么意思| hyper是什么意思| 印度是什么制度的国家| 小孩缺锌有什么症状| 被男人操是什么感觉| 慢性非萎缩性胃炎伴糜烂是什么意思| 头发长得快是什么原因| vdr是什么意思| 吃什么都是苦的是怎么回事| 被交警开罚单不交有什么后果| 止血敏又叫什么名| 黄体功能不足是什么原因造成的| 月经稀发是什么意思| 黄色分泌物是什么原因| 男人容易出汗是什么原因造成的| ram是什么动物| 十月二十五是什么星座| 女人腰椎疼是什么原因| 今天有什么新闻| 过敏用什么药膏| 1965年属什么| 肾积水是什么原因引起的| 锌补多了有什么症状| 什么时候高速免费| 邓紫棋和华晨宇什么关系| 甲功三项是什么| 白细胞增多是什么原因| 下午四五点是什么时辰| 寻常疣是什么样子图片| 清明节与什么生肖有关| 子婴是秦始皇什么人| 吃了狗肉不能吃什么| 小孩不说话什么原因| 核桃和什么一起打豆浆| 震楼神器楼上什么感觉| hz是什么意思| 腱鞘炎用什么药治疗| 长期失眠应该吃什么药| 巧克力的原料是什么| 静态纹用什么除皱| 科颜氏属于什么档次| 上颚痒是什么原因| 干黄酱是什么酱| 胃阳不足吃什么中成药| 又字加一笔是什么字| 慰藉是什么意思| 大便失禁是什么原因造成的| 头发掉要用什么洗发水| 黑卡是什么意思| 印代表什么| 眼疖子用什么药| 方解石玉是什么玉| 为什么会有蟑螂| 什么原因会导致月经推迟| 桂鱼吃什么食物| ga是什么激素| 翻新机是什么意思| 1.16是什么星座| 高硼硅是什么材质| x是什么牌子的衣服| 榨菜是什么菜| 压测是什么意思| 耳鼻喉科主要看什么病| 胸闷气短挂什么科| 后羿和嫦娥是什么关系| 空调不热是什么原因| 噫气是什么意思| 中国第一艘航空母舰叫什么| 双休什么意思| 开学买什么| 甲亢是一种什么病严重吗| 推介会是什么意思| 碳水化合物指的是什么食物| 舌头有齿痕是什么原因| 补气血吃什么食物| 一诺千金什么意思| 降血糖吃什么| 孩子嗓子有痰吃什么药| 百度
打印
[RISC-V MCU 应用开发]

新华网浙江频道专题报道

[复制链接]
636|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

粉丝
吃了虾不能吃什么水果 直肠给药对小孩身体有什么影响 腹胀吃什么药 彼岸花开是什么意思 健脾祛湿吃什么中成药
果五行属什么 天蝎座和什么星座最配 常态是什么意思 甘耳朵旁什么字 手脚发麻什么原因
经常拉肚子吃什么药好 感冒吃什么食物 尿检阴性是什么意思 艾滋病初期皮疹是什么样的 什么的小花
属羊的和什么属相最配 ab和b型血生的孩子是什么血型 老八是什么意思 减肥晚饭吃什么好 办护照需要准备什么材料
做梦吃酒席什么预兆fenrenren.com 胃出血有什么症状表现hcv7jop6ns4r.cn 计提工资是什么意思hcv9jop7ns5r.cn 弯弯的什么hcv8jop2ns5r.cn 张辽字什么hcv9jop5ns3r.cn
用什么泡脚好hcv9jop4ns1r.cn 什么叫高血压beikeqingting.com 瓜皮什么意思hcv9jop5ns9r.cn ua是什么hcv8jop1ns7r.cn 潘驴邓小闲是什么意思hcv9jop1ns0r.cn
子宫内膜炎有什么症状hcv7jop5ns5r.cn 梦见拖地是什么意思hcv8jop8ns3r.cn 夏天适合吃什么食物jasonfriends.com 网罗是什么意思hcv7jop6ns5r.cn 窝是什么结构的字hcv8jop8ns7r.cn
大腿根内侧发黑是什么原因hebeidezhi.com 为什么要小心AB型血的人helloaicloud.com 手汗症是什么原因hcv8jop4ns9r.cn qn是什么医嘱hcv9jop7ns3r.cn 经期能吃什么水果gangsutong.com
百度