微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 关于51 驱动6050 求大神帮忙把x轴速度表示出来 (如Xa=____x轴速度)

关于51 驱动6050 求大神帮忙把x轴速度表示出来 (如Xa=____x轴速度)

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

  1. //****************************************
  2. // Update to MPU6050 by shinetop
  3. // MCU: STC89C52
  4. // 2012.3.1
  5. // 功能: 显示加速度计和陀螺仪的10位原始数据
  6. //****************************************
  7. // GY-52 MPU6050 IIC测试程序
  8. // 使用单片机STC89C51
  9. // 晶振:11.0592M
  10. // 显示:LCD1602
  11. // 编译环境 Keil uVision3
  12. // 参考宏晶网站24c04通信程序
  13. // 时间:2011年9月1日
  14. // QQ:531389319
  15. //****************************************
  16. #include <REG51.H>       
  17. #include <math.h>    //Keil library  
  18. #include <stdio.h>   //Keil library       
  19. #include <INTRINS.H>
  20. typedef unsigned char  uchar;
  21. typedef unsigned short ushort;
  22. typedef unsigned int   uint;
  23. uchar Xx;
  24. uchar XXX;
  25. //****************************************
  26. // 定义51单片机端口
  27. //****************************************
  28. #define DataPort P0                //LCD1602数据端口
  29. sbit    SCL=P1^0;                        //IIC时钟引脚定义
  30. sbit    SDA=P1^1;                        //IIC数据引脚定义
  31. sbit    LCM_RS=P2^6;                //LCD1602命令端口               
  32. sbit    LCM_RW=P2^5;                //LCD1602命令端口               
  33. sbit    LCM_EN=P2^7;                //LCD1602命令端口
  34. sbit        warm=P2^0;
  35. //****************************************
  36. // 定义MPU6050内部地址
  37. //****************************************
  38. #define        SMPLRT_div                0x19        //陀螺仪采样率,典型值:0x07(125Hz)
  39. #define        CONFIG                        0x1A        //低通滤波频率,典型值:0x06(5Hz)
  40. #define        GYRO_CONFIG                0x1B        //陀螺仪自检及测量范围,典型值:0x18(不自检,2000deg/s)
  41. #define        ACCEL_CONFIG        0x1C        //加速计自检、测量范围及高通滤波频率,典型值:0x01(不自检,2G,5Hz)
  42. #define        ACCEL_XOUT_H        0x3B
  43. #define        ACCEL_XOUT_L        0x3C
  44. #define        ACCEL_YOUT_H        0x3D
  45. #define        ACCEL_YOUT_L        0x3E
  46. #define        ACCEL_ZOUT_H        0x3F
  47. #define        ACCEL_ZOUT_L        0x40
  48. #define        TEMP_OUT_H                0x41
  49. #define        TEMP_OUT_L                0x42
  50. #define        GYRO_XOUT_H                0x43
  51. #define        GYRO_XOUT_L                0x44       
  52. #define        GYRO_YOUT_H                0x45
  53. #define        GYRO_YOUT_L                0x46
  54. #define        GYRO_ZOUT_H                0x47
  55. #define        GYRO_ZOUT_L                0x48
  56. #define        PWR_MGMT_1                0x6B        //电源管理,典型值:0x00(正常启用)
  57. #define        WHO_AM_I                        0x75        //IIC地址寄存器(默认数值0x68,只读)
  58. #define        SlaveAddress        0xD0        //IIC写入时的地址字节数据,+1为读取
  59. //****************************************
  60. //定义类型及变量
  61. //****************************************
  62. uchar dis[4];                                                        //显示数字(-511至512)的字符数组
  63. int        dis_data;                                                //变量
  64. //int        Temperature,Temp_h,Temp_l;        //温度及高低位数据
  65. //****************************************
  66. //函数声明
  67. //****************************************
  68. void  delay(unsigned int k);                                                                                //延时
  69. //LCD相关函数
  70. void  InitLcd();                                                                                                                //初始化lcd1602
  71. void  lcd_printf(uchar *s,int temp_data);
  72. void  WriteDataLCM(uchar dataW);                                                                        //LCD数据
  73. void  WriteCommandLCM(uchar CMD,uchar Attribc);                                //LCD指令
  74. void  DisplayOneChar(uchar X,uchar Y,uchar DData);                        //显示一个字符
  75. void  DisplayListChar(uchar X,uchar Y,uchar *DData,L);        //显示字符串
  76. //MPU6050操作函数
  77. void  InitMPU6050();                                                                                                        //初始化MPU6050
  78. void  Delay5us();
  79. void  I2C_Start();
  80. void  I2C_Stop();
  81. void  I2C_SendACK(bit ack);
  82. bit   I2C_RecvACK();
  83. void  I2C_SendByte(uchar dat);
  84. uchar I2C_RecvByte();
  85. void  I2C_ReadPage();
  86. void  I2C_WritePage();
  87. void  display_ACCEL_x();
  88. void  display_ACCEL_y();
  89. void  display_ACCEL_z();
  90. uchar Single_ReadI2C(uchar REG_Address);                                                //读取I2C数据
  91. void  Single_WriteI2C(uchar REG_Address,uchar REG_data);        //向I2C写入数据
  92. //****************************************
  93. //整数转字符串
  94. //****************************************
  95. void lcd_printf(uchar *s,int temp_data)
  96. {
  97.         if(temp_data<0)
  98.         {
  99.                 temp_data=-temp_data;
  100.                 *s='-';
  101.         }
  102.         else *s=' ';
  103.         *++s =temp_data/100+0x30;
  104.         temp_data=temp_data%100;     //取余运算
  105.         *++s =temp_data/10+0x30;
  106.         temp_data=temp_data%10;      //取余运算
  107.         *++s =temp_data+0x30;        
  108. }
  109. //****************************************
  110. //延时
  111. //****************************************
  112. void delay(unsigned int k)       
  113. {                                               
  114.         unsigned int i,j;                               
  115.         for(i=0;i<k;i++)
  116.         {                       
  117.                 for(j=0;j<121;j++);
  118.         }                                               
  119. }
  120. //****************************************
  121. //LCD1602初始化
  122. //****************************************
  123. void InitLcd()                               
  124. {                       
  125.         WriteCommandLCM(0x38,1);       
  126.         WriteCommandLCM(0x08,1);       
  127.         WriteCommandLCM(0x01,1);       
  128.         WriteCommandLCM(0x06,1);       
  129.         WriteCommandLCM(0x0c,1);
  130.         DisplayOneChar(0,0,'A');
  131.         DisplayOneChar(0,1,'G');
  132. }                       
  133. //****************************************
  134. //LCD1602写允许
  135. //****************************************
  136. void WaitForEnable(void)       
  137. {                                       
  138.         DataPort=0xff;               
  139.         LCM_RS=0;LCM_RW=1;_nop_();
  140.         LCM_EN=1;_nop_();_nop_();
  141.         while(DataPort&0x80);       
  142.         LCM_EN=0;                               
  143. }                                       
  144. //****************************************
  145. //LCD1602写入命令
  146. //****************************************
  147. void WriteCommandLCM(uchar CMD,uchar Attribc)
  148. {                                       
  149.         if(Attribc)WaitForEnable();       
  150.         LCM_RS=0;LCM_RW=0;_nop_();
  151.         DataPort=CMD;_nop_();       
  152.         LCM_EN=1;_nop_();_nop_();LCM_EN=0;
  153. }                                       
  154. //****************************************
  155. //LCD1602写入数据
  156. //****************************************
  157. void WriteDataLCM(uchar dataW)
  158. {                                       
  159.         WaitForEnable();               
  160.         LCM_RS=1;LCM_RW=0;_nop_();
  161.         DataPort=dataW;_nop_();       
  162.         LCM_EN=1;_nop_();_nop_();LCM_EN=0;
  163. }               
  164. //****************************************
  165. //LCD1602写入一个字符
  166. //****************************************
  167. void DisplayOneChar(uchar X,uchar Y,uchar DData)
  168. {                                               
  169.         Y&=1;                                               
  170.         X&=15;                                               
  171.         if(Y)X|=0x40;                                       
  172.         X|=0x80;                       
  173.         WriteCommandLCM(X,0);               
  174.         WriteDataLCM(DData);
  175. }                                               
  176. //****************************************
  177. //LCD1602显示字符串
  178. //****************************************
  179. void DisplayListChar(uchar X,uchar Y,uchar *DData,L)
  180. {
  181.         uchar ListLength=0;
  182.         Y&=0x1;               
  183.         X&=0xF;               
  184.         while(L--)            
  185.         {                       
  186.                 DisplayOneChar(X,Y,DData[ListLength]);
  187.                 ListLength++;  
  188.                 X++;                        
  189.         }   
  190. }
  191. //**************************************
  192. //延时5微秒(STC90C52RC@12M)
  193. //不同的工作环境,需要调整此函数
  194. //当改用1T的MCU时,请调整此延时函数
  195. //**************************************
  196. void Delay5us()
  197. {
  198.         _nop_();_nop_();_nop_();_nop_();
  199.         _nop_();_nop_();_nop_();_nop_();
  200.         _nop_();_nop_();_nop_();_nop_();
  201.         _nop_();_nop_();_nop_();_nop_();
  202.         _nop_();_nop_();_nop_();_nop_();
  203.         _nop_();_nop_();_nop_();_nop_();
  204. }
  205. //**************************************
  206. //I2C起始信号
  207. //**************************************
  208. void I2C_Start()
  209. {
  210.     SDA = 1;                    //拉高数据线
  211.     SCL = 1;                    //拉高时钟线
  212.     Delay5us();                 //延时
  213.     SDA = 0;                    //产生下降沿
  214.     Delay5us();                 //延时
  215.     SCL = 0;                    //拉低时钟线
  216. }
  217. //**************************************
  218. //I2C停止信号
  219. //**************************************
  220. void I2C_Stop()
  221. {
  222.     SDA = 0;                    //拉低数据线
  223.     SCL = 1;                    //拉高时钟线
  224.     Delay5us();                 //延时
  225.     SDA = 1;                    //产生上升沿
  226.     Delay5us();                 //延时
  227. }
  228. //**************************************
  229. //I2C发送应答信号
  230. //入口参数:ack (0:ACK 1:NAK)
  231. //**************************************
  232. void I2C_SendACK(bit ack)
  233. {
  234.     SDA = ack;                  //写应答信号
  235.     SCL = 1;                    //拉高时钟线
  236.     Delay5us();                 //延时
  237.     SCL = 0;                    //拉低时钟线
  238.     Delay5us();                 //延时
  239. }
  240. //**************************************
  241. //I2C接收应答信号
  242. //**************************************
  243. bit I2C_RecvACK()
  244. {
  245.     SCL = 1;                    //拉高时钟线
  246.     Delay5us();                 //延时
  247.     CY = SDA;                   //读应答信号
  248.     SCL = 0;                    //拉低时钟线
  249.     Delay5us();                 //延时
  250.     return CY;
  251. }
  252. //**************************************
  253. //向I2C总线发送一个字节数据
  254. //**************************************
  255. void I2C_SendByte(uchar dat)
  256. {
  257.     uchar i;
  258.     for (i=0; i<8; i++)         //8位计数器
  259.     {
  260.         dat <<= 1;              //移出数据的最高位
  261.         SDA = CY;               //送数据口
  262.         SCL = 1;                //拉高时钟线
  263.         Delay5us();             //延时
  264.         SCL = 0;                //拉低时钟线
  265.         Delay5us();             //延时
  266.     }
  267.     I2C_RecvACK();
  268. }
  269. //**************************************
  270. //从I2C总线接收一个字节数据
  271. //**************************************
  272. uchar I2C_RecvByte()
  273. {
  274.     uchar i;
  275.     uchar dat = 0;
  276.     SDA = 1;                    //使能内部上拉,准备读取数据,
  277.     for (i=0; i<8; i++)         //8位计数器
  278.     {
  279.         dat <<= 1;
  280.         SCL = 1;                //拉高时钟线
  281.         Delay5us();             //延时
  282.         dat |= SDA;             //读数据               
  283.         SCL = 0;                //拉低时钟线
  284.         Delay5us();             //延时
  285.     }
  286.     return dat;
  287. }
  288. //**************************************
  289. //向I2C设备写入一个字节数据
  290. //**************************************
  291. void Single_WriteI2C(uchar REG_Address,uchar REG_data)
  292. {
  293.     I2C_Start();                  //起始信号
  294.     I2C_SendByte(SlaveAddress);   //发送设备地址+写信号
  295.     I2C_SendByte(REG_Address);    //内部寄存器地址,
  296.     I2C_SendByte(REG_data);       //内部寄存器数据,
  297.     I2C_Stop();                   //发送停止信号
  298. }
  299. //**************************************
  300. //从I2C设备读取一个字节数据
  301. //**************************************
  302. uchar Single_ReadI2C(uchar REG_Address)
  303. {
  304.         uchar REG_data;
  305.         I2C_Start();                   //起始信号
  306.         I2C_SendByte(SlaveAddress);    //发送设备地址+写信号
  307.         I2C_SendByte(REG_Address);     //发送存储单元地址,从0开始       
  308.         I2C_Start();                   //起始信号
  309.         I2C_SendByte(SlaveAddress+1);  //发送设备地址+读信号
  310.         REG_data=I2C_RecvByte();       //读出寄存器数据
  311.         I2C_SendACK(1);                //接收应答信号
  312.         I2C_Stop();                    //停止信号
  313.         return REG_data;
  314. }
  315. //**************************************
  316. //初始化MPU6050
  317. //**************************************
  318. void InitMPU6050()
  319. {
  320.         Single_WriteI2C(PWR_MGMT_1, 0x00);        //解除休眠状态
  321.         Single_WriteI2C(SMPLRT_div, 0x07);                  
  322.         Single_WriteI2C(CONFIG, 0x06);
  323.         Single_WriteI2C(GYRO_CONFIG, 0x18);
  324.         Single_WriteI2C(ACCEL_CONFIG, 0x01);
  325. }
  326. //**************************************
  327. //合成数据
  328. //**************************************
  329. int GetData(uchar REG_Address)
  330. {
  331.         char H,L;
  332.         H=Single_ReadI2C(REG_Address);
  333.         L=Single_ReadI2C(REG_Address+1);
  334.         return (H<<8)+L;   //合成数据
  335. }
  336. //**************************************
  337. //在1602上显示10位数据
  338. //**************************************
  339. void Display10BitData(int value,uchar x,uchar y)
  340. {
  341.         if(value==GetData(ACCEL_XOUT_H))        //
  342.         XXX=2;                                           //
  343.         value/=64;                                                        //转换为10位数据
  344.         lcd_printf(dis, value);                        //转换数据显示
  345.         DisplayListChar(x,y,dis,4);        //启始列,行,显示数组,显示长度
  346. }
  347. //**************************************
  348. //显示温度
  349. //**************************************
  350. //void display_temp()
  351. //{
  352. //        Temp_h=Single_ReadI2C(TEMP_OUT_H); //读取温度
  353. //        Temp_l=Single_ReadI2C(TEMP_OUT_L); //读取温度
  354. //        Temperature=Temp_h<<8|Temp_l;     //合成温度
  355. //        Temperature = 35+ ((double) (Temperature + 13200)) / 280; // 计算出温度
  356. //        lcd_printf(dis,Temperature);     //转换数据显示
  357. //        DisplayListChar(11,1,dis,4);     //启始列,行,显示数组,显示位数
  358. //}
  359. //*********************************************************
  360. //主程序
  361. //*********************************************************
  362. void main()
  363. {
  364.         XXX=0;                                   ////////
  365.         delay(500);                //上电延时               
  366.         InitLcd();                //液晶初始化
  367.         InitMPU6050();        //初始化MPU6050
  368.         delay(150);
  369.         while(1)
  370.         {
  371.                 Display10BitData(GetData(ACCEL_XOUT_H),2,0);        //显示X轴加速度
  372.                 Display10BitData(GetData(ACCEL_YOUT_H),7,0);        //显示Y轴加速度
  373.                 Display10BitData(GetData(ACCEL_ZOUT_H),12,0);        //显示Z轴加速度
  374.                 Display10BitData(GetData(GYRO_XOUT_H),2,1);        //显示X轴角速度
  375.                 Display10BitData(GetData(GYRO_YOUT_H),7,1);        //显示Y轴角速度
  376.                 Display10BitData(GetData(GYRO_ZOUT_H),12,1);        //显示Z轴角速度
  377.                 delay(500);

  378.                 Xx=GetData(ACCEL_XOUT_H);
  379.                 if(Xx>100)                 //
  380.                 warm=1;                          //
  381.                 if(Xx<100)                        //
  382.                 warm=0;                          //
  383.         }
  384. }

复制代码


谢谢分享

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

网站地图

Top