版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhuming3834/article/details/82789731
使用之前
在使用树莓派3B+和wiringPi之前希望你已经熟读了和他们相关的文档。
http://wiringpi.com/reference/i2c-library/
- 树莓派3B+的引脚图
这张图可以清晰的查看每个引脚的功能。 - mpu6050模块电路图
模块外观:
模块的资料地址:http://pan.baidu.com/share/link?shareid=2384903480&uk=1900861665 - 我是用的树莓派第一组IIC接口,也就是排针的第3个第5引脚。MPU6050模块的AD0接地。
开启树莓派IIC接口
- ssh方式登录树莓派;
- 执行
sudo su
切换成root
用户,如果你是root
用户登录,请忽略这一步; - 执行
raspi-config
,出现如下界面,键盘上下键选择第5个,然后按回车键进入;
- 继续按键盘上下键,还是第5个,进入IIC;
这里大家可以发现还可以设置其他接口,摄像头,SSH,VNC,SPI,串口等。 - 选择是
由于之前我已经设置过,且设置成了中文,所以显示是这样的。这里我们按键盘的左右键切换,然后按回车键确定即可。
当然还可以是直接进入树莓派的桌面去设置。设置完了之后为了保险起见,我们重启sudo reboot
一下树莓派。
检查电路连接是否正常
上面我已经说了电路的连接了。下面要做的就是检查电路是否连接正常。
- 执行
gpio i2cdetect
,出现如下效果说明电路连接正常;
这里我们看见了一个68,这个68就是我们的mpu6050的器件地址。关于IIC总线的知识请大家自行百度学习。 - 为什么是68呢?这个就需要看数据手册了。
我们事先把模块的AD0接地了,所以b1101000
就是68了,这里68应该是十六进制的,也就是0x68。
这里也说了MPU6050的IIC总线的最大速度是400kHz。 - 读取数据,执行
i2cdump -y 1 0x68
这里通过终端命令就已经读取到了MPU6050里面寄存器的数据了。
关于MPU6050的相关寄存器,上面的资料地址里面有数据手册说明。
代码实现
#include <stdio.h>
#include <wiringPi.h>
#include <wiringPiI2C.h>
//****************************************
// 定义MPU6050内部地址
//****************************************
#define SMPLRT_DIV 0x19 //陀螺仪采样率,典型值:0x07(125Hz)
#define CONFIG 0x1A //低通滤波频率,典型值:0x06(5Hz)
#define GYRO_CONFIG 0x1B //陀螺仪自检及测量范围,典型值:0x18(不自检,2000deg/s)
#define ACCEL_CONFIG 0x1C //加速计自检、测量范围及高通滤波频率,典型值:0x01(不自检,2G,5Hz)
#define ACCEL_XOUT_H 0x3B
#define ACCEL_XOUT_L 0x3C
#define ACCEL_YOUT_H 0x3D
#define ACCEL_YOUT_L 0x3E
#define ACCEL_ZOUT_H 0x3F
#define ACCEL_ZOUT_L 0x40
#define TEMP_OUT_H 0x41
#define TEMP_OUT_L 0x42
#define GYRO_XOUT_H 0x43
#define GYRO_XOUT_L 0x44
#define GYRO_YOUT_H 0x45
#define GYRO_YOUT_L 0x46
#define GYRO_ZOUT_H 0x47
#define GYRO_ZOUT_L 0x48
#define PWR_MGMT_1 0x6B //电源管理,典型值:0x00(正常启用)
#define WHO_AM_I 0x75 //IIC地址寄存器(默认数值0x68,只读)
#define SlaveAddress 0x68 //MPU6050器件地址
int fd;
// 初始化 mpu6050
void initMPU6050(){
wiringPiSetup () ;
fd = wiringPiI2CSetup (SlaveAddress);
if (fd >= 0) { // fd 为负数,说明IIC连接失败
printf("fd = %d\n",fd);
wiringPiI2CWriteReg8(fd,PWR_MGMT_1,0x00); // 开启温度检测 关闭休眠
wiringPiI2CWriteReg8(fd,SMPLRT_DIV, 0x07);
wiringPiI2CWriteReg8(fd,CONFIG, 0x06);
wiringPiI2CWriteReg8(fd,GYRO_CONFIG, 0x18);
wiringPiI2CWriteReg8(fd,ACCEL_CONFIG, 0x01);
}
else {
printf("IIC初始化失败");
}
}
// 读取制定寄存器中的数据
int getData(int reg_address){
return (wiringPiI2CReadReg8(fd,reg_address) << 8) + wiringPiI2CReadReg8(fd,reg_address + 1);
}
int main (void)
{
initMPU6050();
for(;;){
printf("ACCEL_XOUT_data = %d\n",getData(ACCEL_XOUT_H));
printf("ACCEL_YOUT_data = %d\n",getData(ACCEL_YOUT_H));
printf("ACCEL_ZOUT_data = %d\n",getData(ACCEL_ZOUT_H));
printf("GYRO_XOUT_data = %d\n",getData(GYRO_XOUT_H));
printf("GYRO_YOUT_data = %d\n",getData(GYRO_YOUT_H));
printf("GYRO_DOUT_data = %d\n",getData(GYRO_ZOUT_H));
// 这里温度计算公式 还没找到具体的出处,百度的,不可靠
printf("TEMP_OUT_data = %f\n",((double)getData(TEMP_OUT_H)/340 + 36.53));
delay(5000); // 间隔5秒 打印一次数据
}
return 0 ;
}
wiringpi相关函数说明
int wiringPiI2CSetup (int devId) ;
使用给定的设备标识符初始化I2C系统。如果返回负值,则说明初始化失败。int wiringPiI2CWriteReg8 (int fd, int reg, int data) ;
往指定的器件fd
的寄存器地址reg
写入数据data
。int wiringPiI2CReadReg8 (int fd, int reg) ;
从指定的器件fd
的寄存器地址reg
读取数据。
上面的2和3是8位器件的操作方式,还有16位器件的操作方式。
关于MPU6050的相关寄存器说明,这个看数据手册是最准确的。
最后
其实使用wiringpi库区操作IIC并不难,简单的驱动MPU6050并读取数据也不难。难的是怎么使用MPU6050去一些东西。网上很多四轴飞行器和两轮自平衡小车里面都有使用这个。