极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 11256|回复: 1

新手问一个用cc2530读取MPU6050的问题

[复制链接]
发表于 2014-7-29 23:43:03 | 显示全部楼层 |阅读模式
我用IAR给cc2530编写程序读取MPU6050数据,可是通过串口传回的数据确实一直不变动, 只有按了复位键才会变动一下,然后又是一直不变动。在C51单片机上测试完全没有问题。
下面是IAR的代码
#include <iocc2530.h>
#include <math.h>    //Keil library  
#include <stdio.h>   //Keil library       
#include <intrinsics.h>
typedef unsigned char  uchar;
typedef unsigned short ushort;
typedef unsigned int   uint;

#define BV(n)      (1 << (n))
#define st(x)      do { x } while (__LINE__ == -1)

#define  _SDA  P0_6
#define  _SDA_DIR  P0DIR
#define  _SDA_BV   BV(6)

#define  _SCL  P0_7
#define  _SCL_DIR  P0DIR
#define  _SCL_BV   BV(7)

#define  _SDA_IN  st((_SDA_DIR)&=~(_SDA_BV);)
#define  _SDA_OUT st((_SDA_DIR)|=(_SDA_BV);)
#define  _SCL_IN  st((_SCL_DIR)&=~(_SCL_BV);)
#define  _SCL_OUT st((_SCL_DIR)|=(_SCL_BV);)

#define  _SDA_1   st(_SDA_OUT;_SDA=1;)
#define  _SDA_0   st(_SDA_OUT;_SDA=0;)
#define  _SCL_1   st(_SCL_OUT;_SCL=1;)
#define  _SCL_0   st(_SCL_OUT;_SCL=0;)

//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 MPU6050_SA_W   0xD0
#define MPU6050_SA_R   0xD1

//****************************************
//定义类型及变量
//****************************************
uchar dis[6];                                //显示数字(-511至512)的字符数组
//****************************************
//函数声明
//****************************************
void  delayms(unsigned int k);                                //延时                                               
void  test(int temp_data);
void _Start(void);
void _Stop(void);
void _Port_Init(void);
uchar _Wait_ACK(void);
uchar _Write(uchar data);
uchar _Read();
uchar _Write_Data(uchar addr,uchar wd);//数据写入
uchar _Read_Data(uchar addr);//数据读出
void  _MPU_Init(void);

//****************************************
//整数转字符串
//****************************************
void test(int temp_data)
{
        if(temp_data<0)
        {
                temp_data=-temp_data;
                dis[0]='-';
        }
        else dis[0]=' ';

        dis[1] =temp_data/10000+0x30;
        temp_data=temp_data%10000;     //取余运算

        dis[2] =temp_data/1000+0x30;
        temp_data=temp_data%1000;     //取余运算

        dis[3] =temp_data/100+0x30;
        temp_data=temp_data%100;     //取余运算
        
        dis[4] =temp_data/10+0x30;
        temp_data=temp_data%10;      //取余运算
        
        dis[5] =temp_data+0x30;        
}
/****************************************************/
/************************串口************************/
/****************************************************/
void UartInitial()
{
  PERCFG = 0x00;
  P0SEL = 0x0c;
  P2DIR &= ~0xc0;
  U0CSR |= 0x80;//设置串口
  U0GCR |= 11;
  U0BAUD |= 216;//波特率设为115200
  U0CSR |= 0x40;
  UTX0IF = 0;
}

void UartSend(uchar infor)
{
  U0DBUF = infor;
  while(UTX0IF == 0);
  UTX0IF = 0;
}

void UartTX_Send_String(int value,int len)
{
  int j;
  test(value);       
  for(j=0;j<len;j++)
  {
    U0DBUF = dis[j];
    while(UTX0IF == 0);
    UTX0IF = 0;
  }
}


//****************************************
//延时
//****************************************
void delayms(unsigned int k)       
{                                               
        unsigned int i,j;                               
        for(i=0;i<k;i++)
        {                       
                for(j=0;j<1000;j++);
        }                                               
}

void NOP()
{
  int t=5;
  while(t--)
  {
    /* 32 NOPs == 1 usecs */
    asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
    asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
    asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
    asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
    asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
    asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
    asm("nop"); asm("nop");
  }
}

//SCL为高电平时,SDA发生高到低跳变
void _Start(void)
{
    _SDA_1;
    _SCL_1;
     NOP();
    _SDA_0;
     NOP();
    _SCL_0;
     NOP();
}
//SCL为高电平时,SDA发生低到高跳变
void _Stop(void)
{
    _SDA_0;
    _SCL_1;
     NOP();
    _SDA_0;
     NOP();
    _SCL_0;
     NOP();
}
void _Port_Init(void)
{
    _SDA_1;
    NOP();
    _SCL_1;
    NOP();
}
uchar _Wait_ACK(void)
{
    uchar bc=0;
    uint i=1000;
    _SDA_IN;
    _SCL_1;
    NOP();
    do{
    if(_SDA==0)
      break;
    }while(i--);
    bc=_SDA;
    _SCL_0;
    _SDA_OUT;
    return bc;
}
uchar _Write(uchar data)
{
   uchar i;
   _SDA_OUT;
   _SCL_0;
   for(i=0;i<8;i++)
   {
     if(data&0x80)
     {
       _SDA_1;
     }
     else
     {
       _SDA_0;
     }
     data<<=1;
     _SCL_1;
     NOP();
     _SCL_0;
     NOP();
   }
   _SDA_1;//释放总线
   if(_Wait_ACK()==0)//ACK
   {
     return 1;
   }
   else
   {
     return 0;
   }
}
uchar _Read()
{
   uchar data=0;
   uchar i;
   _SDA_IN;
   _SCL_0;
   NOP();
   for(i=0;i<8;i++)
   {
     _SCL=1;
     NOP();
     data<<=1;
     if(_SDA)
     {
       data|=1;
     }
     _SCL=0;
     NOP();
   }
   _SDA_OUT;
   _SCL_0;
   NOP();
   return data;
}
//数据写入
uchar _Write_Data(uchar addr,uchar wd)
{
      _Start();
      if(_Write(MPU6050_SA_W))//Slave address+R/W    0xD0+0/1
      {
          if(_Write(addr))
          {
              if(_Write(wd))
              {
                _Stop();
                NOP();
                return wd;
              }
              return 0xf3;
          }
          return 0xf2;
      }
      else
        return 0xf1;
}
uchar _Read_Data(uchar addr)//数据读出
{
       uchar rd;
      _Start();
      if(_Write(MPU6050_SA_W))
      {
        if(_Write(addr))
        {
          _Start();
          if(_Write(MPU6050_SA_R))
          {
            rd=_Read();
            if(_Wait_ACK())///NoACk
            _Stop();
            NOP();
            return rd;
          }
          return 0xf3;
        }
        return 0xf2;
      }
      return 0xf1;
}
void  _MPU_Init(void)
{
   _Port_Init();
   _Write_Data(PWR_MGMT_1, 0x00);        //解除休眠状态
   _Write_Data(SMPLRT_DIV, 0x07);
   _Write_Data(CONFIG, 0x06);
   _Write_Data(GYRO_CONFIG, 0x18);
   _Write_Data(ACCEL_CONFIG, 0x01);
}
//**************************************
//合成数据
//**************************************
int GetData(uchar REG_Address)
{
        uchar H,L;
        H=_Read_Data(REG_Address);
        L=_Read_Data(REG_Address+1);
        return (H<<8)+L;   //合成数据
}

//*********************************************************
//主程序
//*********************************************************
void main()
{       
        CLKCONCMD = 0x80;      //选择 32M 振荡器
        while(CLKCONSTA&0x40); //等待晶振稳定
        P0SEL &= 0x3f;
        UartInitial();
        _MPU_Init();
        while(1)
        {
                UartTX_Send_String(GetData(ACCEL_XOUT_H),6);        //显示X轴加速度
                UartTX_Send_String(GetData(ACCEL_YOUT_H),6);        //显示Y轴加速度
                UartTX_Send_String(GetData(ACCEL_ZOUT_H),6);        //显示Z轴加速度
                UartTX_Send_String(GetData(GYRO_XOUT_H),6);        //显示X轴角速度
                UartTX_Send_String(GetData(GYRO_YOUT_H),6);        //显示Y轴角速度
                UartTX_Send_String(GetData(GYRO_ZOUT_H),6);        //显示Z轴角速度
                UartSend('\n');
                delayms(1000);
        }
}

继续解答啊,求大神帮帮忙!
回复

使用道具 举报

发表于 2014-8-6 18:42:56 | 显示全部楼层
哥们,借了你的代码,调试了下,应该是I2C出错了。你检查下停止代码。
  1. void _Stop(void)
  2. {
  3.     _SDA_0;
  4.     _SCL_1;
  5.      NOP();
  6.     _SDA_0;
  7.      NOP();
  8.     _SCL_0;
  9.      NOP();
  10. }
复制代码
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|联系我们|极客工坊

GMT+8, 2026-6-14 17:53 , Processed in 0.045289 second(s), 19 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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