搜索
bottom↓
回复: 10

【求助】关于mpu6050模块,数据全是FF

[复制链接]

出0入0汤圆

发表于 2013-5-7 21:18:01 | 显示全部楼层 |阅读模式
本帖最后由 边个叫我 于 2013-5-7 21:20 编辑

小弟不才,买了个mpu6050模块,打算用avr单片机(mega16)先读数出来。但是怎样都是FF的读数。。。
我不知道是什么情况。
检查过iic时序图,还没发现错误。。。。
恳请各位英雄帮帮忙。。。
  1. [color=Cyan]/*avr_usart_mpu6050*/[/color]
  2. #include"iom16v.h"
  3. #include"macros.h"
  4. #include"mpu6050.h"
  5. void main(void)
  6. {
  7.            uint b;
  8.            delayms(5000);                //上电延时
  9.          I2C_Init();               
  10. //         InitLcd();                //液晶初始化
  11.          uart_init(19200);
  12.          InitMPU6050();        //初始化MPU6050
  13.            delayms(5000);                //上电延时       
  14.          while(1)
  15.         {
  16. /*       
  17.                 [color=Lime]Display10BitData(GetData(ACCEL_XOUT_H),2,0);        //显示X轴加速度
  18.                 Display10BitData(GetData(ACCEL_YOUT_H),7,0);        //显示Y轴加速度
  19.                 Display10BitData(GetData(ACCEL_ZOUT_H),12,0);        //显示Z轴加速度
  20.                 Display10BitData(GetData(GYRO_XOUT_H),2,1);        //显示X轴角速度
  21.                 Display10BitData(GetData(GYRO_YOUT_H),7,1);        //显示Y轴角速度
  22.                 Display10BitData(GetData(GYRO_ZOUT_H),12,1);        //显示[/color]
  23. */

  24.               uart_sendB('a');
  25.                   b = GetData(ACCEL_XOUT_H);
  26. //                  uart_sendB(b);
  27. /*          
  28.              [color=Cyan] uart_sendB(GetData(ACCEL_XOUT_H));
  29.               uart_sendB(GetData(ACCEL_YOUT_H));
  30.                   uart_sendB(GetData(ACCEL_ZOUT_H));
  31.                   uart_sendB(GetData(GYRO_XOUT_H));
  32.                   uart_sendB(GetData(GYRO_YOUT_H));
  33.                   uart_sendB(GetData(GYRO_ZOUT_H));[/color]*/
  34.                   //flag=0;

  35.                      uart_sendB(b>>8);
  36.                   uart_sendB(b&0xff);
  37.                 delayms(5000);
  38.         }
  39. }



  40. [color=Cyan]/*mpu6050.h*/[/color]

  41. /*****************************************************

  42.   普通IO模拟I2C通信,MPU-6050数据处理
  43.   
  44. *****************************************************/

  45. #ifndef  __MPU6050_H__
  46. #define  __MPU6050_H__

  47. typedef unsigned char  uchar;
  48. typedef unsigned int   uint;

  49. //-------------------------------------------------------
  50. //端口定义
  51. //-------------------------------------------------------

  52. //#define SCL       PC0       //输出1
  53. #define   Hign_SCL    PORTC |= (1 << PC0)
  54. #define   Low_SCL     PORTC &= ~(1 << PC0)

  55. //#define SDA        PC1      //输出1/输入0
  56. #define   Hign_SDA    PORTC |= (1 << PC1)   
  57. #define   Low_SDA     PORTC &= ~(1 << PC1)
  58. #define   Read_SDA    PINC & (1 << PC1)

  59. #define   EN_SDA_1    DDRC |= (1 << PC1)  //输出1
  60. #define   EN_SDA_0    DDRC &= ~(1 << PC1) //输入0

  61. //-------------------------------------------------------
  62. // 定义MPU6050内部地址
  63. //-------------------------------------------------------
  64. #define        SMPLRT_DIV                0x19        //陀螺仪采样率,典型值:0x07(125Hz)
  65. #define        CONFIG                        0x1A        //低通滤波频率,典型值:0x06(5Hz)
  66. #define        GYRO_CONFIG                0x1B        //陀螺仪自检及测量范围,典型值:0x18(不自检,2000deg/s)
  67. #define        ACCEL_CONFIG        0x1C        //加速计自检、测量范围及高通滤波频率,典型值:0x01(不自检,2G,5Hz)
  68. #define        ACCEL_XOUT_H        0x3B
  69. #define        ACCEL_XOUT_L        0x3C
  70. #define        ACCEL_YOUT_H        0x3D
  71. #define        ACCEL_YOUT_L        0x3E
  72. #define        ACCEL_ZOUT_H        0x3F
  73. #define        ACCEL_ZOUT_L        0x40
  74. #define        TEMP_OUT_H                0x41
  75. #define        TEMP_OUT_L                0x42
  76. #define        GYRO_XOUT_H                0x43
  77. #define        GYRO_XOUT_L                0x44       
  78. #define        GYRO_YOUT_H                0x45
  79. #define        GYRO_YOUT_L                0x46
  80. #define        GYRO_ZOUT_H                0x47
  81. #define        GYRO_ZOUT_L                0x48
  82. #define        PWR_MGMT_1                0x6B        //电源管理,典型值:0x00(正常启用)
  83. #define        WHO_AM_I                0x75        //IIC地址寄存器(默认数值0x68,只读)
  84. #define        SlaveAddress    0xD0    //IIC写入时的地址字节数据,+1为读取
  85. #define  mclk   12000000
  86. #pragma interrupt_handler uart_rx:12

  87. //-------------------------------------------------------
  88. // 函数声明
  89. //-------------------------------------------------------

  90. void  InitMPU6050(void);                                        //初始化MPU6050
  91. void  delayus(uint n);
  92. void  delayms(uint lms);
  93. void  I2C_Init(void);
  94. void  I2C_Start(void);
  95. void  I2C_Stop(void);
  96. void  I2C_Ack(void);
  97. void  I2C_NoAck(void);
  98. uchar I2C_WaitAck(void);
  99. void  I2C_SendByte(uchar dat);
  100. uchar I2C_RecvByte(uchar ack);
  101. uchar Single_ReadI2C(uchar REG_Address);
  102. void  Single_WriteI2C(uchar REG_Address,uchar REG_data);


  103. int   GetData(uchar REG_Address);                    //16位数据合成

  104. //-------------------------------------------------------
  105. // 延时函数
  106. //-------------------------------------------------------
  107. void delayus(unsigned int n)
  108. {
  109.      unsigned int i=0;   
  110.          for(i=0;i<n;i++)
  111.          asm("nop");

  112. }

  113. //-------------------------------------------------------
  114. // 延时函数
  115. //8M 延时计算公式 = 2.88+(n-1)*0.75 us
  116. //

  117. //ms级别的延时函数
  118. void delayms(unsigned int lms)
  119. {
  120.         while(lms--)
  121.         {
  122.                 delayus(1000);        //延时1ms
  123.     }
  124. }
  125. //-------------------------------------------------------
  126. //USART
  127. //-------------------------------------------------------
  128. uchar rdata,flag=0;
  129. void uart_init(uint baud)
  130. {
  131.     UCSRB=0x00;
  132.    UCSRA=0x00;                     //控制寄存器清零
  133.    UCSRC=(1<<URSEL)|(0<<UPM0)|(3<<UCSZ0);   
  134.                                                         //选择UCSRC,异步模式,禁止                        
  135.                                                      //   校验,1位停止位,8位数据位
  136.    baud=mclk/16/baud-1        ;   //波特率最大为65K
  137.    UBRRL=baud;                                                        
  138.    UBRRH=baud>>8;                    //设置波特率
  139.    UCSRB=(1<<TXEN)|(1<<RXEN)|(1<<RXCIE);
  140.                                                        //接收、发送使能,接收中断使能
  141.    SREG=BIT(7);                        //全局中断开放
  142.    DDRD|=0X02;                        //配置TX为输出(很重要)

  143. }
  144. void uart_sendB(uchar data)
  145. {
  146.    while(!(UCSRA&(BIT(UDRE)))) ;
  147.    UDR=data;
  148.    while(!(UCSRA&(BIT(TXC))));
  149.    UCSRA|=BIT(TXC);
  150. }
  151. void uart_rx(void)
  152. {
  153.     UCSRB&=~BIT(RXCIE);
  154.         rdata=UDR;
  155.         flag=1;
  156.         UCSRB|=BIT(RXCIE);
  157. }
  158. //-------------------------------------------------------
  159. //I2C初始化
  160. //--
  161. void I2C_Init(void)
  162. {
  163.         PORTC &= ~(1 << PC0);    //SCL的PORT状态锁定为0,以后不再改变
  164.         DDRC &= ~(1 << PC0);   //SCL设置为输入口
  165.        
  166.         PORTC &= ~(1 << PC1);    //SDA的PORT状态锁定为0,以后不再改变
  167.         DDRC &= ~(1 << PC1);    //SDA设置为输入口
  168.         delayus(10);
  169. }
  170. //-------------------------------------------------------
  171. //I2C起始信号
  172. //在SCL为高电平的时候,SDA由高电平向低电平跳变,开始传送数据
  173. //-------------------------------------------------------
  174. void I2C_Start(void)
  175. {
  176.     EN_SDA_1;                                         //使能输出
  177.        
  178.         Hign_SDA;                    //拉高数据线
  179.     Hign_SCL;                    //拉高时钟线
  180.     delayus(5);
  181.         Low_SDA;                    //产生下降沿
  182.     delayus(5);
  183.         Low_SCL;
  184. }

  185. //-------------------------------------------------------
  186. //I2C停止信号
  187. //在SCL为高电平的时候,SDA由低电平向高电平跳变,结束传送数据
  188. //-------------------------------------------------------
  189. void I2C_Stop(void)
  190. {
  191.     EN_SDA_1;                                         //使能输出
  192.        
  193.         Low_SDA;
  194.     Hign_SCL;         
  195.         delayus(5);
  196. //        Hign_SCL;            
  197.     Hign_SDA;                  
  198.     delayus(5);                 
  199. }

  200. //-------------------------------------------------------
  201. //I2C产生应答信号
  202. //-------------------------------------------------------
  203. void I2C_Ack(void)
  204. {
  205.     Low_SCL;
  206.         EN_SDA_1;                   //使能SDA输出
  207.        
  208.         Low_SDA;
  209.         delayus(5);
  210.         Hign_SCL;
  211.         delayus(5);
  212.         Low_SCL;
  213.         delayus(5);         
  214. }

  215. //-------------------------------------------------------
  216. //I2C不产生应答信号
  217. //-------------------------------------------------------
  218. void I2C_NoAck(void)
  219. {
  220.     Low_SCL;
  221.         EN_SDA_1;                   //使能SDA输出
  222.        
  223.         Hign_SDA;
  224.         delayus(5);
  225.         Hign_SCL;
  226.         delayus(5);
  227.         Low_SCL;       
  228.         delayus(5);   
  229. }

  230. /*******************************************************************************
  231. * Function Name  : I2C_WaitAck
  232. * Input          : None
  233. * Output         : 1,接收应答失败
  234.                    0,接收应答成功
  235. * Return         : Wheather         Reserive Slave Acknowledge Single
  236. ****************************************************************************** */
  237. uchar I2C_WaitAck(void)          //返回为:=1有ACK,=0无ACK
  238. {
  239.         uchar errTime = 0;
  240.         EN_SDA_0;
  241.         Hign_SDA;
  242.         delayus(10);
  243.         Hign_SCL;
  244.         delayus(10);
  245.         while(Read_SDA)
  246.         {
  247.                 errTime++;
  248.                 if(errTime>250)
  249.                 {
  250.                         I2C_Stop();
  251.                         return 1;
  252.                 }
  253.         }
  254.         Low_SCL;//时钟输出0           
  255.         return 0;
  256. }

  257. //-------------------------------------------------------
  258. //向I2C总线发送一个字节数据
  259. //返回从机有无应答,1,有应答,0,无应答
  260. //-------------------------------------------------------
  261. void I2C_SendByte(uchar dat)
  262. {
  263.     uchar i;
  264.         EN_SDA_1;                   //使能SDA输出
  265.    
  266.         Low_SCL;
  267.     for (i=0; i<8; i++)         //8位计数器
  268.     {               
  269.                 if(dat & 0x80)
  270.          {Hign_SDA;}
  271.         else
  272.          {Low_SDA;}
  273.                 dat <<= 1;              //移出数据的最高位
  274.         Hign_SCL;                                //SCL高电平,保持数据                                  
  275.         delayus(10);
  276.                 Low_SCL;                                //SCL低电平,数据被送入I2C
  277.         delayus(10);
  278.         }
  279. }

  280. //-------------------------------------------------------
  281. //从I2C总线接收一个字节数据
  282. //ack=1时,发送ACK,ack=0,发送nACK  
  283. //-------------------------------------------------------
  284. uchar I2C_RecvByte(uchar ack)
  285. {
  286.     uchar i;
  287.     uchar dat = 0;
  288.         EN_SDA_0;                   //使能SDA输入

  289.     for (i=0; i<8; i++)         //8位计数器
  290.     {      
  291.         Low_SCL;
  292.                 delayus(10);
  293.                 Hign_SCL;
  294.                 dat <<= 1;
  295.                 if(Read_SDA) dat++;       
  296.         delayus(10);               
  297.     }

  298.         if(!ack)
  299.         {
  300.           I2C_NoAck();
  301.         }
  302.         else
  303.         {
  304.           I2C_Ack();
  305.         }      
  306.     return dat;
  307. }

  308. //-------------------------------------------------------
  309. //向I2C设备写入一个字节数据
  310. //-------------------------------------------------------
  311. void Single_WriteI2C(uchar REG_Address,uchar REG_data)
  312. {                  
  313.         I2C_Start();                                     //起始信号
  314.     I2C_SendByte(SlaveAddress);   //发送设备地址+写信号
  315.         I2C_WaitAck();
  316.     I2C_SendByte(REG_Address);    //内部寄存器地址
  317.         I2C_WaitAck();
  318.     I2C_SendByte(REG_data);       //内部寄存器数据
  319.         I2C_WaitAck();
  320.     I2C_Stop();                   //发送停止信号
  321. }

  322. //-------------------------------------------------------
  323. //从I2C设备读取一个字节数据
  324. //-------------------------------------------------------
  325. uchar Single_ReadI2C(uchar REG_Address)
  326. {
  327.         uchar REG_data;
  328.         I2C_Start();                   //起始信号
  329.         I2C_SendByte(SlaveAddress);    //发送设备地址+写信号
  330.         I2C_WaitAck();
  331.         I2C_SendByte(REG_Address);     //发送存储单元地址,从0开始       
  332.         I2C_WaitAck();
  333.         I2C_Start();                   //起始信号
  334.         I2C_SendByte(SlaveAddress+1);  //发送设备地址+读信号
  335.         I2C_WaitAck();
  336.         REG_data=I2C_RecvByte(0);       //读出寄存器数据               
  337.         I2C_Stop();                    //停止信号
  338.         return REG_data;
  339. }

  340. //-------------------------------------------------------
  341. //初始化MPU6050
  342. //-------------------------------------------------------
  343. void InitMPU6050(void)
  344. {
  345.         Single_WriteI2C(PWR_MGMT_1, 0x00);        //解除休眠状态
  346.         Single_WriteI2C(SMPLRT_DIV, 0x07);
  347.         Single_WriteI2C(CONFIG, 0x06);
  348.         Single_WriteI2C(GYRO_CONFIG, 0x18);
  349.         Single_WriteI2C(ACCEL_CONFIG, 0x01);
  350. }

  351. //-------------------------------------------------------
  352. //合成数据
  353. //-------------------------------------------------------
  354. int GetData(uchar REG_Address)
  355. {
  356.         uint H;
  357.         uchar L;
  358.         H=Single_ReadI2C(REG_Address);
  359.         L=Single_ReadI2C(REG_Address+1);
  360.         return (H<<8)+L;   //合成数据
  361. }

  362. #endif
复制代码

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

 楼主| 发表于 2013-5-8 08:34:03 | 显示全部楼层
大神呢?
自顶。。。

出0入0汤圆

发表于 2013-8-3 20:35:24 | 显示全部楼层
请问楼主的问题得到解决了吗,我也正困惑呢,要是楼主完成了希望分享一下

出0入0汤圆

发表于 2013-10-14 21:09:04 | 显示全部楼层
我也遇到了跟你同样的问题,读出的寄存器值全部都是255,迷茫无助了,求神兵天降。。。楼主解决了能告知一下吗?

出0入0汤圆

发表于 2013-10-14 21:16:44 | 显示全部楼层
兄弟给你个治疗吧,这种问题只有靠时间来解决,熟悉的工程师 估计10分钟搞定,本身找问题也是种学习

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2013-10-16 17:22:04 | 显示全部楼层
兄弟,我的问题今天解决了,问题出在IIC上了。我的是忘记了应答信号,拔下模块也是返回FF,你用示波器试试看跟我的问题一样吗。

出0入0汤圆

发表于 2014-1-2 20:13:12 | 显示全部楼层
兄弟给我指点指点吧

出0入0汤圆

发表于 2014-1-6 15:10:07 | 显示全部楼层
我的问题是mpu6050 id 是FF,是什么问题,求救啊

出0入0汤圆

发表于 2014-5-12 21:06:48 | 显示全部楼层
这种问题最好对照示波器去检查一遍,使用stm32模拟的I2C程序,发现不知道是谁挖了个坑,如下
AD+R填错了,所以读出全为FF。大家留点心!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2014-5-27 22:32:32 | 显示全部楼层
是不是论坛里的程序?我也是用的这个,读不出来,只要把 I2C_Stop();改成 Low_SCL;就OK了;你试试

uchar I2C_WaitAck(void)          //返回为:=1有ACK,=0无ACK
{
        uchar errTime = 0;
        EN_SDA_0;
        Hign_SDA;
        delayus(10);
        Hign_SCL;
        delayus(10);
        while(Read_SDA)
        {
                errTime++;
                if(errTime>250)
                {
                        I2C_Stop();
                        return 1;
                }
        }
        Low_SCL;//时钟输出0            
        return 0;
}

出0入0汤圆

发表于 2015-2-5 15:56:07 | 显示全部楼层
我也遇到这个问题了,全部是FF,楼主解决了吗?
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-16 01:45

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表