Edwardchenwei 发表于 2014-7-29 23:43:03

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

我用IAR给cc2530编写程序读取MPU6050数据,可是通过串口传回的数据确实一直不变动, 只有按了复位键才会变动一下,然后又是一直不变动。在C51单片机上测试完全没有问题。
下面是IAR的代码
#include <iocc2530.h>
#include <math.h>    //Keil library
#include <stdio.h>   //Keil library       
#include <intrinsics.h>
typedef unsigned charuchar;
typedef unsigned short ushort;
typedef unsigned int   uint;

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

#define_SDAP0_6
#define_SDA_DIRP0DIR
#define_SDA_BV   BV(6)

#define_SCLP0_7
#define_SCL_DIRP0DIR
#define_SCL_BV   BV(7)

#define_SDA_INst((_SDA_DIR)&=~(_SDA_BV);)
#define_SDA_OUT st((_SDA_DIR)|=(_SDA_BV);)
#define_SCL_INst((_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;                                //显示数字(-511至512)的字符数组
//****************************************
//函数声明
//****************************************
voiddelayms(unsigned int k);                                //延时                                               
voidtest(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='-';
        }
        else dis=' ';

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

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

        dis =temp_data/100+0x30;
        temp_data=temp_data%100;   //取余运算
      
        dis =temp_data/10+0x30;
        temp_data=temp_data%10;      //取余运算
      
        dis =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;
    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出错了。你检查下停止代码。void _Stop(void)
{
    _SDA_0;
    _SCL_1;
   NOP();
    _SDA_0;
   NOP();
    _SCL_0;
   NOP();
}
页: [1]
查看完整版本: 新手问一个用cc2530读取MPU6050的问题