i.MX6ULL终结者MPU6050 六轴传感器例程程序设计
本实验的源码工程在开发板光盘资料的:i.MX6UL终结者光盘资料\04_裸机例程源码\19_mpu6050目录下。我们在Ubuntu系统下使用命令“mkdir 19_mpu6050”建立“19_mpu6050”文件夹,如图 1所示:

然后使用“cd 19_mpu6050”命令进入到19_mpu6050文件夹,如图 2所示:

然后使用命令“cp -r …/18_touchscreen/* ./”将上一章例程中的所有内容拷贝到刚刚新建的“19_mpu6050”里面,如图 27.3.3所示:

然后在drivers目录下建立mpu6050文件夹,用来保存mpu6050的驱动文件,然后在“drivers/mpu6050”目录中新建mpu6050.h和mpu6050.c两个文件,然后在mpu6050.h文件输入下面的代码:
1 #ifndef _BSP_MPU6050_H2 #define _BSP_MPU6050_H3 4 #include "imx6ul.h"5 6 #define MPU6050_ADDR 0X68 /* MPU6050器件地址 */7 8 /* MPU6050寄存器 */9 #define MPU_CFG_REG 0X1A /*配置寄存器*/10 #define MPU_PWR_MGMT1_REG 0x6B /*电源管理寄存器1*/11 #define MPU_PWR_MGMT2_REG 0x6C /*电源管理寄存器2*/12 #define MPU_GYRO_CFG_REG 0x1B /*陀螺仪配置寄存器*/13 #define MPU_ACCEL_CFG_REG 0x1C /*加速度配置寄存器*/14 #define MPU_SAMPLE_RATE_REG 0x19 /*采样频率分频器*/15 #define MPU_INT_EN_REG 0x38 /*中断使能寄存器*/16 #define MPU_USER_CTRL_REG 0x6A /*用户控制寄存器*/17 #define MPU_FIFO_EN_REG 0x23 /*FIFO使能寄存器*/18 #define MPU_INTBP_CFG_REG 0x37 /*中断旁路设置寄存器*/19 20 #define ACCEL_XOUT_H 0x3B /* 加速度值,X轴高8位寄存器 */21 #define ACCEL_YOUT_H 0x3D /* 加速度值,Y轴高8位寄存器 */22 #define ACCEL_ZOUT_H 0x3F /* 加速度值,Z轴高8位寄存器 */23 #define GYRO_XOUT_H 0x43 /* 陀螺仪值,X轴高8位寄存器 */24 #define GYRO_YOUT_H 0x45 /* 陀螺仪值,Y轴高8位寄存器 */25 #define GYRO_ZOUT_H 0x47 /* 陀螺仪值,Z轴高8位寄存器 */26 27 28 /* 函数声明 */29 void mpu6050_init(void);30 unsigned char mpu6050_readonebyte(unsigned char addr,unsigned char reg);31 unsigned char mpu6050_writeonebyte(unsigned char addr,unsigned char reg,unsigned char data);32 33 #endif
mpu6050.h文件里面主要定义了一些与mpu6050寄存器相关的宏,以及声明了一些函数。
然后我们打开mpu6050.c文件,在里面输入下面的代码:
1 #include "mpu6050.h"2 #include "i2c.h"3 #include "delay.h"4 #include "cc.h"5 #include "stdio.h"6 7 /*8 * @description : 初始化MPU60509 * @param : 无10 * @return : 无返回11 */12 void mpu6050_init(void)13 {14 15 /* 1、IO初始化,配置I2C IO属性 16 * I2C1_SCL -> UART4_TXD17 * I2C1_SDA -> UART4_RXD18 */19 IOMUXC_SetPinMux(IOMUXC_UART4_TX_DATA_I2C1_SCL, 1);20 IOMUXC_SetPinMux(IOMUXC_UART4_RX_DATA_I2C1_SDA, 1);21 22 /* 23 *bit 16:0 HYS关闭24 *bit [15:14]: 1 默认47K上拉25 *bit [13]: 1 pull功能26 *bit [12]: 1 pull/keeper使能 27 *bit [11]: 0 关闭开路输出28 *bit [7:6]: 10 速度100Mhz29 *bit [5:3]: 110 驱动能力为R0/630 *bit [0]: 1 高转换率31 */32 IOMUXC_SetPinConfig(IOMUXC_UART4_TX_DATA_I2C1_SCL, 0x70B0);33 IOMUXC_SetPinConfig(IOMUXC_UART4_RX_DATA_I2C1_SDA, 0X70B0);34 35 i2c_init(I2C1); /* 初始化I2C1 */36 37 /* 2、初始化MPU6050 */38 mpu6050_writeonebyte(MPU6050_ADDR,
MPU_PWR_MGMT1_REG,
0X80); /* 复位MPU6050 */39 delayms(50);40 mpu6050_writeonebyte(MPU6050_ADDR,
MPU_PWR_MGMT1_REG,
0X00); /* 唤醒MPU6050 */41 delayms(50);42 mpu6050_writeonebyte(MPU6050_ADDR,
MPU_GYRO_CFG_REG,
3<<3);/*陀螺仪传感器,+-2000dps*/43 delayms(50);44 mpu6050_writeonebyte(MPU6050_ADDR,
MPU_ACCEL_CFG_REG,
0<<3);/*加速度传感器,+-2g*/45 delayms(50);46 mpu6050_writeonebyte(MPU6050_ADDR,MPU_SAMPLE_RATE_REG,
19);/*设置采样率50Hz*/47 delayms(50);48 mpu6050_writeonebyte(MPU6050_ADDR,
MPU_INT_EN_REG,
0x00);/*关闭所有中断*/49 delayms(50);50 mpu6050_writeonebyte(MPU6050_ADDR,
MPU_USER_CTRL_REG,
0x00);/*I2C主模式关闭*/51 delayms(50);52 mpu6050_writeonebyte(MPU6050_ADDR,
MPU_FIFO_EN_REG,
0x00);/*关闭FIFO*/53 delayms(50);54 mpu6050_writeonebyte(MPU6050_ADDR,
MPU_INTBP_CFG_REG,
0x80);/*INT引脚低电平有效*/55 delayms(50);56 mpu6050_writeonebyte(MPU6050_ADDR,
MPU_PWR_MGMT1_REG,
0x01);/*设置CLKSEL,PLL X轴为参考*/57 delayms(50);58 mpu6050_writeonebyte(MPU6050_ADDR,
MPU_PWR_MGMT2_REG,
0x00);/*加速度与陀螺仪都工作*/59 delayms(50);60 mpu6050_writeonebyte(MPU6050_ADDR,MPU_CFG_REG,
0x04);/*设置数字低通滤波
器:MPU_SAMPLE_RATE_REG/2=25Hz*/61 delayms(50);62 }63 64 /*65 * @description : 向MPU6050写入数据66 * @param - addr: 设备地址67 * @param - reg : 要写入的寄存器68 * @param - data: 要写入的数据69 * @return : 操作结果70 */71 unsigned char mpu6050_writeonebyte(unsigned char addr,
unsigned char reg, unsigned char data)72 {73 unsigned char status=0;74 unsigned char writedata=data;75 struct i2c_transfer masterXfer;76 77 /* 配置I2C xfer结构体 */78 masterXfer.slaveAddress = addr; /* 设备地址 */79 masterXfer.direction = kI2C_Write; /* 写入数据 */80 masterXfer.subaddress = reg; /* 要写入的寄存器地址 */81 masterXfer.subaddressSize = 1; /* 地址长度一个字节 */82 masterXfer.data = &writedata; /* 要写入的数据 */83 masterXfer.dataSize = 1; /* 写入数据长度1个字节 */84 85 if(i2c_master_transfer(I2C1, &masterXfer))86 status=1;87 88 return status;89 }90 91 /*92 * @description : 从MPU6050读取一个字节的数据93 * @param - addr: 设备地址94 * @param - reg : 要读取的寄存器95 * @return : 读取到的数据。96 */97 unsigned char mpu6050_readonebyte(unsigned char addr,unsigned char reg)98 {99 unsigned char val=0;
100
101 struct i2c_transfer masterXfer;
102 masterXfer.slaveAddress = addr; /* 设备地址 */
103 masterXfer.direction = kI2C_Read; /* 读取数据 */
104 masterXfer.subaddress = reg; /* 要读取的寄存器地址 */
105 masterXfer.subaddressSize = 1; /* 地址长度一个字节 */
106 masterXfer.data = &val; /* 接收数据缓冲区 */
107 masterXfer.dataSize = 1; /* 读取数据长度1个字节 */
108 i2c_master_transfer(I2C1, &masterXfer);
109
110 return val;
111 }
在mpu6050.c文件里面定义了三个函数,首先第一个是mpu6050_init函数,该函数主要完成i2c的初始化,以及mpu6050的初始化(复位mpu6050,设置陀螺仪,加速度计的参数,采样率,关闭中断,FIFO功能,最后使能加速度计和陀螺仪)。第二个函数是mpu6050_writeonebyte,该函数用来配置mpu6050寄存器。第三个函数是mpu6050_readonebyte,该函数是读取mpu6050的寄存器。
然后我们打开main.c文件,在里面输入下面的代码:
1 #include "clk.h"2 #include "delay.h"3 #include "led.h"4 #include "beep.h"5 #include "key.h"6 #include "int.h"7 #include "uart.h"8 #include "lcd.h"9 #include "lcdapi.h"10 #include "rtc.h"11 #include "mpu6050.h"12 #include "stdio.h"13 14 /*15 * @description : 使能I.MX6U的硬件NEON和FPU16 * @param : 无17 * @return : 无18 */19 void imx6ul_hardfpu_enable(void)20 {21 uint32_t cpacr;22 uint32_t fpexc;23 24 /* 使能NEON和FPU */25 cpacr = __get_CPACR();26 cpacr = (cpacr & ~(CPACR_ASEDIS_Msk | CPACR_D32DIS_Msk))27 | (3UL << CPACR_cp10_Pos) | (3UL << CPACR_cp11_Pos);28 __set_CPACR(cpacr);29 fpexc = __get_FPEXC();30 fpexc |= 0x40000000UL;31 __set_FPEXC(fpexc);32 }33 34 /*35 * @description : main函数36 * @param : 无37 * @return : 无38 */39 int main(void)40 {41 unsigned short ACCE_X, ACCE_Y, ACCE_Z, GYRO_X, GYRO_Y, GYRO_Z;42 43 unsigned char i = 0;44 unsigned char state = OFF;45 46 imx6ul_hardfpu_enable(); /* 使能I.MX6U的硬件浮点 */47 int_init(); /* 初始化中断(一定要最先调用!) */48 imx6u_clkinit(); /* 初始化系统时钟 */49 delay_init(); /* 初始化延时 */50 clk_enable(); /* 使能所有的时钟*/51 led_init(); /* 初始化led */52 beep_init(); /* 初始化beep*/53 uart_init(); /* 初始化串口,波特率115200 */54 lcd_init(); /* 初始化LCD */55 mpu6050_init(); /* 初始化MPU6050*/56 57 58 tftlcd_dev.forecolor = LCD_RED; /*设置字体颜色为红色*/59 lcd_show_string(30, 50, 200, 16, 16,60 (char*)"i.MX6ULL MPU6050 TEST");/* 显示信息*/61 62 lcd_show_string(30, 100, 200, 16, 16, (char*)" ACCE_X:");63 lcd_show_string(30, 120, 200, 16, 16, (char*)" ACCE_Y:");64 lcd_show_string(30, 140, 200, 16, 16, (char*)" ACCE_Z:");65 lcd_show_string(30, 160, 200, 16, 16, (char*)" GYRO_X:");66 lcd_show_string(30, 180, 200, 16, 16, (char*)" GYRO_Y:");67 lcd_show_string(30, 200, 200, 16, 16, (char*)" GYRO_Z:");68 69 tftlcd_dev.forecolor = LCD_BLUE;70 71 while(1)72 {73 /* 读取加速度X轴数据 */74 ACCE_X = (mpu6050_readonebyte(MPU6050_ADDR, ACCEL_XOUT_H)<<8)75 + mpu6050_readonebyte(MPU6050_ADDR, ACCEL_XOUT_H+1);76 77 /* 读取加速度Y轴数据 */78 ACCE_Y = (mpu6050_readonebyte(MPU6050_ADDR, ACCEL_YOUT_H)<<8)79 + mpu6050_readonebyte(MPU6050_ADDR, ACCEL_YOUT_H+1);80 81 /* 读取加速度Z轴数据 */82 ACCE_Z = (mpu6050_readonebyte(MPU6050_ADDR, ACCEL_ZOUT_H)<<8)83 + mpu6050_readonebyte(MPU6050_ADDR, ACCEL_ZOUT_H+1);84 85 /* 读取陀螺仪X轴数据 */86 GYRO_X = (mpu6050_readonebyte(MPU6050_ADDR, GYRO_XOUT_H)<<8)87 + mpu6050_readonebyte(MPU6050_ADDR, GYRO_XOUT_H+1);88 89 /* 读取陀螺仪Y轴数据 */90 GYRO_Y = (mpu6050_readonebyte(MPU6050_ADDR, GYRO_YOUT_H)<<8)91 + mpu6050_readonebyte(MPU6050_ADDR, GYRO_YOUT_H+1);92 93 /* 读取陀螺仪Z轴数据 */94 GYRO_Z = (mpu6050_readonebyte(MPU6050_ADDR, GYRO_ZOUT_H)<<8)95 + mpu6050_readonebyte(MPU6050_ADDR, GYRO_ZOUT_H+1);96 97 /* 串口打印获取到的所有数据 */98 printf("ACCE_X:%d
ACCE_Y:%d
ACCE_Z:%d
GYRO_X:%d
GYRO_Y:%d
GYRO_Z:%d\r\n",99 ACCE_X, ACCE_Y, ACCE_Z, GYRO_X, GYRO_Y, GYRO_Z);
100
101 lcd_shownum(30 + 64, 100, ACCE_X, 5, 16);/* 显示加速度X轴数据 */
102 lcd_shownum(30 + 64, 120, ACCE_Y, 5, 16);/* 显示加速度Y轴数据 */
103 lcd_shownum(30 + 64, 140, ACCE_Z, 5, 16);/* 显示加速度Z轴数据 */
104 lcd_shownum(30 + 64, 160, GYRO_X, 5, 16);/* 显示陀螺仪X轴数据 */
105 lcd_shownum(30 + 64, 180, GYRO_Y, 5, 16);/* 显示陀螺仪Y轴数据 */
106 lcd_shownum(30 + 64, 200, GYRO_Z, 5, 16);/* 显示陀螺仪Z轴数据 */
107
108 delayms(200);
109 i++;
110 if(i == 2)
111 {
112 i = 0;
113 state = !state;
114 led_switch(LED0,state);
115 }
116 }
117 return 0;
118 }
在main.c文件第55行调用mpu6050_init函数初始化mpu6050。然后再在while主循环里面读取加速度计和陀螺仪的数值,分别在屏幕和串口显示出来。
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
