小孩老是咬手指甲是什么原因| 术语是什么意思| 生抽和老抽有什么区别| 1978年属马五行属什么| 尿潜血弱阳性是什么意思| h1什么意思| 高密度脂蛋白高是什么原因| 癫痫病是什么原因引起的| 12583是什么电话| 八股是什么意思| 梦见自己大肚子快生了是什么意思| 建日是什么意思| 什么是公历年份| 亚甲炎是什么病| 吃了螃蟹后不能吃什么| 突然晕厥是什么原因| 火是什么意思| 空调开不了机是什么原因| 镇长属于什么级别| 寒湿重吃什么药| 头顶疼是什么原因引起的| 白袜子是什么意思| 肾上腺结节挂什么科| 吃什么去肝火| 肺ca是什么病| 属马的本命佛是什么佛| 六七是什么意思| 什么情况| 头顶长白头发是什么原因造成的| 为什么眼皮会肿| 胸部b超挂什么科| 骆驼趾是什么意思| 自我感动是什么意思| 甲钴胺治疗什么病| 耳前瘘管有什么危害| 蜈蚣吃什么食物| 什么是静息心率| 精神紊乱吃什么药| 什么火锅最好吃| 包罗万象是什么意思| 白带过氧化氢阳性什么意思| 吃完榴莲后不能吃什么| 腊肉炒什么菜好吃| 观音菩萨成道日是什么意思| 膝盖后面叫什么部位| 什么的朋友| 湛蓝湛蓝的什么| 肢体麻木是什么原因| 如泰山前面一个字是什么啊| 1954年属什么生肖| 什么食物蛋白质含量高| 2月23日什么星座| 硝是什么东西| 胃炎吃什么中药效果好| 没有精液是什么原因| 什么粉一沾就痒还看不出来| 名节是什么意思| 县公安局局长是什么级别| LOP是什么胎位| nt是什么币| 脚底长水泡是什么原因| 乙肝抗体是什么意思| 什么食物含碘高| 晚上剪指甲有什么禁忌| 但愿人长久的下一句是什么| 金命适合什么颜色| 为什么肠道总是咕咕的响| 白带有腥味是什么原因| 肛门瘙痒是什么问题| 香蕉为什么不能放冰箱| 金钱龟吃什么食物| 测血型挂什么科| 姊妹是什么意思| 治疗晕病有什么好方法| 小孩长白头发是什么原因| 附带是什么意思| 失眠吃什么药| 血象高是什么原因| 三点水一个前读什么| 刚出生的小鱼苗吃什么| 什么叫网红| 曹操属什么| 儿童肠胃感冒吃什么药效果好| 口腔异味吃什么药| 井柏然原名叫什么| 尿胆原normal是什么意思| 什么是钝角| 荷叶茶有什么作用| hys是什么意思| 吃什么可以回奶| 善待是什么意思| 朔日是什么意思| 双子座是什么时候| 呕吐是什么原因引起的| 观音菩萨成道日是什么意思| 尿分叉吃什么药能治好| 手指甲出现竖纹是什么原因| 高粱是什么颜色| 06年属狗的是什么命| 乳头经常痒是什么原因| 晦气是什么意思| 高中学考是什么意思| 玉兰片和竹笋有什么区别| 珉字五行属什么| 高铁为什么没有e| 办理户口迁移需要什么材料| 吃葡萄对身体有什么好处| 俊俏什么意思| amh是什么检查项目| svc是什么意思| 测幽门螺旋杆菌挂什么科| 脚踝水肿是什么原因| 易建联为什么不打nba| 相敬如宾什么意思| 绿壳鸡蛋是什么鸡生的| 猫咪能吃什么水果| 结晶体是什么意思| 凌波仙子指的是什么花| 胸小是缺少什么营养| 什么是平舌音什么是翘舌音| 拉肚子可以喝什么饮料| 1009是什么星座| 舒张压是什么意思| 盆腔炎吃什么药最好| 月经为什么推迟不来| ntd是什么意思| 拧巴是什么意思| 垚字是什么意思| 西湖醋鱼是什么鱼| 为什么会得神经性皮炎| 什么护肤产品补水最好| 脚跟痛什么原因| 玟字五行属什么| 肠粘连吃什么药| 睡醒头疼是什么原因| 睾丸疼痛什么原因| 红细胞压积偏高是什么意思| trc是什么意思| 什么菜可以隔夜吃| 老是肚子饿是什么原因| 集成灶什么品牌最好| 脸上发痒是什么原因| 最多笔画的汉字是什么| 肝素是什么| 凝望什么| 肾虚是什么原因引起的| 什么长而什么| 什么是主动脉夹层| 文气是什么意思| sg是什么意思| 什么地听| 花仙子是什么意思| 马齿苋吃了有什么好处| 痛风不能喝什么饮料| 应接不暇的暇是什么意思| 仲夏夜是什么意思| 老头疼是什么原因导致的| 盆腔积液吃什么消炎药| 三七甘一是什么意思| 过敏性鼻炎用什么药效果最好| 胃大肚子大是什么原因| 妇科检查白细胞酯酶阳性是什么意思| 什么鸣什么吠| 贫血吃什么补血最快| 治疗幽门螺旋杆菌用什么药| 乌鸡蛋是什么颜色| 闹心是什么意思啊| 癞皮狗是什么意思| 房颤吃什么药| 红酒配什么菜| 舌苔发白是什么病的前兆| 脱水有什么症状| 年柱金舆是什么意思| 琪字五行属什么| 偏光太阳镜是什么意思| 感冒了吃什么饭菜合适| 翻来覆去是什么意思| 新生儿超敏c反应蛋白高说明什么| 什么叫闭经| 业力是什么| 葡萄像什么比喻句| 长期口臭吃什么药| 血小板高是什么原因| 病理科是干什么的| 玉溪烟属于什么档次| 7.22是什么星座| 湿疹是什么样的症状| 世界上最长的蛇是什么| 甲状腺检查挂什么科| 甲状腺是什么意思| 书记处书记是什么级别| 药物过敏挂什么科| 内分泌失调是什么意思| 胃疼挂什么科| 下巴脖子长痘痘是什么原因| 九月十三号是什么星座| 山竹什么样的好| 葡萄糖属于什么糖| 宰相是现在的什么官| 座山雕什么意思| 髋关节积液是什么原因造成的| 凤眼果什么时候成熟| 孔雀开屏是什么行为| 颈椎病头晕吃什么药好| 辩证思维是什么意思| 梦见已故的父母是什么兆头| 蛤读什么| 公安局局长是什么级别| 来月经期间吃什么最好| 托马斯是什么意思| 血压不稳定是什么原因| 为什么微信附近的人看不到我| 孤单的反义词是什么| 低血压吃什么药效果好| 急得很什么| 梦见被雷劈什么意思| 女生被口是什么感觉| 什么叫滑精| 做梦怀孕了是什么意思| 嗜酸性气道炎症是什么意思| 吃什么减脂肪| 吃降压药有什么副作用| 副处级干部是什么级别| 湿疹是因为什么原因引起的| 喝酒眼睛红是什么原因| 上海有什么好玩的地方适合小孩子| 流清水鼻涕是什么感冒| 四面楚歌是什么意思| 平板和ipad有什么区别| 嘴发酸是什么原因引起| 肾阳不足吃什么中成药| 南音是什么意思| 什么是软装| 被动是什么意思| 蚁后长什么样| 高铁二等座是什么意思| 蜗牛的触角有什么作用| 双红出彩是什么生肖| 血糖高有什么表现| 林俊杰为什么不结婚| 淋巴细胞高是什么原因| 纳气是什么意思| 什么散步填词语| 中位数是什么| 咖啡加奶叫什么| mcg是什么意思| 痔疮挂什么科室| 心机什么意思| 肝浸润是什么意思| 人工降雨的原理是什么| 口干口苦口臭是什么原因| 什么叫囊肿| 先河是什么意思| 非那根又叫什么| 女人梦见狗是什么预兆| 冠脉ct能检查出什么| 被紫外线灯照到有什么后果呀| 征信对个人有什么影响| 血脂高吃什么油| 叶脉是什么| 责成是什么意思| 高考考生号是什么| 困境是什么意思| 小腿怕冷是什么原因| 百度
打印
[RISC-V MCU 应用开发]

A股市场再现举牌事件 华豚企业举牌爱建集团拟

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

粉丝
毛囊炎是什么样子 玉树临风是什么意思 子午相冲是什么意思 国民党为什么会失败 梦见种菜是什么意思
这个季节吃什么水果最好 髋关节弹响是什么原因 袁绍和袁术是什么关系 痛风什么引起的原因有哪些 胃肠镜能检查出什么病
手指肚发红是什么原因 嫌恶是什么意思 家五行属性是什么 肝回声改变是什么意思 什么人容易得脑梗
1975属什么生肖 反流性食管炎b级是什么意思 湿气重吃什么药好 喝酒胃出血吃什么药 黄瓜敷脸有什么功效
舌尖发麻是什么原因hcv8jop7ns9r.cn 女性吃什么改善更年期hcv8jop5ns3r.cn 手脱皮用什么药好得快hcv7jop4ns8r.cn 检查hpv需要注意什么提前注意什么hcv9jop2ns5r.cn 生存是什么意思hcv9jop5ns0r.cn
白色的玉是什么玉hcv9jop1ns4r.cn 冰箱发烫是什么原因hcv9jop1ns0r.cn 阴人是什么意思baiqunet.com 白蛋白低吃什么补得快hcv9jop8ns3r.cn 吃什么补内膜最快hcv7jop6ns4r.cn
传导阻滞是什么意思hcv9jop3ns9r.cn 甲状腺功能挂什么科hcv8jop9ns5r.cn 医院可以点痣吗挂什么科hcv7jop4ns7r.cn 开塞露用多了有什么副作用tiangongnft.com 泪崩是什么意思hcv9jop6ns9r.cn
麻薯粉是什么粉hcv7jop5ns0r.cn 尿道感染流脓吃什么药cl108k.com prc是什么意思hcv7jop9ns3r.cn 梦见红棺材是什么征兆hcv9jop6ns6r.cn 西施是什么生肖hcv7jop4ns7r.cn
百度