50. MPU6050传感器 您所在的位置:网站首页 如何测车速 50. MPU6050传感器

50. MPU6050传感器

2024-07-11 03:34| 来源: 网络整理| 查看: 265

50.5.2.2. 代码分析¶

官方的驱动主要是了MPL软件库(Motion Processing Library),要移植该软件库我们需要为它提供I2C读写接口、定时服务以及MPU6050的数据更新标志 若需要输出调试信息到上位机,还需要提供串口接口。

I2C读写接口

MPL库的内部对I2C读写时都使用i2c_write及i2c_read函数,在文件“inv_mpu.c”中给出了它们的接口格式, 见 代码清单:MPU6050-9。

代码清单:MPU6050-9 I2C读写接口(inv_mpu.c文件)¶ 1 2 3 4 5 6 7 8 9/* 以下函数需要定义成如下格式: * i2c_write(unsigned char slave_addr, unsigned char reg_addr, * unsigned char length, unsigned char const *data) * i2c_read(unsigned char slave_addr, unsigned char reg_addr, * unsigned char length, unsigned char *data) */ #define i2c_write Sensors_I2C_WriteRegister #define i2c_read Sensors_I2C_ReadRegister

这些接口的格式与我们上一小节写的I2C读写函数Sensors_I2C_ReadRegister及Sensors_I2C_WriteRegister一致,所以可直接使用宏替换。

提供定时服务

MPL软件库中使用到了延时及时间戳功能,要求需要提供delay_ms函数实现毫秒级延时,提供get_ms获取毫秒级的时间戳, 它们的接口格式也在“inv_mpu.c”文件中给出,见 代码清单:MPU6050-10。

代码清单:MPU6050-10 定时服务接口(inv_mpu.c文件)¶ 1 2 3 4 5 6 7/* * delay_ms(unsigned long num_ms) * get_ms(unsigned long *count) */ #define delay_ms Delay_ms #define get_ms get_tick_count

我们为接口提供的Delay_ms及get_tick_count函数定义在bsp_SysTick.c文件,我们使用SysTick每毫秒产生一次中断, 进行计时,见 代码清单:MPU6050-11。

代码清单:MPU6050-11 使用Systick进行定时(bsp_SysTick.c)¶ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48static __IO u32 TimingDelay; static __IO uint32_t g_ul_ms_ticks=0; /** * @brief us延时程序,1ms为一个单位 * @param * @arg nTime: Delay_ms( 1 ) 则实现的延时为 1 ms * @retval 无 */ void Delay_ms(__IO u32 nTime) { TimingDelay = nTime; while (TimingDelay != 0); } /** * @brief 获取节拍程序 * @param 无 * @retval 无 * @attention 在 SysTick 中断函数 SysTick_Handler()调用 */ void TimingDelay_Decrement(void) { if (TimingDelay != 0x00) { TimingDelay--; } } /** * @brief 获取当前毫秒值 * @param 存储最新毫秒值的变量 * @retval 无 */ int get_tick_count(unsigned long *count) { count[0] = g_ul_ms_ticks; return 0; } /** * @brief 毫秒累加器,在中断里每毫秒加1 * @param 无 * @retval 无 */ void TimeStamp_Increment (void) { g_ul_ms_ticks++; }

上述代码中的TimingDelay_Decrement和TimeStamp_Increment函数是在Systick的中断服务函数中被调用的, 见 代码清单:MPU6050-12。systick被配置为每毫秒产生一次中断, 而每次中断中会对TimingDelay变量减1,对g_ul_ms_ticks变量加1。它们分别用于Delay_ms函数利用TimingDelay的值进行阻塞延迟, 而get_tick_count函数获取的时间戳即g_ul_ms_ticks的值。

代码清单:MPU6050-12 Systick的中断服务函数(stm32f10x_it.c文件)¶ 1 2 3 4 5 6 7 8 9 10/** * @brief SysTick 中断服务函数. * @param None * @retval None */ void SysTick_Handler(void) { TimingDelay_Decrement(); TimeStamp_Increment(); }

提供串口调试接口

MPL代码库的调试信息输出函数都集中到了log_stm32.c文件中,我们可以为这些函数提供串口输出接口, 以便把这些信息输出到上位机,见 代码清单:MPU6050-3。

代码清单:MPU6050-13 串口调试接口(log_stm32.c文件)¶ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45/*串口输出接口*/ int fputcc(int ch) { /* 发送一个字节数据到USART1 */ USART_SendData(DEBUG_USART, (uint8_t) ch); /* 等待发送完毕 */ while (USART_GetFlagStatus(DEBUG_USART, USART_FLAG_TXE) == RESET); return (ch); } /*输出四元数数据*/ void eMPL_send_quat(long *quat) { char out[PACKET_LENGTH]; int i; if (!quat) return; memset(out, 0, PACKET_LENGTH); out[0] = '$'; out[1] = PACKET_QUAT; out[3] = (char)(quat[0] >> 24); out[4] = (char)(quat[0] >> 16); out[5] = (char)(quat[0] >> 8); out[6] = (char)quat[0]; out[7] = (char)(quat[1] >> 24); out[8] = (char)(quat[1] >> 16); out[9] = (char)(quat[1] >> 8); out[10] = (char)quat[1]; out[11] = (char)(quat[2] >> 24); out[12] = (char)(quat[2] >> 16); out[13] = (char)(quat[2] >> 8); out[14] = (char)quat[2]; out[15] = (char)(quat[3] >> 24); out[16] = (char)(quat[3] >> 16); out[17] = (char)(quat[3] >> 8); out[18] = (char)quat[3]; out[21] = '\r'; out[22] = '\n'; for (i=0; iCTRL|=SysTick_CTRL_ENABLE_Msk; /* LED 端口初始化 */ LED_GPIO_Config(); LED_BLUE; /* 串口通信初始化 */ USART_Config(); //MPU6050中断引脚 EXTI_Pxy_Config(); //I2C初始化 I2C_Bus_Init(); printf("mpu 6050 test start"); result = mpu_init(&int_param); if (result) { LED_RED; MPL_LOGE("Could not initialize gyro.result = %d\n",result); } else { LED_GREEN; } /* If you're not using an MPU9150 AND you're not using DMP features, this * function will place all slaves on the primary bus. * mpu_set_bypass(1); */ result = inv_init_mpl(); if (result) { MPL_LOGE("Could not initialize MPL.\n"); } /* 计算6轴和9轴传感器的四元数*/ inv_enable_quaternion(); inv_enable_9x_sensor_fusion(); /* 无运动状态时更新陀螺仪 * WARNING: These algorithms are mutually exclusive. */ inv_enable_fast_nomot(); /* inv_enable_motion_no_motion(); */ /* inv_set_no_motion_time(1000); */ /* 当温度变化时更新 陀螺仪*/ inv_enable_gyro_tc(); /* 允许read_from_mpl使用 MPL APIs. */ inv_enable_eMPL_outputs(); result = inv_start_mpl(); if (result == INV_ERROR_NOT_AUTHORIZED) { while (1) { MPL_LOGE("Not authorized.\n"); } } if (result) { MPL_LOGE("Could not start the MPL.\n"); } /* 设置寄存器,开启陀螺仪 */ /* 唤醒所有传感器 */ mpu_set_sensors(INV_XYZ_GYRO | INV_XYZ_ACCEL); /* 把陀螺仪及加速度数据放进FIFO */ mpu_configure_fifo(INV_XYZ_GYRO | INV_XYZ_ACCEL); mpu_set_sample_rate(DEFAULT_MPU_HZ); /* 重新读取配置,确认前面的设置成功 */ mpu_get_sample_rate(&gyro_rate); mpu_get_gyro_fsr(&gyro_fsr); mpu_get_accel_fsr(&accel_fsr); /*使用MPL同步配置 */ /* 设置每毫秒的采样率*/ inv_set_gyro_sample_rate(1000000L / gyro_rate); inv_set_accel_sample_rate(1000000L / gyro_rate); /* 设置chip-to-body原点矩阵. * 设置硬件单位为dps/g's/degrees 因子. */ inv_set_gyro_orientation_and_scale( inv_orientation_matrix_to_scalar(gyro_pdata.orientation), (long)gyro_fsr


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有