本实验的源码工程在开发板光盘资料的:i.MX6UL终结者光盘资料\04_裸机例程源码\19_mpu6050目录下。我们在Ubuntu系统下使用命令“mkdir 19_mpu6050”建立“19_mpu6050”文件夹,如图 1所示:
然后使用“cd 19_mpu6050”命令进入到19_mpu6050文件夹,如图 2所示:
然后使用命令“cp -r …/18_touchscreen 7 8 9 #define MPU_CFG_REG 0x1A 10 #define MPU_PWR_MGMT1_REG 0x6B 11 #define MPU_PWR_MGMT2_REG 0x6C 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 18 #define MPU_INTBP_CFG_REG 0x37 19 20 #define ACCEL_XOUT_H 0x3B 21 #define ACCEL_YOUT_H 0x3D 22 #define ACCEL_ZOUT_H 0x3F 23 #define GYRO_XOUT_H 0x43 24 #define GYRO_YOUT_H 0x45 25 #define GYRO_ZOUT_H 0x47 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
12 void mpu6050_init(void)
13 {
14
15
19 IOMUXC_SetPinMux(IOMUXC_UART4_TX_DATA_I2C1_SCL, 1);
20 IOMUXC_SetPinMux(IOMUXC_UART4_RX_DATA_I2C1_SDA, 1);
21
22
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);
36
37
38 mpu6050_writeonebyte(MPU6050_ADDR,
MPU_PWR_MGMT1_REG,
0x80);
39 delayms(50);
40 mpu6050_writeonebyte(MPU6050_ADDR,
MPU_PWR_MGMT1_REG,
0x00);
41 delayms(50);
42 mpu6050_writeonebyte(MPU6050_ADDR,
MPU_GYRO_CFG_REG,
3<<3);
43 delayms(50);
44 mpu6050_writeonebyte(MPU6050_ADDR,
MPU_ACCEL_CFG_REG,
0<<3);
45 delayms(50);
46 mpu6050_writeonebyte(MPU6050_ADDR,
MPU_SAMPLE_RATE_REG,
19);
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);
51 delayms(50);
52 mpu6050_writeonebyte(MPU6050_ADDR,
MPU_FIFO_EN_REG,
0x00);
53 delayms(50);
54 mpu6050_writeonebyte(MPU6050_ADDR,
MPU_INTBP_CFG_REG,
0x80);
55 delayms(50);
56 mpu6050_writeonebyte(MPU6050_ADDR,
MPU_PWR_MGMT1_REG,
0x01);
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);
61 delayms(50);
62 }
63
64
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
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;
84
85 if(i2c_master_transfer(I2C1, &masterXfer))
86 status=1;
87
88 return status;
89 }
90
91
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;
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
19 void imx6ul_hardfpu_enable(void)
20 {
21 uint32_t cpacr;
22 uint32_t fpexc;
23
24
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
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();
47 int_init();
48 imx6u_clkinit();
49 delay_init();
50 clk_enable();
51 led_init();
52 beep_init();
53 uart_init();
54 lcd_init();
55 mpu6050_init();
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
74 ACCE_X = (mpu6050_readonebyte(MPU6050_ADDR, ACCEL_XOUT_H)<<8)
75 + mpu6050_readonebyte(MPU6050_ADDR, ACCEL_XOUT_H+1);
76
77
78 ACCE_Y = (mpu6050_readonebyte(MPU6050_ADDR, ACCEL_YOUT_H)<<8)
79 + mpu6050_readonebyte(MPU6050_ADDR, ACCEL_YOUT_H+1);
80
81
82 ACCE_Z = (mpu6050_readonebyte(MPU6050_ADDR, ACCEL_ZOUT_H)<<8)
83 + mpu6050_readonebyte(MPU6050_ADDR, ACCEL_ZOUT_H+1);
84
85
86 GYRO_X = (mpu6050_readonebyte(MPU6050_ADDR, GYRO_XOUT_H)<<8)
87 + mpu6050_readonebyte(MPU6050_ADDR, GYRO_XOUT_H+1);
88
89
90 GYRO_Y = (mpu6050_readonebyte(MPU6050_ADDR, GYRO_YOUT_H)<<8)
91 + mpu6050_readonebyte(MPU6050_ADDR, GYRO_YOUT_H+1);
92
93
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);
102 lcd_shownum(30 + 64, 120, ACCE_Y, 5, 16);
103 lcd_shownum(30 + 64, 140, ACCE_Z, 5, 16);
104 lcd_shownum(30 + 64, 160, GYRO_X, 5, 16);
105 lcd_shownum(30 + 64, 180, GYRO_Y, 5, 16);
106 lcd_shownum(30 + 64, 200, GYRO_Z, 5, 16);
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主循环里面读取加速度计和陀螺仪的数值,分别在屏幕和串口显示出来。