shuen729 发表于 2014-11-28 10:20:56

STM32F103 IIC读取MPU6050数据

一直想做四轴,就是没有行动。直到最近有点时间,开始着手做,之前在论坛里看了不少四轴的资料(烈火、圆点、匿名等),决定自己先做些底层的硬件平台熟悉熟悉,然后画板子。TB上买了STM32F103C8最小系统板+烧写器+MPU6050,开始调试:
因为之前没有用过ARM芯片,所以先花了两周的时间把IIC外设调通,之后再连接MPU6050。用了两种方法:分开读取加速度计数据、连续一次性读取加速度和角速度数据(时钟都是400K)。废话不多说上图:

方法一:一次读取一个数据(包含高低位)

unsigned int Read_MPU6050_2Bytes(uint8_t DeviceAddress,uint8_t Start_MemoryAddress)
{
unsigned int Received_data;
      I2C_AcknowledgeConfig(I2C2,ENABLE);//开应答
while(I2C_GetFlagStatus(I2C2,I2C_FLAG_BUSY));//等待总线空闲
      I2C_GenerateSTART(I2C2,ENABLE);//START
      while(I2C_CheckEvent(I2C2,I2C_EVENT_MASTER_MODE_SELECT)!=SUCCESS);//等待START 完成
I2C_SendDeviceAddress(I2C2,DeviceAddress,Write);//发送MPU6050地址+写入指令
      while(I2C_CheckEvent(I2C2,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)!=SUCCESS);//等待上一步完成
      I2C_SendData(I2C2,Start_MemoryAddress);//写入要操作的寄存器地址
      while(I2C_CheckEvent(I2C2,I2C_EVENT_MASTER_BYTE_TRANSMITTED)!=SUCCESS);//等待上一步完成
      I2C_GenerateSTART(I2C2,ENABLE); //再次START
      while(I2C_CheckEvent(I2C2,I2C_EVENT_MASTER_MODE_SELECT)!=SUCCESS);//等待上一步完成
I2C_SendDeviceAddress(I2C2,DeviceAddress,Read);//发送MPU6050地址+读出指令
      I2C_PECPositionConfig(I2C2,I2C_PECPosition_Next);//indicates that the next byte is PEC
      while(I2C_CheckEvent(I2C2,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)!=SUCCESS);//wait for ADDR BUZY MSL to be set
      I2C_AcknowledgeConfig(I2C2,DISABLE);//Clear ACK
      while(I2C_GetFlagStatus(I2C2,I2C_FLAG_BTF)!=SET);//wait for BTF
      I2C_GenerateSTOP(I2C2,ENABLE);////Stop
      while(I2C_CheckEvent(I2C2,I2C_EVENT_MASTER_BYTE_RECEIVED)!=SUCCESS);//
      Received_data=I2C_ReceiveData(I2C2);//
      Received_data=Received_data<<8;
      Received_data|=I2C_ReceiveData(I2C2);//连续读两次数据寄存器把数据寄存器和移位寄存器的数据都读出来
      return Received_data;
}
示波器抓到的读取加速度和角速度(6个数据,包含高低位)的总时间:740uS






方法2:一次读取加速度+角速度+温度数据(包含高低位)
连续读取要好好看看下图的这个时序(755Page Reference)


程序(直接粘贴中文注释成乱码):
void Get_Mpu6050_Data(void)
{
uint8_t i=0;
I2C_AcknowledgeConfig(I2C2,ENABLE);//
while(I2C_GetFlagStatus(I2C2,I2C_FLAG_BUSY));//µÈ´ý¿ÕÏÐ
//START£¬Ö÷¶¯Çл»³ÉMASTERģʽ
        I2C_GenerateSTART(I2C2,ENABLE);//²úÉú¿ªÊ¼ÐźÅ
        while(I2C_CheckEvent(I2C2,I2C_EVENT_MASTER_MODE_SELECT)!=SUCCESS);
        //´Ó»úµØÖ·+дָÁî
I2C_SendDeviceAddress(I2C2,MPU6050_ADDR,Write);//·¢ËÍ´Ó»úµØÖ·+дÈëÖ¸Áî
        while(I2C_CheckEvent(I2C2,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)!=SUCCESS);
        //дÈëÒª¶ÁÈ¡µÄ¼Ä´æÆ÷µØÖ·
        I2C_SendData(I2C2,ACCEL_XOUT_H);//дÈë±»²Ù×÷µÄ¼Ä´æÆ÷µØÖ·
        while(I2C_CheckEvent(I2C2,I2C_EVENT_MASTER_BYTE_TRANSMITTED)!=SUCCESS);//µÈ´ý·¢ËÍÍê±Ï
        //START
        I2C_GenerateSTART(I2C2,ENABLE);//Ôٴη¢Æð¿ªÊ¼ÐźÅ
        while(I2C_CheckEvent(I2C2,I2C_EVENT_MASTER_MODE_SELECT)!=SUCCESS);
                //´Ó»úµØÖ·+¶ÁÖ¸Áî
I2C_SendDeviceAddress(I2C2,MPU6050_ADDR,Read);//·¢ËÍ´Ó»úµØÖ·+¶ÁÖ¸Áî
        //I2C_PECPositionConfig(I2C2,I2C_PECPosition_Next);
        //I2C_AcknowledgeConfig(I2C2,ENABLE);
        while(I2C_CheckEvent(I2C2,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)!=SUCCESS);//wait for ADDR BUZY MSL to be set
        for(i=0;i<12;)
                      {
                  if(i<11)
                                                                                {
                   while(I2C_GetFlagStatus(I2C2,I2C_FLAG_RXNE)!=SET);//µÈ´ý½ÓÊÕµ½Êý¾Ý
                   Data_Mpu6050=I2C_ReceiveData(I2C2);//¶ÁÈ¡¸Õ¸ÕÊÕµ½µÄÊý¾Ý
                                                                       i++;                                       
                  }
                                                                                //最后三个数据收取需要小动作
                                                                                if(i>=11){
         //等待数据进来把data register & shift register灌满,放心不会丢失后面的数据
                while((I2C_GetFlagStatus(I2C2,I2C_FLAG_RXNE)!=SET)&&(I2C_GetFlagStatus(I2C2,I2C_FLAG_BTF)!=SET));      
                                                                                        I2C_AcknowledgeConfig(I2C2,DISABLE);//Clear ACK       
                                                                                        Data_Mpu6050=I2C_ReceiveData(I2C2);//读取Data N-2
                      I2C_GenerateSTOP(I2C2,ENABLE);////Stop
                      i++;                                                                                       
                      Data_Mpu6050=I2C_ReceiveData(I2C2);//读取Data N-1
                      while(I2C_GetFlagStatus(I2C2,I2C_FLAG_RXNE)!=SET);//等待Data N进来       
                      i++;                                                                                       
                      Data_Mpu6050=I2C_ReceiveData(I2C2);//读取Data N                                                                       
                                                                                }
                  }
}

实际测试的时间:370uS


读取数据就是这些,程序在附件里。
======================================分割线=====================================
MPU6050的数据读出来了,处理的时候遇到了问题,InvenSense在RM文件里没说清楚,16位的数据到底怎么scale,-2g对应0,0g对应0xffff/2?好疑惑(按这个处理的结果不对)。于是走上了瞎猜的路,还好最后蒙对了。0xffff对应+0g,0x0000对应-0g,2g对应(0xffff/2)+1,-2g对应(0xffff/2)-1。(按这个处理结果是对的,下面是图):




欢迎拍砖。

shuen729 发表于 2014-11-28 10:22:16

沙发自己坐{:victory:}

lzm2010 发表于 2014-11-28 11:01:56

硬件I2C比較難調,還是軟件方便。{:lol:}

franki 发表于 2014-11-28 19:28:16

字体好大啊 !

nicholas2xj 发表于 2014-11-28 23:39:40

学习,谢谢楼主分享

luweixuan 发表于 2014-11-29 00:19:11

字体啊,手机党伤不起!

酷赛引 发表于 2014-11-30 22:03:34

和楼主同感,一直想弄但是没有真正动起来,能否发个站内信给我,加QQ一起沟通学习
{:smile:}

NUAA_ZM 发表于 2014-12-1 13:05:51

参考下,准备用f407做iic

ntsyans 发表于 2014-12-3 12:51:15

GY-521引脚怎么接啊

shuen729 发表于 2014-12-4 10:29:09

酷赛引 发表于 2014-11-30 22:03
和楼主同感,一直想弄但是没有真正动起来,能否发个站内信给我,加QQ一起沟通学习
...

我权限不够

shuen729 发表于 2014-12-4 10:34:38

ntsyans 发表于 2014-12-3 12:51
GY-521引脚怎么接啊

模块资料里面应该有啊,电源和通信连上就能用了

磊磊映画 发表于 2014-12-9 22:49:10

lzm2010 发表于 2014-11-28 11:01
硬件I2C比較難調,還是軟件方便。

匿名四轴就把硬件IIC封起来了 没有开源

shuen729 发表于 2015-9-13 17:20:17

酷赛引 发表于 2014-11-30 22:03
和楼主同感,一直想弄但是没有真正动起来,能否发个站内信给我,加QQ一起沟通学习
...

试着给你发消息,你那边只接受好友的消息。

世界的一帧 发表于 2015-9-13 17:29:58

先收藏了有时间回来下载仔细参考一下

张流火星 发表于 2015-10-7 13:55:15

最近也在做四轴,准备自己调6050,先试试行不行吧!不行再来问大神们,哈哈

酷赛引 发表于 2015-12-22 08:26:20

shuen729 发表于 2015-9-13 17:20
试着给你发消息,你那边只接受好友的消息。

可以加一下我的扣:一零七一五六九三,一起沟通学习
页: [1]
查看完整版本: STM32F103 IIC读取MPU6050数据