找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1884|回复: 0
收起左侧

通过stm32cubemax完成配置,与mpu6050通信兵读取数据,将数据通过串口打印出来

[复制链接]
ID:806997 发表于 2020-7-22 23:28 | 显示全部楼层 |阅读模式
通过stm32cubemax完成配置,与mpu6050通信并读取数据,将数据通过串口打印出来

单片机源程序如下:
  1. /* USER CODE END Header */

  2. /* Includes ------------------------------------------------------------------*/
  3. #include "main.h"
  4. #include "i2c.h"
  5. #include "stm32f4xx_hal.h"
  6. #include "usart.h"
  7. #include "gpio.h"
  8. #include "stdio.h"

  9. /* Private includes ----------------------------------------------------------*/
  10. #include "inv_mpu.h"
  11. #include "inv_mpu_dmp_motion_driver.h"
  12. #include <math.h>
  13. #define ADDRESS_W 0xD0   //写地址 0x68
  14. #define ADDRESS_R 0xD1   //读地址  0x69
  15. #define MPU_PWR_MGMT1_REG                0X6B        //电源管理寄存器1
  16. #define MPU_GYRO_CFG_REG                0X1B        //陀螺仪配置寄存器
  17. #define MPU_ACCEL_CFG_REG                0X1C        //加速度计配置寄存器
  18. #define MPU_SAMPLE_RATE_REG                0X19        //陀螺仪采样频率分频器
  19. #define MPU_INT_EN_REG                        0X38        //中断使能寄存器
  20. #define MPU_USER_CTRL_REG                0X6A        //用户控制寄存器
  21. #define MPU_FIFO_EN_REG                        0X23        //FIFO使能寄存器
  22. #define MPU_INTBP_CFG_REG                0X37        //中断/旁路设置寄存器
  23. #define MPU_DEVICE_ID_REG                0X75        //器件ID寄存器
  24. #define MPU_PWR_MGMT2_REG                0X6C        //电源管理寄存器2
  25. #define MPU_CFG_REG                                0X1A        //配置寄存器 低通滤波器配置寄存器
  26. #define MPU_TEMP_OUTH_REG                0X41        //温度值高八位寄存器
  27. #define MPU_TEMP_OUTL_REG                0X42        //温度值低8位寄存器

  28. #define MPU_ACCEL_XOUTH_REG                0X3B        //加速度值,X轴高8位寄存器
  29. #define MPU_ACCEL_XOUTL_REG                0X3C        //加速度值,X轴低8位寄存器
  30. #define MPU_ACCEL_YOUTH_REG                0X3D        //加速度值,Y轴高8位寄存器
  31. #define MPU_ACCEL_YOUTL_REG                0X3E        //加速度值,Y轴低8位寄存器
  32. #define MPU_ACCEL_ZOUTH_REG                0X3F        //加速度值,Z轴高8位寄存器
  33. #define MPU_ACCEL_ZOUTL_REG                0X40        //加速度值,Z轴低8位寄存器

  34. #define MPU_GYRO_XOUTH_REG                0X43        //陀螺仪值,X轴高8位寄存器
  35. #define MPU_GYRO_XOUTL_REG                0X44        //陀螺仪值,X轴低8位寄存器
  36. #define MPU_GYRO_YOUTH_REG                0X45        //陀螺仪值,Y轴高8位寄存器
  37. #define MPU_GYRO_YOUTL_REG                0X46        //陀螺仪值,Y轴低8位寄存器
  38. #define MPU_GYRO_ZOUTH_REG                0X47        //陀螺仪值,Z轴高8位寄存器
  39. #define MPU_GYRO_ZOUTL_REG                0X48        //陀螺仪值,Z轴低8位寄存器

  40. //定义输出速度
  41. #define DEFAULT_MPU_HZ  (100)                //100Hz

  42. //q30格式,long转float时的除数.
  43. #define q30  1073741824.0f
  44. /* USER CODE END Includes */

  45. /* Private typedef -----------------------------------------------------------*/
  46. /* USER CODE BEGIN PTD */

  47. /* USER CODE END PTD */

  48. /* Private define ------------------------------------------------------------*/

  49. /* USER CODE BEGIN PD */

  50. /* USER CODE END PD */

  51. /* Private macro -------------------------------------------------------------*/
  52. /* USER CODE BEGIN PM */

  53. /* USER CODE END PM */

  54. /* Private variables ---------------------------------------------------------*/
  55. void MPU_6050_Init(void);
  56. unsigned char  MPU_Set_LPF(unsigned short lpf);
  57. //DMP库需要的函数
  58. unsigned char HAL_i2c_write(unsigned char slave_addr, unsigned char reg_addr, unsigned char length, unsigned char const *data);
  59. unsigned char HAL_i2c_read(unsigned char slave_addr, unsigned char reg_addr, unsigned char length, unsigned char const *data);
  60. //读取 温度传感器   陀螺仪  加速度数据
  61. void read_all(void);
  62. //陀螺仪方向控制
  63. unsigned short inv_orientation_matrix_to_scalar(const signed char *mtx);
  64. //方向转换
  65. unsigned short inv_row_2_scale(const signed char *row);
  66. //MPU6050自测试
  67. //返回值:0,正常
  68. //    其他,失败
  69. unsigned char run_self_test(void);
  70. //mpu6050,dmp初始化
  71. //返回值:0,正常
  72. //    其他,失败
  73. unsigned char mpu_dmp_init(void);
  74. //得到dmp处理后的数据(注意,本函数需要比较多堆栈,局部变量有点多)
  75. //pitch:俯仰角 精度:0.1°   范围:-90.0° <---> +90.0°
  76. //roll:横滚角  精度:0.1°   范围:-180.0°<---> +180.0°
  77. //yaw:航向角   精度:0.1°   范围:-180.0°<---> +180.0°
  78. //返回值:0,正常
  79. //    其他,失败
  80. unsigned char mpu_dmp_get_data(float *pitch,float *roll,float *yaw);
  81. /* USER CODE BEGIN PV */

  82. /* USER CODE END PV */

  83. /* Private function prototypes -----------------------------------------------*/
  84. void SystemClock_Config(void);
  85. /* USER CODE BEGIN PFP */

  86. /* USER CODE END PFP */

  87. /* Private user code ---------------------------------------------------------*/
  88. /* USER CODE BEGIN 0 */
  89. static signed char gyro_orientation[9] = { 1, 0, 0,
  90.                                            0, 1, 0,
  91.                                            0, 0, 1};

  92. float pitch,roll,yaw;                 //欧拉角
  93. //串口1发送1个字符
  94. //c:要发送的字符
  95. void usart1_send_char(uint8_t c)
  96. {
  97.     while(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_TC)==RESET){};
  98.     USART1->DR=c;  
  99. }

  100. //传送数据给匿名四轴上位机软件(V2.6版本)
  101. //fun:功能字. 0X01~0X1C
  102. //data:数据缓存区,最多28字节!!
  103. //len:data区有效数据个数
  104. void usart1_niming_report(uint8_t fun,uint8_t*data,uint8_t len)
  105. {
  106.         uint8_t send_buf[32];
  107.         uint8_t i;
  108.         if(len>28)return;        //最多28字节数据
  109.         send_buf[len+3]=0;        //校验数置零
  110.         send_buf[0]=0XAA;        //帧头
  111.         send_buf[1]=0XAA;        //帧头
  112.         send_buf[2]=fun;        //功能字
  113.         send_buf[3]=len;        //数据长度
  114.         for(i=0;i<len;i++)send_buf[4+i]=data[i];                        //复制数据
  115.         for(i=0;i<len+4;i++)send_buf[len+4]+=send_buf[i];        //计算校验和       
  116.         for(i=0;i<len+5;i++)usart1_send_char(send_buf[i]);        //发送数据到串口1
  117. }
  118. //发送加速度传感器数据+陀螺仪数据(传感器帧)
  119. //aacx,aacy,aacz:x,y,z三个方向上面的加速度值
  120. //gyrox,gyroy,gyroz:x,y,z三个方向上面的陀螺仪值
  121. void mpu6050_send_data(short aacx,short aacy,short aacz,short gyrox,short gyroy,short gyroz)
  122. {
  123.         uint8_t tbuf[18];
  124.         tbuf[0]=(aacx>>8)&0XFF;
  125.         tbuf[1]=aacx&0XFF;
  126.         tbuf[2]=(aacy>>8)&0XFF;
  127.         tbuf[3]=aacy&0XFF;
  128.         tbuf[4]=(aacz>>8)&0XFF;
  129.         tbuf[5]=aacz&0XFF;
  130.         tbuf[6]=(gyrox>>8)&0XFF;
  131.         tbuf[7]=gyrox&0XFF;
  132.         tbuf[8]=(gyroy>>8)&0XFF;
  133.         tbuf[9]=gyroy&0XFF;
  134.         tbuf[10]=(gyroz>>8)&0XFF;
  135.         tbuf[11]=gyroz&0XFF;
  136.         tbuf[12]=0;//因为开启MPL后,无法直接读取磁力计数据,所以这里直接屏蔽掉.用0替代.
  137.         tbuf[13]=0;
  138.         tbuf[14]=0;
  139.         tbuf[15]=0;
  140.         tbuf[16]=0;
  141.         tbuf[17]=0;
  142.         usart1_niming_report(0X02,tbuf,18);//传感器帧,0X02
  143. }       
  144. //通过串口1上报结算后的姿态数据给电脑(状态帧)
  145. //roll:横滚角.单位0.01度。 -18000 -> 18000 对应 -180.00  ->  180.00度
  146. //pitch:俯仰角.单位 0.01度。-9000 - 9000 对应 -90.00 -> 90.00 度
  147. //yaw:航向角.单位为0.1度 0 -> 3600  对应 0 -> 360.0度
  148. //csb:超声波高度,单位:cm
  149. //prs:气压计高度,单位:mm
  150. void usart1_report_imu(short roll,short pitch,short yaw,short csb,int prs)
  151. {
  152.         uint8_t tbuf[12];          
  153.         tbuf[0]=(roll>>8)&0XFF;
  154.         tbuf[1]=roll&0XFF;
  155.         tbuf[2]=(pitch>>8)&0XFF;
  156.         tbuf[3]=pitch&0XFF;
  157.         tbuf[4]=(yaw>>8)&0XFF;
  158.         tbuf[5]=yaw&0XFF;
  159.         tbuf[6]=(csb>>8)&0XFF;
  160.         tbuf[7]=csb&0XFF;
  161.         tbuf[8]=(prs>>24)&0XFF;
  162.         tbuf[9]=(prs>>16)&0XFF;
  163.         tbuf[10]=(prs>>8)&0XFF;
  164.         tbuf[11]=prs&0XFF;
  165.         usart1_niming_report(0X01,tbuf,12);//状态帧,0X01
  166. }                                                                                    

  167. /* USER CODE END 0 */

  168. /**
  169.   * @brief  The application entry point.
  170.   * @retval int
  171.   */
  172. int main(void)
  173. {
  174.   /* USER CODE BEGIN 1 */
  175.         unsigned char DMP_INT_FLAG=0;
  176.         unsigned char rev_flag=0;
  177.   /* USER CODE END 1 */
  178.   

  179.   /* MCU Configuration--------------------------------------------------------*/

  180.   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  181.   HAL_Init();

  182.   /* USER CODE BEGIN Init */

  183.   /* USER CODE END Init */

  184.   /* Configure the system clock */
  185.   SystemClock_Config();

  186.   /* USER CODE BEGIN SysInit */

  187.   /* USER CODE END SysInit */

  188.   /* Initialize all configured peripherals */
  189.   MX_GPIO_Init();
  190.   MX_I2C3_Init();
  191.   MX_USART1_UART_Init();
  192.   /* USER CODE BEGIN 2 */
  193.   HAL_Delay(5000);
  194.         printf("MPU6050test\n");
  195.         MPU_6050_Init();// 可以尝试 直接打开FIFO
  196.         //初始化DMP
  197.         DMP_INT_FLAG=mpu_dmp_init();
  198.         printf("DMP_INT_FLAG %d \n",DMP_INT_FLAG);
  199.   /* USER CODE END 2 */

  200.   /* Infinite loop */
  201.   /* USER CODE BEGIN WHILE */
  202.   while (1)
  203.   {
  204.                 if((rev_flag=mpu_dmp_get_data(&pitch,&roll,&yaw))==0)
  205.                 {
  206.                         printf("俯仰角 = %.2f\r\n",pitch);
  207.                         printf("偏航角 = %.2f\r\n",roll);
  208.                         printf("翻滚角 = %.2f\r\n",yaw);
  209.                 }
  210. //                else
  211. //                {
  212. //                                printf("rev_flag %d\n",rev_flag);
  213. //                                HAL_Delay(100);//读取频率不能太慢 防止FIFO溢出
  214. //                }

  215.           read_all();
  216.           HAL_Delay(100);

  217.     /* USER CODE END WHILE */

  218.     /* USER CODE BEGIN 3 */
  219.   }
  220.   /* USER CODE END 3 */
  221. }

  222. /**
  223.   * @brief System Clock Configuration
  224.   * @retval None
  225.   */
  226. void SystemClock_Config(void)
  227. {
  228.   RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  229.   RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  230.   /** Configure the main internal regulator output voltage
  231.   */
  232.   __HAL_RCC_PWR_CLK_ENABLE();
  233.   __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
  234.   /** Initializes the CPU, AHB and APB busses clocks
  235.   */
  236.   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  237.   RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  238.   RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  239.   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  240.   RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  241.   RCC_OscInitStruct.PLL.PLLM = 8;
  242.   RCC_OscInitStruct.PLL.PLLN = 96;
  243.   RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  244.   RCC_OscInitStruct.PLL.PLLQ = 4;
  245.   if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  246.   {
  247.     Error_Handler();
  248.   }
  249.   /** Initializes the CPU, AHB and APB busses clocks
  250.   */
  251.   RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
  252.                               |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  253.   RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  254.   RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  255.   RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  256.   RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  257.   if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3) != HAL_OK)
  258.   {
  259.     Error_Handler();
  260.   }
  261. }

  262. /* USER CODE BEGIN 4 */
  263. void MPU_6050_Init(void)
  264. ……………………

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

所有资料51hei提供下载:
F411-MPU6050.7z (6.76 MB, 下载次数: 27)
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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