找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 8373|回复: 19
打印 上一主题 下一主题
收起左侧

利用STM8驱动的MPU6050陀螺仪源程序

  [复制链接]
跳转到指定楼层
楼主
利用STM8驱动的陀螺仪程序,参考其他人写的32的程序,自己修改接口,完成驱动陀螺仪。

单片机源程序如下:
  1. #include "MPU6050.h"
  2. #include "IOI2C.h"
  3. #include "usart1.h"
  4. #include <math.h>
  5. #include "inv_mpu_dmp_motion_driver.h"
  6. #include "inv_mpu.h"
  7. #include <stdio.h>
  8. /**************************************************************************/
  9. #define PRINT_ACCEL     (0x01)
  10. #define PRINT_GYRO      (0x02)
  11. #define PRINT_QUAT      (0x04)
  12. #define ACCEL_ON        (0x01)
  13. #define GYRO_ON         (0x02)
  14. #define MOTION          (0)
  15. #define NO_MOTION       (1)
  16. #define DEFAULT_MPU_HZ  (200)
  17. #define FLASH_SIZE      (512)
  18. #define FLASH_MEM_START ((void*)0x1800)
  19. #define q30  1073741824.0f

  20. static signed char gyro_orientation[9] = {-1, 0, 0,
  21.                                            0,-1, 0,
  22.                                            0, 0, 1};

  23. static  unsigned short inv_row_2_scale(const signed char *row)
  24. {
  25.     unsigned short b;

  26.     if (row[0] > 0)
  27.         b = 0;
  28.     else if (row[0] < 0)
  29.         b = 4;
  30.     else if (row[1] > 0)
  31.         b = 1;
  32.     else if (row[1] < 0)
  33.         b = 5;
  34.     else if (row[2] > 0)
  35.         b = 2;
  36.     else if (row[2] < 0)
  37.         b = 6;
  38.     else
  39.         b = 7;      // error
  40.     return b;
  41. }


  42. static  unsigned short inv_orientation_matrix_to_scalar(
  43.     const signed char *mtx)
  44. {
  45.     unsigned short scalar;
  46.     scalar = inv_row_2_scale(mtx);
  47.     scalar |= inv_row_2_scale(mtx + 3) << 3;
  48.     scalar |= inv_row_2_scale(mtx + 6) << 6;


  49.     return scalar;
  50. }

  51. static void run_self_test(void)
  52. {
  53.     int result;
  54.     long gyro[3], accel[3];

  55.     result = mpu_run_self_test(gyro, accel);
  56.     if (result == 0x7) {
  57.         /* Test passed. We can trust the gyro data here, so let's push it down
  58.          * to the DMP.
  59.          */
  60.         float sens;
  61.         unsigned short accel_sens;
  62.         mpu_get_gyro_sens(&sens);
  63.         gyro[0] = (long)(gyro[0] * sens);
  64.         gyro[1] = (long)(gyro[1] * sens);
  65.         gyro[2] = (long)(gyro[2] * sens);
  66.         dmp_set_gyro_bias(gyro);
  67.         mpu_get_accel_sens(&accel_sens);
  68.         accel[0] *= accel_sens;
  69.         accel[1] *= accel_sens;
  70.         accel[2] *= accel_sens;
  71.         dmp_set_accel_bias(accel);
  72.                 printf("setting bias succesfully ......\r\n");
  73.     }
  74. }



  75. uint8_t buffer[14];

  76. int16_t  MPU6050_FIFO[6][11];
  77. int16_t Gx_offset=0,Gy_offset=0,Gz_offset=0;


  78. /**************************实现函数********************************************
  79. *函数原型:                void  MPU6050_newValues(int16_t ax,int16_t ay,int16_t az,int16_t gx,int16_t gy,int16_t gz)
  80. *功  能:            将新的ADC数据更新到 FIFO数组,进行滤波处理
  81. *******************************************************************************/

  82. void  MPU6050_newValues(int16_t ax,int16_t ay,int16_t az,int16_t gx,int16_t gy,int16_t gz)
  83. {
  84. unsigned char i ;
  85. int32_t sum=0;
  86. for(i=1;i<10;i++){        //FIFO 操作
  87. MPU6050_FIFO[0][i-1]=MPU6050_FIFO[0][i];
  88. MPU6050_FIFO[1][i-1]=MPU6050_FIFO[1][i];
  89. MPU6050_FIFO[2][i-1]=MPU6050_FIFO[2][i];
  90. MPU6050_FIFO[3][i-1]=MPU6050_FIFO[3][i];
  91. MPU6050_FIFO[4][i-1]=MPU6050_FIFO[4][i];
  92. MPU6050_FIFO[5][i-1]=MPU6050_FIFO[5][i];
  93. }
  94. MPU6050_FIFO[0][9]=ax;//将新的数据放置到 数据的最后面
  95. MPU6050_FIFO[1][9]=ay;
  96. MPU6050_FIFO[2][9]=az;
  97. MPU6050_FIFO[3][9]=gx;
  98. MPU6050_FIFO[4][9]=gy;
  99. MPU6050_FIFO[5][9]=gz;

  100. sum=0;
  101. for(i=0;i<10;i++){        //求当前数组的合,再取平均值
  102.    sum+=MPU6050_FIFO[0][i];
  103. }
  104. MPU6050_FIFO[0][10]=sum/10;

  105. sum=0;
  106. for(i=0;i<10;i++){
  107.    sum+=MPU6050_FIFO[1][i];
  108. }
  109. MPU6050_FIFO[1][10]=sum/10;

  110. sum=0;
  111. for(i=0;i<10;i++){
  112.    sum+=MPU6050_FIFO[2][i];
  113. }
  114. MPU6050_FIFO[2][10]=sum/10;

  115. sum=0;
  116. for(i=0;i<10;i++){
  117.    sum+=MPU6050_FIFO[3][i];
  118. }
  119. MPU6050_FIFO[3][10]=sum/10;

  120. sum=0;
  121. for(i=0;i<10;i++){
  122.    sum+=MPU6050_FIFO[4][i];
  123. }
  124. MPU6050_FIFO[4][10]=sum/10;

  125. sum=0;
  126. for(i=0;i<10;i++){
  127.    sum+=MPU6050_FIFO[5][i];
  128. }
  129. MPU6050_FIFO[5][10]=sum/10;
  130. }

  131. /**************************实现函数********************************************
  132. *函数原型:                void MPU6050_setClockSource(uint8_t source)
  133. *功  能:            设置  MPU6050 的时钟源
  134. * CLK_SEL | Clock Source
  135. * --------+--------------------------------------
  136. * 0       | Internal oscillator
  137. * 1       | PLL with X Gyro reference
  138. * 2       | PLL with Y Gyro reference
  139. * 3       | PLL with Z Gyro reference
  140. * 4       | PLL with external 32.768kHz reference
  141. * 5       | PLL with external 19.2MHz reference
  142. * 6       | Reserved
  143. * 7       | Stops the clock and keeps the timing generator in reset
  144. *******************************************************************************/
  145. void MPU6050_setClockSource(uint8_t source){
  146.     IICwriteBits(devAddr, MPU6050_RA_PWR_MGMT_1, MPU6050_PWR1_CLKSEL_BIT, MPU6050_PWR1_CLKSEL_LENGTH, source);

  147. }

  148. /** Set full-scale gyroscope range.
  149. * @param range New full-scale gyroscope range value
  150. * @see getFullScaleRange()
  151. * @see MPU6050_GYRO_FS_250
  152. * @see MPU6050_RA_GYRO_CONFIG
  153. * @see MPU6050_GCONFIG_FS_SEL_BIT
  154. * @see MPU6050_GCONFIG_FS_SEL_LENGTH
  155. */
  156. void MPU6050_setFullScaleGyroRange(uint8_t range) {
  157.     IICwriteBits(devAddr, MPU6050_RA_GYRO_CONFIG, MPU6050_GCONFIG_FS_SEL_BIT, MPU6050_GCONFIG_FS_SEL_LENGTH, range);
  158. }

  159. /**************************实现函数********************************************
  160. *函数原型:                void MPU6050_setFullScaleAccelRange(uint8_t range)
  161. *功  能:            设置  MPU6050 加速度计的最大量程
  162. *******************************************************************************/
  163. void MPU6050_setFullScaleAccelRange(uint8_t range) {
  164.     IICwriteBits(devAddr, MPU6050_RA_ACCEL_CONFIG, MPU6050_ACONFIG_AFS_SEL_BIT, MPU6050_ACONFIG_AFS_SEL_LENGTH, range);
  165. }

  166. /**************************实现函数********************************************
  167. *函数原型:                void MPU6050_setSleepEnabled(uint8_t enabled)
  168. *功  能:            设置  MPU6050 是否进入睡眠模式
  169.                                 enabled =1   睡觉
  170.                             enabled =0   工作
  171. *******************************************************************************/
  172. void MPU6050_setSleepEnabled(uint8_t enabled) {
  173.     IICwriteBit(devAddr, MPU6050_RA_PWR_MGMT_1, MPU6050_PWR1_SLEEP_BIT, enabled);
  174. }

  175. /**************************实现函数********************************************
  176. *函数原型:                uint8_t MPU6050_getDeviceID(void)
  177. *功  能:            读取  MPU6050 WHO_AM_I 标识         将返回 0x68
  178. *******************************************************************************/
  179. uint8_t MPU6050_getDeviceID(void) {

  180.     IICreadBytes(devAddr, MPU6050_RA_WHO_AM_I, 1, buffer);
  181.     return buffer[0];
  182. }

  183. /**************************实现函数********************************************
  184. *函数原型:                uint8_t MPU6050_testConnection(void)
  185. *功  能:            检测MPU6050 是否已经连接
  186. *******************************************************************************/
  187. uint8_t MPU6050_testConnection(void) {
  188.    if(MPU6050_getDeviceID() == 0x68)  //0b01101000;
  189.    return 1;
  190.            else return 0;
  191. }

  192. /**************************实现函数********************************************
  193. *函数原型:                void MPU6050_setI2CMasterModeEnabled(uint8_t enabled)
  194. *功  能:            设置 MPU6050 是否为AUX I2C线的主机
  195. *******************************************************************************/
  196. void MPU6050_setI2CMasterModeEnabled(uint8_t enabled) {
  197.     IICwriteBit(devAddr, MPU6050_RA_USER_CTRL, MPU6050_USERCTRL_I2C_MST_EN_BIT, enabled);
  198. }

  199. /**************************实现函数********************************************
  200. *函数原型:                void MPU6050_setI2CBypassEnabled(uint8_t enabled)
  201. *功  能:            设置 MPU6050 是否为AUX I2C线的主机
  202. *******************************************************************************/
  203. void MPU6050_setI2CBypassEnabled(uint8_t enabled) {
  204.     IICwriteBit(devAddr, MPU6050_RA_INT_PIN_CFG, MPU6050_INTCFG_I2C_BYPASS_EN_BIT, enabled);
  205. }

  206. /**************************实现函数********************************************
  207. *函数原型:                void MPU6050_initialize(void)
  208. *功  能:            初始化         MPU6050 以进入可用状态。
  209. *******************************************************************************/
  210. void MPU6050_initialize(void) {
  211.     MPU6050_setClockSource(MPU6050_CLOCK_PLL_XGYRO); //设置时钟
  212.     MPU6050_setFullScaleGyroRange(MPU6050_GYRO_FS_2000);//陀螺仪最大量程 +-1000度每秒
  213.     MPU6050_setFullScaleAccelRange(MPU6050_ACCEL_FS_2);        //加速度度最大量程 +-2G
  214.     MPU6050_setSleepEnabled(0); //进入工作状态
  215.          MPU6050_setI2CMasterModeEnabled(0);         //不让MPU6050 控制AUXI2C
  216.          MPU6050_setI2CBypassEnabled(0);         //主控制器的I2C与        MPU6050的AUXI2C        直通。控制器可以直接访问HMC5883L
  217. }




  218. /**************************************************************************
  219. 函数功能:MPU6050内置DMP的初始化
  220. 入口参数:无
  221. 返回  值:无
  222. 作    者:平衡小车之家
  223. **************************************************************************/
  224. void DMP_Init(void)
  225. {
  226.    u8 temp[1]={0};
  227.    i2cRead(0x68,0x75,1,temp);
  228.          printf("mpu_set_sensor complete ......\r\n");
  229.         if(temp[0]!=0x68)NVIC_SystemReset();
  230.         if(!mpu_init())
  231.   {
  232.           if(!mpu_set_sensors(INV_XYZ_GYRO | INV_XYZ_ACCEL))
  233.                    printf("mpu_set_sensor complete ......\r\n");
  234.           if(!mpu_configure_fifo(INV_XYZ_GYRO | INV_XYZ_ACCEL))
  235.                    printf("mpu_configure_fifo complete ......\r\n");
  236.           if(!mpu_set_sample_rate(DEFAULT_MPU_HZ))
  237.                    printf("mpu_set_sample_rate complete ......\r\n");
  238.           if(!dmp_load_motion_driver_firmware())
  239.                   printf("dmp_load_motion_driver_firmware complete ......\r\n");
  240.           if(!dmp_set_orientation(inv_orientation_matrix_to_scalar(gyro_orientation)))
  241.                    printf("dmp_set_orientation complete ......\r\n");
  242.           if(!dmp_enable_feature(DMP_FEATURE_6X_LP_QUAT | DMP_FEATURE_TAP |
  243.                 DMP_FEATURE_ANDROID_ORIENT | DMP_FEATURE_SEND_RAW_ACCEL | DMP_FEATURE_SEND_CAL_GYRO |
  244.                 DMP_FEATURE_GYRO_CAL))
  245.                    printf("dmp_enable_feature complete ......\r\n");
  246.           if(!dmp_set_fifo_rate(DEFAULT_MPU_HZ))
  247.                    printf("dmp_set_fifo_rate complete ......\r\n");
  248.           run_self_test();
  249.           if(!mpu_set_dmp_state(1))
  250.                    printf("mpu_set_dmp_state complete ......\r\n");
  251.   }
  252. }
  253. /**************************************************************************
  254. 函数功能:读取MPU6050内置DMP的姿态信息
  255. 入口参数:无
  256. 返回  值:无
  257. 作    者:平衡小车之家
  258. **************************************************************************/
  259. uint8_t Read_DMP(float* Pitch,float* Roll,float* Yaw)
  260. {        
  261. ……………………

  262. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
6050测试3.rar (598.63 KB, 下载次数: 298)


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏6 分享淘帖 顶3 踩
回复

使用道具 举报

沙发
ID:158903 发表于 2018-6-21 15:14 | 只看该作者

谢谢分享
回复

使用道具 举报

板凳
ID:357306 发表于 2018-6-23 16:25 | 只看该作者
高手!谢谢,学习了
回复

使用道具 举报

地板
ID:361002 发表于 2018-6-28 14:59 | 只看该作者
谢谢分享
回复

使用道具 举报

5#
ID:425665 发表于 2018-11-13 14:28 | 只看该作者
正好有个项目可以用到这个程序,感谢楼主。
回复

使用道具 举报

6#
ID:421518 发表于 2019-4-1 09:59 | 只看该作者
谢谢分享。。。。。
回复

使用道具 举报

7#
ID:430197 发表于 2019-4-2 12:13 | 只看该作者
学习了,谢谢分享
回复

使用道具 举报

8#
ID:578767 发表于 2019-7-6 01:23 | 只看该作者
学习 学习 谢谢
回复

使用道具 举报

9#
ID:578767 发表于 2019-7-6 01:24 | 只看该作者
学习了,谢谢分享。。
回复

使用道具 举报

10#
ID:585663 发表于 2019-7-22 20:39 | 只看该作者
uint8_t buffer[14];

int16_t  MPU6050_FIFO[6][11];
int16_t Gx_offset=0,Gy_offset=0,Gz_offset=0;

请问这段什么意思?实现什么功能
回复

使用道具 举报

11#
ID:196702 发表于 2019-8-3 00:33 | 只看该作者
感谢楼主。
回复

使用道具 举报

12#
ID:645237 发表于 2019-11-19 18:25 | 只看该作者
谢谢分享
回复

使用道具 举报

13#
ID:754694 发表于 2020-8-25 12:57 来自手机 | 只看该作者
好资料,谢谢分享
回复

使用道具 举报

14#
ID:229821 发表于 2020-9-11 22:47 | 只看该作者
好资料。谢谢楼主的共享精神。
回复

使用道具 举报

15#
ID:754694 发表于 2020-10-24 21:24 来自手机 | 只看该作者
32到8完美移植,多谢分享
回复

使用道具 举报

16#
ID:81138 发表于 2021-1-27 15:48 | 只看该作者
不知道电路是如何设计的
回复

使用道具 举报

17#
ID:928052 发表于 2021-8-8 20:26 | 只看该作者
为什么重复下载,需要重复扣分呢?
回复

使用道具 举报

18#
ID:767310 发表于 2021-8-26 16:21 | 只看该作者
编译提示NVIC_SystemReset没有定义,并且空间不足 ,请问楼主是用哪个型号的STM8芯片
回复

使用道具 举报

19#
ID:1038866 发表于 2022-7-17 09:05 | 只看该作者
高手!谢谢,学习
回复

使用道具 举报

20#
ID:189235 发表于 2023-10-14 00:51 | 只看该作者
#在这里快速回复#谢谢分享
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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