查看: 2964|回复: 8
打印 上一主题 下一主题

GY-52三轴陀螺仪的测试代码(基于51单片机)

[复制链接]
跳转到指定楼层
沙发
发表于 2014-8-11 15:44:46 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式


走过路过,不要错过

GY-52三轴陀螺仪的测试代码(基于51单片机):



  1. //***************************************
  2. // GY-52 MPU3050 IIC测试程序
  3. // 使用单片机STC89C51
  4. // 晶振:11.0592M
  5. // 显示:LCD1602
  6. //****************************************
  7. #include  <REG51.H>       
  8. #include  <math.h>    //Keil library  
  9. #include  <stdio.h>   //Keil library       
  10. #include  <INTRINS.H>
  11. #define   uchar unsigned char
  12. #define   uint unsigned int       
  13. #define   DataPort P0    //LCD1602数据端口
  14. sbit          SCL=P1^0;      //IIC时钟引脚定义
  15. sbit           SDA=P1^1;      //IIC数据引脚定义
  16. sbit      LCM_RS=P2^0;   //LCD1602命令端口               
  17. sbit      LCM_RW=P2^1;   //LCD1602命令端口               
  18. sbit      LCM_EN=P2^2;   //LCD1602命令端口

  19. //定义MPU3050内部地址********************
  20. #define WHO            0x00
  21. #define        SMPL        0x15
  22. #define DLPF        0x16
  23. #define INT_C        0x17
  24. #define INT_S        0x1A
  25. #define        TMP_H        0x1B
  26. #define        TMP_L        0x1C
  27. #define        GX_H        0x1D
  28. #define        GX_L        0x1E
  29. #define        GY_H        0x1F
  30. #define        GY_L        0x20
  31. #define GZ_H        0x21
  32. #define GZ_L        0x22
  33. #define PWR_M        0x3E
  34. //****************************

  35. #define        SlaveAddress   0xD0          //定义器件在IIC总线中的从地址,根据ALT  ADDRESS地址引脚不同修改
  36.                           
  37. typedef unsigned char  BYTE;
  38. typedef unsigned short WORD;

  39. uchar dis[4];                         //显示数组
  40. BYTE BUF[8];                         //接收数据缓存区                      
  41. int  dis_data;                       //变量
  42. int Temperature,Temp_h,Temp_l;
  43. void delay(unsigned int k);
  44. void InitLcd();                     //初始化lcd1602
  45. void InitMPU3050();                 //初始化MPU3050

  46. void WriteDataLCM(uchar dataW);
  47. void WriteCommandLCM(uchar CMD,uchar Attribc);
  48. void DisplayOneChar(uchar X,uchar Y,uchar DData);
  49. void DisplayListChar(uchar X,uchar Y,uchar *DData,L);

  50. void  Single_WriteMPU3050(uchar REG_Address,uchar REG_data);   //单个写入数据
  51. uchar Single_ReadMPU3050(uchar REG_Address);                   //单个读取内部寄存器数据

  52. //****************************************模拟IIC使用函数
  53. void Delay5us();
  54. void MPU3050_Start();
  55. void MPU3050_Stop();
  56. void MPU3050_SendACK(bit ack);
  57. bit  MPU3050_RecvACK();
  58. void MPU3050_SendByte(BYTE dat);
  59. BYTE MPU3050_RecvByte();
  60. void MPU3050_ReadPage();
  61. void MPU3050_WritePage();
  62. //****************************************
  63. void display_x();
  64. void display_y();
  65. void display_z();

  66. //****************************************

  67. void lcd_printf(uchar *s,int temp_data)
  68. {
  69.         if(temp_data<0){
  70.         temp_data=-temp_data;
  71.     *s='-';
  72.         }
  73.         else *s=' ';
  74.     *++s =temp_data/100+0x30;
  75.     temp_data=temp_data%100;     //取余运算
  76.     *++s =temp_data/10+0x30;
  77.     temp_data=temp_data%10;      //取余运算
  78.     *++s =temp_data+0x30;        
  79. }

  80. /*******************************/
  81. void delay(unsigned int k)       
  82. {                                               
  83. unsigned int i,j;                               
  84. for(i=0;i<k;i++)
  85. {                       
  86. for(j=0;j<121;j++)                       
  87. {;}}                                               
  88. }
  89. /*******************************/
  90. void WaitForEnable(void)       
  91. {                                       
  92. DataPort=0xff;               
  93. LCM_RS=0;LCM_RW=1;_nop_();
  94. LCM_EN=1;_nop_();_nop_();
  95. while(DataPort&0x80);       
  96. LCM_EN=0;                               
  97. }                                       
  98. /*******************************/
  99. void WriteCommandLCM(uchar CMD,uchar Attribc)
  100. {                                       
  101. if(Attribc)WaitForEnable();       
  102. LCM_RS=0;LCM_RW=0;_nop_();
  103. DataPort=CMD;_nop_();       
  104. LCM_EN=1;_nop_();_nop_();LCM_EN=0;
  105. }                                       
  106. /*******************************/
  107. void WriteDataLCM(uchar dataW)
  108. {                                       
  109. WaitForEnable();               
  110. LCM_RS=1;LCM_RW=0;_nop_();
  111. DataPort=dataW;_nop_();       
  112. LCM_EN=1;_nop_();_nop_();LCM_EN=0;
  113. }               
  114. /***********************************/
  115. void InitLcd()                               
  116. {                       
  117. WriteCommandLCM(0x38,1);       
  118. WriteCommandLCM(0x08,1);       
  119. WriteCommandLCM(0x01,1);       
  120. WriteCommandLCM(0x06,1);       
  121. WriteCommandLCM(0x0c,1);
  122. DisplayOneChar(0,0,'x');
  123. DisplayOneChar(1,0,':');
  124. DisplayOneChar(0,1,'y');
  125. DisplayOneChar(1,1,':');
  126. DisplayOneChar(9,0,'z');
  127. DisplayOneChar(10,0,':');
  128. DisplayOneChar(9,1,'T');
  129. DisplayOneChar(10,1,':');
  130. }                       
  131. /***********************************/
  132. void DisplayOneChar(uchar X,uchar Y,uchar DData)
  133. {                                               
  134. Y&=1;                                               
  135. X&=15;                                               
  136. if(Y)X|=0x40;                                       
  137. X|=0x80;                       
  138. WriteCommandLCM(X,0);               
  139. WriteDataLCM(DData);               
  140. }                                               
  141. /***********************************/
  142. void DisplayListChar(uchar X,uchar Y,uchar *DData,L)
  143. {
  144. uchar ListLength=0;
  145. Y&=0x1;               
  146. X&=0xF;               
  147. while(L--)            
  148. {                       
  149. DisplayOneChar(X,Y,DData[ListLength]);
  150. ListLength++;  
  151. X++;                        
  152. }   
  153. }
  154. /**************************************
  155. 延时5微秒(STC90C52RC@12M)
  156. 不同的工作环境,需要调整此函数,注意时钟过快时需要修改
  157. 当改用1T的MCU时,请调整此延时函数
  158. **************************************/
  159. void Delay5us()
  160. {
  161.     _nop_();_nop_();_nop_();_nop_();
  162.     _nop_();_nop_();_nop_();_nop_();
  163.         _nop_();_nop_();_nop_();_nop_();
  164.         _nop_();_nop_();_nop_();_nop_();
  165.     _nop_();_nop_();_nop_();_nop_();
  166.         _nop_();_nop_();_nop_();_nop_();
  167. }

  168. /**************************************
  169. 起始信号
  170. **************************************/
  171. void MPU3050_Start()
  172. {
  173.     SDA = 1;                    //拉高数据线
  174.     SCL = 1;                    //拉高时钟线
  175.     Delay5us();                 //延时
  176.     SDA = 0;                    //产生下降沿
  177.     Delay5us();                 //延时
  178.     SCL = 0;                    //拉低时钟线
  179. }

  180. /**************************************
  181. 停止信号
  182. **************************************/
  183. void MPU3050_Stop()
  184. {
  185.     SDA = 0;                    //拉低数据线
  186.     SCL = 1;                    //拉高时钟线
  187.     Delay5us();                 //延时
  188.     SDA = 1;                    //产生上升沿
  189.     Delay5us();                 //延时
  190. }

  191. /**************************************
  192. 发送应答信号
  193. 入口参数:ack (0:ACK 1:NAK)
  194. **************************************/
  195. void MPU3050_SendACK(bit ack)
  196. {
  197.     SDA = ack;                  //写应答信号
  198.     SCL = 1;                    //拉高时钟线
  199.     Delay5us();                 //延时
  200.     SCL = 0;                    //拉低时钟线
  201.     Delay5us();                 //延时
  202. }

  203. /**************************************
  204. 接收应答信号
  205. **************************************/
  206. bit MPU3050_RecvACK()
  207. {
  208.     SCL = 1;                    //拉高时钟线
  209.     Delay5us();                 //延时
  210.     CY = SDA;                   //读应答信号
  211.     SCL = 0;                    //拉低时钟线
  212.     Delay5us();                 //延时

  213.     return CY;
  214. }

  215. /**************************************
  216. 向IIC总线发送一个字节数据
  217. **************************************/
  218. void MPU3050_SendByte(BYTE dat)
  219. {
  220.     BYTE i;

  221.     for (i=0; i<8; i++)         //8位计数器
  222.     {
  223.         dat <<= 1;              //移出数据的最高位
  224.         SDA = CY;               //送数据口
  225.         SCL = 1;                //拉高时钟线
  226.         Delay5us();             //延时
  227.         SCL = 0;                //拉低时钟线
  228.         Delay5us();             //延时
  229.     }
  230.     MPU3050_RecvACK();
  231. }

  232. /**************************************
  233. 从IIC总线接收一个字节数据
  234. **************************************/
  235. BYTE MPU3050_RecvByte()
  236. {
  237.     BYTE i;
  238.     BYTE dat = 0;

  239.     SDA = 1;                    //使能内部上拉,准备读取数据,
  240.     for (i=0; i<8; i++)         //8位计数器
  241.     {
  242.         dat <<= 1;
  243.         SCL = 1;                //拉高时钟线
  244.         Delay5us();             //延时
  245.         dat |= SDA;             //读数据               
  246.         SCL = 0;                //拉低时钟线
  247.         Delay5us();             //延时
  248.     }
  249.     return dat;
  250. }

  251. //单字节写入*******************************************

  252. void Single_WriteMPU3050(uchar REG_Address,uchar REG_data)
  253. {
  254.     MPU3050_Start();                  //起始信号
  255.     MPU3050_SendByte(SlaveAddress);   //发送设备地址+写信号
  256.     MPU3050_SendByte(REG_Address);    //内部寄存器地址,
  257.     MPU3050_SendByte(REG_data);       //内部寄存器数据,
  258.     MPU3050_Stop();                   //发送停止信号
  259. }

  260. //单字节读取*****************************************
  261. uchar Single_ReadMPU3050(uchar REG_Address)
  262. {  uchar REG_data;
  263.     MPU3050_Start();                          //起始信号
  264.     MPU3050_SendByte(SlaveAddress);           //发送设备地址+写信号
  265.     MPU3050_SendByte(REG_Address);            //发送存储单元地址,从0开始       
  266.     MPU3050_Start();                          //起始信号
  267.     MPU3050_SendByte(SlaveAddress+1);         //发送设备地址+读信号
  268.     REG_data=MPU3050_RecvByte();              //读出寄存器数据
  269.         MPU3050_SendACK(1);   
  270.         MPU3050_Stop();                           //停止信号
  271.     return REG_data;
  272. }

  273. //初始化MPU3050,根据需要请参考pdf进行修改************************
  274. void InitMPU3050()
  275. {
  276.    Single_WriteMPU3050(PWR_M, 0x80);   //
  277.    Single_WriteMPU3050(SMPL, 0x07);    //
  278.    Single_WriteMPU3050(DLPF, 0x1E);    //±2000°
  279.    Single_WriteMPU3050(INT_C, 0x00 );  //
  280.    Single_WriteMPU3050(PWR_M, 0x00);   //
  281. }
复制代码

回复

使用道具 举报

板凳
 楼主| 发表于 2014-8-11 15:45:05 | 只看该作者
  1. //***********************************************************************
  2. //显示x轴
  3. void display_x()
  4. {
  5. BUF[0]= Single_ReadMPU3050(GX_L);
  6. BUF[1]= Single_ReadMPU3050(GX_H);
  7. dis_data=(BUF[1]<<8)+BUF[0]; //合成数据
  8. dis_data/=16.4; //计算对应 度/秒
  9. lcd_printf(dis, dis_data); //转换数据显示
  10. DisplayListChar(2,0,dis,4); //启始列,行,显示数组,显示长度
  11. }

  12. //***********************************************************************
  13. //显示y轴
  14. void display_y()
  15. {
  16. BUF[2]= Single_ReadMPU3050(GY_L);
  17. BUF[3]= Single_ReadMPU3050(GY_H);
  18. dis_data=(BUF[3]<<8)+BUF[2]; //合成数据
  19. dis_data/=16.4; //计算对应 度/秒
  20. lcd_printf(dis, dis_data); //转换数据显示
  21. DisplayListChar(2,1,dis,4); //启始列,行,显示数组,显示位数
  22. }

  23. //***********************************************************************
  24. //显示z轴
  25. void display_z()
  26. {
  27. BUF[4]= Single_ReadMPU3050(GZ_L);
  28. BUF[5]= Single_ReadMPU3050(GZ_H);
  29. dis_data=(BUF[5]<<8)+BUF[4]; //合成数据
  30. dis_data/=16.4; //计算对应 度/秒
  31. lcd_printf(dis, dis_data); //转换数据显示
  32. DisplayListChar(11,0,dis,4); //启始列,行,显示数组,显示位数
  33. }

  34. //***********************************************************************
  35. //显示温度
  36. void display_temp()
  37. {
  38. Temp_h=Single_ReadMPU3050(TMP_H); //读取温度
  39. Temp_l=Single_ReadMPU3050(TMP_L); //读取温度
  40. Temperature=Temp_h<<8|Temp_l; //合成温度
  41. Temperature = 35+ ((double) (Temperature + 13200)) / 280; // 计算出温度
  42. lcd_printf(dis,Temperature); //转换数据显示
  43. DisplayListChar(11,1,dis,4); //启始列,行,显示数组,显示位数
  44. }

  45. //*********************************************************
  46. //******主程序********
  47. //*********************************************************
  48. void main()
  49. {
  50. delay(500);         //上电延时       
  51. InitLcd(); //液晶初始化
  52. InitMPU3050(); //初始化MPU3050
  53. delay(50);
  54. while(1) //循环
  55. {
  56. display_x(); //---------显示X轴
  57. display_y(); //---------显示Y轴
  58. display_z(); //---------显示Z轴
  59. display_temp(); //---------显示温度
  60. delay(100); //延时
  61. }
  62. }
复制代码
回复 支持 反对

使用道具 举报

4#
 楼主| 发表于 2014-8-11 16:00:30 | 只看该作者

拿出来吓吓你们
回复 支持 反对

使用道具 举报

5#
发表于 2014-8-11 20:01:12 | 只看该作者
吓死了。。。怎么办啊
回复 支持 反对

使用道具 举报

6#
发表于 2014-8-11 20:19:17 | 只看该作者
好东西,收了
回复 支持 反对

使用道具 举报

7#
 楼主| 发表于 2014-8-12 08:43:12 | 只看该作者
lucky80204 发表于 2014-8-11 20:01
吓死了。。。怎么办啊

打电话        
回复 支持 反对

使用道具 举报

8#
 楼主| 发表于 2014-8-12 08:43:45 | 只看该作者

缴税           
回复 支持 反对

使用道具 举报

9#
发表于 2014-8-12 08:47:22 | 只看该作者

119...楼主。。。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 加入中科因仑

本版积分规则

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