模块学习(二)——MPU6050

发布者:EtherealBeauty最新更新时间:2022-08-09 来源: csdn关键字:MPU6050 手机看文章 扫描二维码
随时随地手机看文章

去年电赛备赛期间,学的STM32标准库,那一整个繁琐直接给我劝退了,当时学习MPU6050时就非常痛苦,代码也看不懂,无非抄来抄去,然后就是编译,改错,编译无穷尽也。最近参考野火的MPU6050代码,将其移植到了MSP430f5529之上,今天分享出来。


1.重要性

MPU6050模块对于不论平衡车还是四旋翼无人机的开发都是非常重要的一个模块,除此之外,对于四轮小车的转弯闭环控制也是至关重要的,因此备战电赛控制类这是一个不可避开的模块。该模块包含陀螺仪和加速度传感器,可以解算出其x,y,z三个方向的角度和各个方向的角速度,使用十分方便,此次并未采用官方的DMP库。


2.代码

废话不多说,直接上代码,调用即可。


/*

 * MPU6050.c

 *

 *  Created on: 2022年7月17日

 *      Author: S10

 */

#include "driverlib.h"

#include "mpu6050.h"


void ByteWrite6050(unsigned char REG_Address,unsigned char REG_data);

unsigned char ByteRead6050(unsigned char REG_Address);

int Get6050Data(unsigned char REG_Address);

void InitMPU6050();

float Mpu6050AccelAngle(char dir);

float Mpu6050GyroAngle(char dir);


///开启信号

void IIC_start()

{

    SDA_OUT;

    SCL_OUT;

    SCL_HIGH;

    SDA_HIGH;

    __delay_cycles(10);

    SDA_LOW;

    __delay_cycles(10);

    SCL_LOW;

}

///停止信号

void IIC_stop()

{

    SDA_OUT;

    SCL_OUT;

    SDA_LOW;

    SCL_HIGH;

    __delay_cycles(10);

    SDA_HIGH;

    __delay_cycles(10);

}



//发送应答信号(MCU=>||)

void SendACK(unsigned char ack)

{

    SDA_OUT;

    SCL_OUT;

    if(ack==1)

    {

        SDA_HIGH;

    }

    else if(ack==0)

    {

        SDA_LOW;

    }

    else

        return;

    SCL_HIGH;

    __delay_cycles(10);

    SCL_LOW;

    __delay_cycles(10);

}

接收应答信号(||=>MCU)

unsigned char IIC_testACK()

{

    unsigned char a;

    SCL_OUT;

    SDA_IN;

//GPIO_setAsInputPinWithPullUpResistor (GPIO_PORT_P8, GPIO_PIN2);

    SCL_HIGH;

    __delay_cycles(10);

    if(GPIO_getInputPinValue (GPIO_PORT_P8, GPIO_PIN2)==1)

    {

        a=1;

    }

    else

    {

        a=0;

    }


    SCL_LOW;

    __delay_cycles(10);

    SDA_OUT;

    return a;

}


///向IIC总线发送数据(MCU=>||)

void IIC_writebyte(unsigned char IIC_byte)

{

    unsigned char i;

    SDA_OUT;

    SCL_OUT;

//    SCL_LOW;

        for (i=0; i<8; i++)         //8位计数器

            {

                if((IIC_byte<                {

                    SDA_HIGH;

                }

                else

                {

                    SDA_LOW;

                }


        __delay_cycles(10);

        SCL_HIGH;

        __delay_cycles(10);

        SCL_LOW;

//        __delay_cycles(10);

//        IIC_byte<<=1;

    }


    IIC_testACK();

}



IIC接收一个字节(||——>MCU)

unsigned char IIC_readebyte(void)

{

    unsigned char i,k=0;

    SDA_IN;

    GPIO_setAsInputPinWithPullUpResistor (GPIO_PORT_P8, GPIO_PIN2);

    SCL_OUT;

    SCL_LOW;

    __delay_cycles(100);

    for(i=0;i<8;i++)

    {

        SCL_HIGH;

        k=k<<1;

        if(SDA)

            k|=1;

        SCL_LOW;

        __delay_cycles(100);

    }

    SDA_OUT;

    __delay_cycles(100);

    return k;

}



//**************************************

//向I2C设备写入一个字节数据

//**************************************

void ByteWrite6050(unsigned char REG_Address,unsigned char REG_data)

{

    IIC_start();                  //起始信号

    IIC_writebyte(SlaveAddress);   //发送设备地址+写信号

    IIC_writebyte(REG_Address);    //内部寄存器地址,

    IIC_writebyte(REG_data);        //内部寄存器数据,

    IIC_stop();                   //发送停止信号

}

//**************************************

//从I2C设备读取一个字节数据

//**************************************

unsigned char ByteRead6050(unsigned char REG_Address)

{

    unsigned char REG_data;

    IIC_start();                   //起始信号

    IIC_writebyte(SlaveAddress);     //发送设备地址+写信号

    IIC_writebyte(REG_Address);      //发送存储单元地址,从0开始

    IIC_start();                   //起始信号

    IIC_writebyte(SlaveAddress+1);  //发送设备地址+读信号

    REG_data=IIC_readebyte();       //读出寄存器数据

    SendACK(1);                //接收应答信号

    IIC_stop();                    //停止信号

    return REG_data;

}

//**************************************

//合成数据

//**************************************

int Get6050Data(unsigned char REG_Address)

{

    char H,L;

    H=ByteRead6050(REG_Address);

    L=ByteRead6050(REG_Address+1);

    return (H<<8)+L;   //合成数据

}

//**************************************

//初始化MPU6050

//**************************************

void InitMPU6050()

{

    ByteWrite6050(PWR_MGMT_1, 0x00);  // 解除休眠状态

    ByteWrite6050(SMPLRT_DIV, 0x07);  // 陀螺仪采样率设置(125HZ)

    ByteWrite6050(CONFIG, 0x06);      // 低通滤波器设置(5HZ频率)

    ByteWrite6050(GYRO_CONFIG, 0x18); // 陀螺仪自检及检测范围设置(不自检,16.4LSB/DBS/S)

    ByteWrite6050(ACCEL_CONFIG, 0x01); // 不自检,量程2g

}


/*

**********************************************

**函数名  :float Mpu6050AccelAngle(int8 dir)

**函数功能:输出加速度传感器测量的倾角值

**            范围为2g时,换算关系:16384 LSB/g

**            角度较小时,x=sinx得到角度(弧度), deg = rad*180/3.14

**            因为x>=sinx,故乘以1.2适当放大

**返回参数:测量的倾角值

**传入参数:dir - 需要测量的方向

**           ACCEL_XOUT - X方向

**           ACCEL_YOUT - Y方向

**           ACCEL_ZOUT - Z方向

**********************************************

*/

float Mpu6050AccelAngle(char dir)

{

    float accel_agle; // 测量的倾角值

    float result; // 测量值缓存变量

    result = (float)Get6050Data(dir); // 测量当前方向的加速度值,转换为浮点数

    accel_agle = (result + MPU6050_ZERO_ACCELL)/16384; // 去除零点偏移,计算得到角度(弧度)

    accel_agle = accel_agle*1.2*180/3.14;     //弧度转换为度


    return accel_agle; // 返回测量值

}


/*

**********************************************

**函数名  :float Mpu6050GyroAngle(int8 dir)

**函数功能:输出陀螺仪测量的倾角加速度

**            范围为2000deg/s时,换算关系:16.4 LSB/(deg/s)

**返回参数:测量的倾角加速度值

**传入参数:dir - 需要测量的方向

**           GYRO_XOUT - X轴方向

**           GYRO_YOUT - Y轴方向

**           GYRO_ZOUT - Z轴方向

**********************************************

*/

float Mpu6050GyroAngle(char dir)

{

    float gyro_angle;

    gyro_angle = (float)Get6050Data(dir);   // 检测陀螺仪的当前值

    gyro_angle = -(gyro_angle + MPU6050_ZERO_GYRO)/16.4;    //去除零点偏移,计算角速度值,负号为方向处理


    return gyro_angle; // 返回测量值

}


/*

 * MPU6050.h

 *

 *  Created on: 2022年7月17日

 *      Author: S10

 */


#ifndef MPU6050_H_

#define MPU6050_H_


//********Mpu6050的零点校准值**************

#define MPU6050_ZERO_ACCELL 378

#define MPU6050_ZERO_GYRO 13

//*************定义MPU6050内部地址*******************

#define SMPLRT_DIV      0x19    //输出8位无符号位,输出分频,用来配置采样频率的寄存器。采样率=陀螺仪的输出率/(1+该寄存器值),低通滤波器使能时陀螺仪输出为8k,反之1k。

#define CONFIG          0x1A    //配置低通滤波器的寄存器

#define GYRO_CONFIG     0x1B    //三个方向角度的自我测试和量程

#define ACCEL_CONFIG    0x1C    //三个方向加速度的自我测试和量程

/***************加速度传感器寄存器******************/

#define ACCEL_XOUT_H            0x3B

#define ACCEL_XOUT_L            0x3C

#define ACCEL_XOUT      ACCEL_XOUT_H    // X轴读取地址,高位为起始位

#define ACCEL_YOUT_H            0x3D

#define ACCEL_YOUT_L            0x3E

#define ACCEL_YOUT      ACCEL_YOUT_H    // Y轴读取地址,高位为起始位

#define ACCEL_ZOUT_H            0x3F

#define ACCEL_ZOUT_L            0x40

#define ACCEL_ZOUT      ACCEL_ZOUT_H    // Z轴读取地址,高位为起始位

/*****************温度传感器寄存器****************/

#define TEMP_OUT_H      0x41

#define TEMP_OUT_L      0x42

#define TEMP_OUT          TEMP_OUT_H    // 温度传感器读取地址,高位为起始位

//

/陀螺仪相关寄存器//

//

#define GYRO_XOUT_H     0x43

#define GYRO_XOUT_L     0x44

#define GYRO_XOUT        GYRO_XOUT_H    // 陀螺仪X轴读取地址,高位为起始位

#define GYRO_YOUT_H     0x45

#define GYRO_YOUT_L     0x46

#define GYRO_YOUT        GYRO_YOUT_H    // 陀螺仪Y轴读取地址,高位为起始位

#define GYRO_ZOUT_H     0x47

#define GYRO_ZOUT_L     0x48

#define GYRO_ZOUT        GYRO_ZOUT_H    // 陀螺仪Z轴读取地址,高位为起始位

///

其它寄存器/

//

#define PWR_MGMT_1      0x6B    //电源管理

[1] [2]
关键字:MPU6050 引用地址:模块学习(二)——MPU6050

上一篇:模块学习(三)——激光测距模块(TOF10120)
下一篇:MSP430——UART(四)

推荐阅读最新更新时间:2024-11-12 11:10

MSP432学习笔记:REF_A模块
REF_A模块是一个通用的参考系统,用于为给定设备上的其他模拟模块(如模数转换器、数模转换器、比较器或LCD控制器)生成所需的电压参考。本章描述REF_A模块。 1.1:REF_A介绍 REF_A模块生成供设备中各种模拟模块使用的参考电压。REF_A模块的核心是一个带隙,所有其他参考电压都从这个带隙中通过统一或同相增益阶段。REF_A模块中的REFGEN子系统由带隙带隙偏置和产生可用的初级电压基准的非逆变缓冲级系统:1.2 V, 1.45 V, 2.5 V。此外,当启用时,可用缓冲带隙电压。REF_A的功能包括: •集中式工厂校准带隙,具有优异的PSRR、温度系数和准确度 •1.2 v、1.45 v或2.5 v用户
[单片机]
MSP432<font color='red'>学习</font>笔记:REF_A<font color='red'>模块</font>
MSP430F5529 DriverLib 库函数学习笔记(十五)SFR 模块
平台:Code Composer Studio 10.3.1 MSP430F5529 LaunchPad™ Development Kit (MSP‑EXP430F5529LP) API (机翻) 特殊函数寄存器API提供了一组用于使用MSP430Ware SFR模块的函数。提供了启用和禁用中断和控制~ RST/NMI引脚的功能。 SFR模块可以使设备的其他外设产生中断。 SFR APl被分成两组: SFR管理中断的函数 SFR 管理RST/NMI引脚控制的函数 SFR管理中断的函数 SFR_enableInterrupt(uint8_t interruptMask) //启用选定
[单片机]
MSP430学习笔记(3)时钟模块
1. 时钟模块包括高速晶体振荡器、低俗晶体振荡器、数字控制振荡器DCO、锁频环FLL以及锁频环增强版本FLL+等部件构成。 2. 时钟模块产生3个输出结果:ACLK(辅助时钟),MCLK(主系统时钟)和SMCLK(子系统时钟)。 3. MSP430采用锁频环FLL以及锁频环增强版本FLL+等部件将晶体频率倍频至系统频率。数字控制振荡器DCO和锁频环FLL计数相结合可实现快速启动。在晶体振荡器失效时DCO可自动用于系统时钟。 4. 3个时钟输入源: a) LFXT1CLK:低频时钟源 b) XT2CLK:高频时钟源 c) DCOCLK:数字控制RC振荡器 5. 3种时钟信号 a)
[单片机]
MSP430<font color='red'>学习</font>笔记(3)时钟<font color='red'>模块</font>
基于 STM32 的硬件 I2C 读取 MPU6050 数据
MPU6050其实就是一个 I2C 器件,里面有很多寄存器(但是我们用到的只有几个),我们通过读写寄存器来操作这个芯片。所以首要问题就是 STM32 和 MPU6050 的 I2C 通信。 1、配置 STM32 (用I2C1:PB6——SCL;PB7——SDA) 1)时钟 RCC RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1 , ENABLE); 2)GPIO 配置 GPIO_InitStructure.GPIO_Pin = GPIO
[单片机]
基于 STM32 的硬件 I2C 读取 <font color='red'>MPU6050</font> 数据
STM8学习笔记——PWM模块
首先将管脚配置为推挽输出。下面以向上计数模式为例来讲述PWM产生的原理:TIMx开始向上计数,TIMx_CNT为计数值,计数一次加1,TIMx_ARR确定了计数的上限,达到上限后计数器从0开始重新计数,所以一次PWM频率就由TIMx_ARR来确定了,即计数器时钟*(TIMx_ARR-1),频率确定了,接下来就是占空比。占空比是由TIMx_CCRx来确定的,PWM模式1下当TIMx_CNT TIMx_CCRx,输出OCiREF有效电平,TIMx_CNT =TIMx_CCRx时,输出OCiREF无效电平,至于有效电平是0还是1,要设置TIMx_CCERx,这样产生了一个PWM波形,可以说配置非常灵活,当TIMx_CCRx为0时,占
[单片机]
正点原子STM32学习笔记——MPU6050介绍
一、MPU6050简介 1.什么是MPU6050? MPU6050是InvenSense公司推出的全球首款整合性6轴运动处理组件,内带3轴陀螺仪和3轴加速度传感器,并且含有一个第二IIC接口,可用于连接外部磁力传感器,利用自带数字运动处理器(DMP: Digital Motion Processor)硬件加速引擎,通过主IIC接口,可以向应用端输出完整的9轴姿态融合演算数据。 有了DMP,我们可以使用InvenSense公司提供的运动处理资料库,非常方便的实现姿态解算,降低了运动处理运算对操作系统的负荷,同时大大降低了开发难度 。 2.MUP6050特点。 MPU6050 的特点包括: ① 以数字形式输出
[单片机]
正点原子STM32<font color='red'>学习</font>笔记——<font color='red'>MPU6050</font>介绍
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved