微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 无线和射频 > TI蓝牙设计交流 > CC2540直接读MPU6050,前天运行OK,今天运行不行了?

CC2540直接读MPU6050,前天运行OK,今天运行不行了?

时间:10-02 整理:3721RD 点击:

//**************************************** // GY-52 MPU3050 IIC测试程序 // 使用单片机STC89C51 // 晶振:11.0592M // 显示:LCD1602 // 编译环境 Keil uVision2 // 参考宏晶网站24c04通信程序 // 时间:2011年9月1日 // QQ:531389319 //第X作者Btz23,QQ357074909 日期:20140525 2030 //****************************************

#include <math.h>    //Keil library  #include <stdio.h>   //Keil library  #include <ioCC2540.h> #include "hal_types.h"

 

#define MPU6050_DMP_UPDATES_SIZE    47

 

 

//**************************************** //定义CC2540端口 //**************************************** #define DataPort P0                                 #define    SDA P1_3                           // #define    SCL P1_4                           //

//sbit    LCM_RS=P2^0;                                  // //sbit    LCM_RW=P2^1;                                  //  //sbit    LCM_EN=P2^2;                                  //

//**************************************** //定义类型及变量 //**************************************** char   dis[6];       //显示数字(-511至512)的字符数组 int dis_data;      //变量 int Temperature,Temp_h,Temp_l;                         //温度及高低位数据

//**************************************** //函数声明 //**************************************** void  delay(unsigned int k);            //延时  //void Print_Dec_Char(uchar *s,float  temp_data);

//void  lcd_printf(uchar *s,int temp_data);

//MPU6050操作函数

 

//**************************************** //整数转字符串 //****************************************

/*void Print_Dec_Char(char *s,float  temp_data) {         if(temp_data<0)  {   temp_data=-temp_data;   *s='-';  }  else *s=' ';                 int temp5=temp_data*1000;        

         *++s =temp5/1000000+0x30;  temp5=temp5%1000000;     //取余运算                 *++s =temp5/100000+0x30;  temp5=temp5%100000;     //取余运算          *++s =temp5/10000+0x30;  temp5=temp5%10000;     //取余运算

 *++s =temp5/1000+0x30;  temp5=temp5%1000;     //取余运算

        *++s='.';          *++s =temp5/100+0x30;  temp5=temp5%100;     //取余运算          *++s =temp5/10+0x30;         temp5=temp5%10;      //取余运算          *++s =temp5+0x30;   }

//**************************************** void lcd_printf(char *s,int temp_data) {   //double Temp2;       if(temp_data<0)  {   temp_data=-temp_data;   *s='-';  }  else *s=' ';                  //temp_data=temp_data*1000;

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

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

 *++s =temp_data/100+0x30;  temp_data=temp_data%100;     //取余运算  *++s =temp_data/10+0x30;  temp_data=temp_data%10;      //取余运算  *++s =temp_data+0x30;   }*/

void  SeriPushSend(uchar send_data) {     U0DBUF=send_data;      while(UTX0IF == 0);       UTX0IF = 0;   } //**************************************** //延时 //**************************************** void delay(unsigned int k)  {        unsigned int i,j;      for(i=0;i<k;i++)  {      for(j=0;j<121;j++);  }       }

//************************************** //延时5微秒(STC90C52RC@12M) //不同的工作环境,需要调整此函数 //当改用1T的MCU时,请调整此延时函数 //************************************** void Delay5us(int microSecs)  //对应一个指令是多少时间,在规格书中难找,在HAO_LCD中找到下面的延时程序,更改之,修改201405252039 {    while(microSecs--)   {     /* 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");   } } //************************************** //I2C起始信号 //************************************** void I2C_Start() {     SDA = 1;                    //拉高数据线     SCL = 1;                    //拉高时钟线     Delay5us(5);                //延时     SDA = 0;                    //产生下降沿     Delay5us(5);                //延时     SCL = 0;                    //拉低时钟线 } //************************************** //I2C停止信号 //************************************** void I2C_Stop() {     SDA = 0;                    //拉低数据线     SCL = 1;                    //拉高时钟线     Delay5us(5);                //延时     SDA = 1;                    //产生上升沿     Delay5us(5);                //延时 } //************************************** //I2C发送应答信号 //入口参数:ack (0:ACK 1:NAK) //************************************** void I2C_SendACK(int ack) {     SDA = ack;                  //写应答信号     SCL = 1;                    //拉高时钟线     Delay5us(5);                //延时     SCL = 0;                    //拉低时钟线     Delay5us(5);                //延时 } //************************************** //I2C接收应答信号 //************************************** int I2C_RecvACK() {     SCL = 1;                    //拉高时钟线         P1DIR=0x05;                 //设定为输入 btz     Delay5us(5);                //延时     int CY = SDA;               //读应答信号                      SCL = 0;                    //拉低时钟线         P1DIR=0xFF;                 //这里在单步执行时,没将输入变为输出,接下来的数据就写不进,更改之,修改201405252039     Delay5us(5);                //延时     return CY; } //************************************** //向I2C总线发送一个字节数据 //************************************** void I2C_SendByte(uint8_t dat) {     uchar i;          for (i=0; i<8; i++)         //8位计数器     {                 if(dat&0x80)                SDA = 1;              //送数据口 开如用CY,今天单步执行就不行了?         else if(dat&0x80)          //原来是没有这句语名,当SDA为1时赋值后,转而按续执行,SDA又赋0值了,更改之,修改201405252039           SDA=0;         SCL = 1;                //拉高时钟线         Delay5us(5);            //延时         SCL = 0;                //拉低时钟线         Delay5us(5);            //延时         dat <<= 1;              //移出数据的最高位     }                I2C_RecvACK(); } //************************************** //从I2C总线接收一个字节数据 //************************************** uchar I2C_RecvByte() {     uchar i;     uchar dat = 0;     P1DIR &= ~0X05;             //设SDA脚为输入 btz;     //P0INP=0x02;     //SDA = 1;                  //使能内部上拉,准备读取数据,     for (i=0; i<8; i++)         //8位计数器     {         dat <<= 1;         SCL = 1;                //拉高时钟线          Delay5us(5);            //延时         dat |= SDA;             //读数据                  SCL = 0;                //拉低时钟线         Delay5us(5);            //延时     }     P1DIR |= 0xFF;              //重新设定为输输 btz;      return dat; } //************************************** //向I2C设备写入一个字节数据 //************************************** void Single_WriteI2C(uchar REG_Address,uint8_t REG_data) {     I2C_Start();                  //起始信号     I2C_SendByte(SlaveAddress);   //发送设备地址+写信号     I2C_SendByte(REG_Address);    //内部寄存器地址,     I2C_SendByte(REG_data);       //内部寄存器数据,     I2C_Stop();                   //发送停止信号 } //************************************** //从I2C设备读取一个字节数据 //**************************************

uint8 Single_ReadI2C_B(uchar REG_Address)//注意数据类型 {  uint8 REG_data_b;  I2C_Start();                   //起始信号  I2C_SendByte(SlaveAddress);    //发送设备地址+写信号  I2C_SendByte(REG_Address);     //发送存储单元地址,从0开始   I2C_Start();                   //起始信号  I2C_SendByte(SlaveAddress+1);  //发送设备地址+读信号  REG_data_b=I2C_RecvByte();       //读出寄存器数据  I2C_SendACK(1);                //接收应答信号  I2C_Stop();                    //停止信号  return REG_data_b; }

uchar Single_ReadI2C(uchar REG_Address) {  uchar REG_data;  I2C_Start();                   //起始信号  I2C_SendByte(SlaveAddress);    //发送设备地址+写信号  I2C_SendByte(REG_Address);     //发送存储单元地址,从0开始   I2C_Start();                   //起始信号  I2C_SendByte(SlaveAddress+1);  //发送设备地址+读信号  REG_data=I2C_RecvByte();       //读出寄存器数据  I2C_SendACK(1);                //接收应答信号  I2C_Stop();                    //停止信号  return REG_data; } //************************************** //初始化MPU6050 //************************************** void InitMPU6050() {  Single_WriteI2C(PWR_MGMT_1, 0x00); //解除休眠状态  Single_WriteI2C(SMPLRT_div, 0x07);//  Single_WriteI2C(CONFIG, 0x06);//  Single_WriteI2C(GYRO_CONFIG, 0x18);//  Single_WriteI2C(ACCEL_CONFIG, 0x01);// } //************************************** //合成数据 //************************************** uchar GetData(uchar REG_Address) {  uchar H,L;  H=Single_ReadI2C(REG_Address);  L=Single_ReadI2C(REG_Address+1);  return (H<<8)+L;                         //合成数据 } //************************************** //在1602上显示10位数据 //************************************** void Display10BitData(int value,uchar x,uchar y) {  uchar i; // value/=64;    //转换为10位数据  lcd_printf(dis, value);   //转换数据显示  for(i=0;i<6;i++)  {     SeriPushSend(dis[i]);     }

  //  DisplayListChar(x,y,dis,4);        //启始列,行,显示数组,显示长度 } //************************************** //显示温度 //************************************** //void display_temp() //{ // Temp_h=Single_ReadI2C(TEMP_OUT_H); //读取温度 // Temp_l=Single_ReadI2C(TEMP_OUT_L); //读取温度 // Temperature=Temp_h<<8|Temp_l;     //合成温度 // Temperature = 35+ ((double) (Temperature + 13200)) / 280; // 计算出温度 // lcd_printf(dis,Temperature);     //转换数据显示 // DisplayListChar(11,1,dis,4);     //启始列,行,显示数组,显示位数 //}

void InitUART(void) { PERCFG = 0x00;                  //位置 1 P0 口 P0SEL = 0x0c;                   //P0_2,P0_3 用作串口(外部设备功能) P2DIR &= ~0XC0;                 //P0 优先作为 UART0 U0CSR |= 0x80;                  //设置为 UART 方式 U0GCR |= 11;         U0BAUD |= 216;                  //波特率设为 115200 UTX0IF = 0;                     //UART0 TX 中断标志初始置位 0 }

void UartSend_String(uchar *Data,int len) {

  int j; for(j=0;j<len;j++) { U0DBUF = *Data++; while(UTX0IF == 0); UTX0IF = 0; } }

void Printf_float(float tempdata1) {   int temp3;   temp3=tempdata1*1000;      lcd_printf(dis,temp3); }

void System_CC2540_init() {    P0SEL = 0x07;           P1DIR =0xFF;           //重设定为输出 btz           //P1INP &=~0X01;       //打开上拉     }

/******

****/

 

#define LED1 P1_0

//InitLcd();  //液晶初始化       

void main() {            float temp1;         int tempx[47];  int k;

        delay(500);         //上电延时         System_CC2540_init();          InitMPU6050();         //初始化MPU6050                                                Single_WriteI2C(MPU6050_RA_PWR_MGMT_1,0x59);               char gyro_b=Single_ReadI2C(GYRO_CONFIG);     // 测试MPU6050读写是否正常                 while(1)  {                           SeriPushSend(0x0d);         SeriPushSend(0x0a);                                             //换行,回车  delay(100);  } }

tz,

这,这代码看得亚历山大啊。。。

能描述地详细点吗?

谢谢Yan,也表示抱歉!拷上去,网站排版出来就是这个样子啦,再贴

//****************************************

// GY-52 MPU3050 IIC测试程序 // 使用单片机STC89C51

// 晶振:11.0592M // 显示:LCD1602

 // 编译环境 Keil uVision2 // 参考宏晶网站24c04通信程序

 // 时间:2011年9月1日 // QQ:531389319

//第X作者Btz23,QQ357074909 日期:20140525 2030 //****************************************

#include <math.h>    //Keil library 

 #include <stdio.h>   //Keil library 

 #include <ioCC2540.h> #include "hal_types.h"

 

#define MPU6050_DMP_UPDATES_SIZE    47

 

 

//**************************************** //定义CC2540端口 //****************************************

 #define DataPort P0                               

  #define    SDA P1_3                          

// #define    SCL P1_4                          

 

 

//****************************************

 //定义类型及变量

//****************************************

 char   dis[6];       //显示数字(-511至512)的字符数组

 int dis_data;      //变量

 int Temperature,Temp_h,Temp_l;                         //温度及高低位数据

//**************************************** //函数声明 //****************************************

void  delay(unsigned int k);            //延时

  //void Print_Dec_Char(uchar *s,float  temp_data);

//void  lcd_printf(uchar *s,int temp_data);

//MPU6050操作函数

 

 

 

 

void  SeriPushSend(uchar send_data)

 {    

              U0DBUF=send_data;     

              while(UTX0IF == 0);      

              UTX0IF = 0;   }

//**************************************** //延时 //****************************************

void delay(unsigned int k) 

 {        unsigned int i,j;    

      for(i=0;i<k;i++)  

         {      

          for(j=0;j<121;j++);

        }      

}

//************************************** //延时5微秒(STC90C52RC@12M)

//不同的工作环境,需要调整此函数

//当改用1T的MCU时,请调整此延时函数

 //**************************************

 void Delay5us(int microSecs)  //对应一个指令是多少时间,在规格书中难找,在HAO_LCD中找到下面的延时程序,更改之,修改201405252039

 {    while(microSecs--)  

 {     /* 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");   }

 }

//************************************** //I2C起始信号 //**************************************

void I2C_Start()

 {    

             SDA = 1;                    //拉高数据线    

              SCL = 1;                    //拉高时钟线    

             Delay5us(5);                //延时    

             SDA = 0;                    //产生下降沿    

             Delay5us(5);                //延时    

              SCL = 0;                    //拉低时钟线 }

//************************************** //I2C停止信号 //**************************************

void I2C_Stop()

{    

              SDA = 0;                    //拉低数据线    

             SCL = 1;                    //拉高时钟线    

              Delay5us(5);                //延时    

              SDA = 1;                    //产生上升沿    

             Delay5us(5);                //延时

 }

//**************************************

//I2C发送应答信号

 //入口参数:ack (0:ACK 1:NAK)

 //**************************************

 void I2C_SendACK(int ack)

{    

             SDA = ack;                  //写应答信号    

              SCL = 1;                    //拉高时钟线    

              Delay5us(5);                //延时    

              SCL = 0;                    //拉低时钟线    

             Delay5us(5);                //延时

}

 //************************************** //I2C接收应答信号 //**************************************

int I2C_RecvACK()

{    

             SCL = 1;                    //拉高时钟线        

             P1DIR=0x05;                 //设定为输入 btz    

             Delay5us(5);                //延时    

              int CY = SDA;               //读应答信号                     

             SCL = 0;                    //拉低时钟线        

             P1DIR=0xFF;                 //这里在单步执行时,没将输入变为输出,接下来的数据就写不进,更改之,修改201405252039    

             Delay5us(5);                //延时    

              return CY;

}

//************************************** //向I2C总线发送一个字节数据 //**************************************

void I2C_SendByte(uint8_t dat)

{    

      uchar i;         

      for (i=0; i<8; i++)         //8位计数器    

       {                

         if(dat&0x80)               

         SDA = 1;              //送数据口 开如用CY,今天单步执行就不行了?        

         else if(dat&0x80)          //原来是没有这句语名,当SDA为1时赋值后,转而按续执行,SDA又赋0值了,更改之,修改201405252039          

         SDA=0;        

         SCL = 1;                //拉高时钟线        

        Delay5us(5);            //延时        

         SCL = 0;                //拉低时钟线        

         Delay5us(5);            //延时        

        dat <<= 1;              //移出数据的最高位  

       }               

    I2C_RecvACK();

 }

 //************************************** //从I2C总线接收一个字节数据 //**************************************

 uchar I2C_RecvByte()

 {    

        uchar i;    

        uchar dat = 0;    

        P1DIR &= ~0X05;             //设SDA脚为输入 btz;    

        //P0INP=0x02;    

        //SDA = 1;                  //使能内部上拉,准备读取数据,    

        for (i=0; i<8; i++)         //8位计数器    

          {

             dat <<= 1;

             SCL = 1;                //拉高时钟线

             Delay5us(5);            //延时

             dat |= SDA;             //读数据  

             SCL = 0;                //拉低时钟线  

              Delay5us(5);            //延时   

  }    

       P1DIR |= 0xFF;              //重新设定为输输 btz;

      return dat;

 }

//************************************** //向I2C设备写入一个字节数据 //**************************************

void Single_WriteI2C(uchar REG_Address,uint8_t REG_data)

{    

      I2C_Start();                  //起始信号    

      I2C_SendByte(SlaveAddress);   //发送设备地址+写信号

     I2C_SendByte(REG_Address);    //内部寄存器地址,

     I2C_SendByte(REG_data);       //内部寄存器数据,

     I2C_Stop();                   //发送停止信号

}

//************************************** //从I2C设备读取一个字节数据 //**************************************

uint8 Single_ReadI2C_B(uchar REG_Address)//注意数据类型

{  

     uint8 REG_data_b;  I2C_Start();                   //起始信号

      I2C_SendByte(SlaveAddress);    //发送设备地址+写信号

      I2C_SendByte(REG_Address);     //发送存储单元地址,从0开始

      I2C_Start();                   //起始信号

      I2C_SendByte(SlaveAddress+1);  //发送设备地址+读信号

      REG_data_b=I2C_RecvByte();       //读出寄存器数据

      I2C_SendACK(1);                //接收应答信号

      I2C_Stop();                    //停止信号

     return REG_data_b;

}

uchar Single_ReadI2C(uchar REG_Address)

{  uchar REG_data;

          I2C_Start();                   //起始信号

          I2C_SendByte(SlaveAddress);    //发送设备地址+写信号

          I2C_SendByte(REG_Address);     //发送存储单元地址,从0开始 

          I2C_Start();                   //起始信号  

         I2C_SendByte(SlaveAddress+1);  //发送设备地址+读信号

         REG_data=I2C_RecvByte();       //读出寄存器数据

        I2C_SendACK(1);                //接收应答信号

         I2C_Stop();                    //停止信号  

         return REG_data; }

//************************************** //初始化MPU6050 //**************************************

void InitMPU6050()

 {  

        Single_WriteI2C(PWR_MGMT_1, 0x00); //解除休眠状态

         Single_WriteI2C(SMPLRT_div, 0x07);//  

          Single_WriteI2C(CONFIG, 0x06);//  

         Single_WriteI2C(GYRO_CONFIG, 0x18);//  

         Single_WriteI2C(ACCEL_CONFIG, 0x01);//

 }

//************************************** //合成数据 //**************************************

uchar GetData(uchar REG_Address)

 {  

uchar H,L;

 H=Single_ReadI2C(REG_Address);

 L=Single_ReadI2C(REG_Address+1);  

return (H<<8)+L;                         //合成数据

 }

//************************************** //显示温度 //************************************** //

 

void InitUART(void)

 { PERCFG = 0x00;                  //位置 1 P0 口

P0SEL = 0x0c;                   //P0_2,P0_3 用作串口(外部设备功能)

P2DIR &= ~0XC0;                 //P0 优先作为

UART0 U0CSR |= 0x80;                  //设置为

UART 方式 U0GCR |= 11;        

U0BAUD |= 216;                  //波特率设为 115200

UTX0IF = 0;                     //UART0 TX 中断标志初始置位 0 }

void UartSend_String(uchar *Data,int len)

{

  int j; for(j=0;j<len;j++)

{ U0DBUF = *Data++; while(UTX0IF == 0); UTX0IF = 0; } }

 

 

#define LED1 P1_0

   

void main()

 {           

        float temp1;

        int tempx[47];  int k;

        delay(500);         //上电延时        

        System_CC2540_init(); 

        InitMPU6050();         //初始化MPU6050     

        Single_WriteI2C(MPU6050_RA_PWR_MGMT_1,0x59);     

       char gyro_b=Single_ReadI2C(GYRO_CONFIG);     // 测试MPU6050读写是否正常  

               while(1)

              {

                           SeriPushSend(0x0d);

                          SeriPushSend(0x0a);           //换行,回车         

                           delay(100);

               }

}

自已解决了,今天又遇到一回!

不过这次,按一下“restart debugger”就OK了,有时就是大脑短路了,

程序是OK,板子是OK,就不会想一下调试器是否OK,是否要复位一下!

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top