树莓派驱动6轴传感器MPU6500与SPI初体验(一)


     手里有一块老版本的树莓派B+,除了点亮个led灯,每怎么玩过,最近看了个视频,8轴载人飞行器,感觉太爽了。视频看出是极客通过无人机DIY出来的,现在城市交通这么拥堵,要是能DIY一个飞行器来做交通工具是不是很拉风(当然前提不考虑空管问题)。不过估算了下,光电机,电调单轴的费用就要10K左右,8轴下来。。。这钱可以买辆汽车了。虽然公司是偏向于做硬件产品的,但本人一直从事软件开发,所以对硬件的只是比较欠缺。上网看了下资料,大部分是I2C的例子和说明,少有SPI协议的,偶尔搜索到几个介绍BCM系列SPI编程的,还都是基于系统设备映射脱离驱动完成的,有够复杂。

     1.6轴传感器

          某宝10多块钱买了一个,MPU6500。

树莓派驱动6轴传感器MPU6500与SPI初体验(一)_第1张图片


     2.树莓派与SPI协议

        树莓派使用CP2102将串口转接至pc的usb接口。 树莓派GPIO管脚图示,其中化红线的为需要连接mpu6500的管脚,SPI的4根+电源和接地 共6根连线。


树莓派驱动6轴传感器MPU6500与SPI初体验(一)_第2张图片

 



          SPI协议需要4个管脚进行连接:

                    CS:片选;SCLK:时钟;MOSI:主设备输出从设备输入;MISO:主设备输入,从设备输出;

          对照SPI协议将mpu6500和树莓派连接即可。


      4.设备驱动安装与系统配置

             树莓派B+使用的是BCM 2835的芯片,官方或开源的驱动都支持的很好:

                http://www.airspayce.com/mikem/bcm2835/bcm2835-1.50.tar.gz

               >tar zxvf bcm2835-1.xx.tar.gz

               >cd bcm2835-1.xx
               >./configure
               > make && make install

          驱动安装完成后,需要让系统启动时自行加载,我的系统使用的是archlinux,修改启动配置:

          #/boot/config.txt

             device_tree_param=spi=on

          # /etc/modules-load.d/raspberrypi.conf
            spi-dev

            spi-bcm2835

          重新启动系统,检查是否spi设备可用:

           > lsmod | grep spi
               spi_bcm2835             7412          #看到这一行,表示系统已加载了spi设备。


        5. MPU6500设备测试程序

          #mpu6500.c

         

#include 
#include 
#include 

int main(int argc, char **argv)
{

    if (!bcm2835_init())
    {
      printf("bcm2835_init failed. Are you running as root??\n");
      return 1;
    }
    if (!bcm2835_spi_begin())
    {
      printf("bcm2835_spi_begin failedg. Are you running as root??\n");
      return 1;
    }
    	bcm2835_spi_setBitOrder(BCM2835_SPI_BIT_ORDER_MSBFIRST);//大小端
    	bcm2835_spi_setClockDivider(BCM2835_SPI_CLOCK_DIVIDER_256);//SPI速率 1MHZ
	bcm2835_spi_setDataMode(BCM2835_SPI_MODE0);//模式
    	bcm2835_spi_chipSelect(BCM2835_SPI_CS0);//片选
	bcm2835_spi_setChipSelectPolarity(BCM2835_SPI_CS0, LOW);//使能片选


	unsigned char data[2];
	unsigned char rec[2]={0x00,0x00};
	unsigned char reg=0x6b;

	data[0]=0x6b;//PWR_MGMT_1   初始化
	data[1]=0x80;

	bcm2835_spi_transfern(data,sizeof(data));
	delay(100);

	data[0]=0x68;//SIGNAL_PATH_RESET   初始化
	data[1]=0x07;
	bcm2835_spi_transfern(data,sizeof(data));
	delay(100);

	data[0]=0x6a;
	data[1]=0x10|0x8|0x4|0x1;//USER_CTRL 初始化
	bcm2835_spi_transfern(data,sizeof(data));
	delay(1000);


	data[0]=0x75|0x80;
	bcm2835_spi_transfern(data,sizeof(data));//读取 WHO_AM_I 如果为0x70表示设备正确
	printf("%x \r\n",data[0]);

	bcm2835_spi_end();
	bcm2835_close();
    return 0;
}

             编译:

                 > gcc -c mpu6500.c

                 > gcc mpu6500.o -lbcm2835 -o mpu6500.exe

             6.BCM2835

              详细的SPI时序图和寄存器说明见官方的RM和PS。由于对SPI完全没印象,走了很多弯路。数据的读写是根据寄存器的第8个位(即bit7)来确定的,0为写,1为读。

                 

     


    

你可能感兴趣的:(嵌入式,C/C++/VC,网络编程)