让找料更便捷
电子元器件
采购信息平台
生意随身带
随时随地找货
一站式电子元器件
采购平台
半导体行业观察第一站
标签:
摘要: 在前一篇博客中讲了下一些题外话,从本篇开始讲讲重点的知识,说说无线飞鼠过程用到的模块细说MPU6050一、 MPU6050简介二、 细节问题三、 相关技术四、 操作步骤五、 实现代码一、 MPU6050简介MPU6050集成了3轴加速度和3轴陀螺仪,是一款不错的传感器模块,可以用在很多方面,比如:四轴飞控、空中鼠标、两轮平衡车、GPS定位方面、游戏机、3D遥控器、平板设备等等,此模块给我们提供了强
MPU6050集成了3轴加速度和3轴陀螺仪,是一款不错的传感器模块,可以用在很多方面,比如:四轴飞控、空中鼠标、两轮平衡车、GPS定位方面、游戏机、3D遥控器、平板设备等等,此模块给我们提供了强大的数据供应,由于将加速度和陀螺仪集成到了一起,免去了组合这两个模块时之间的轴差问题,减少了包装问题,这两年很火,成了DIY制作者的最爱。
在淘宝上买MPU6050时,要注意一下几点:
查看卖家给出的介绍信息,是否刻意夸大,结合自己所学的知识进行判断。比如:当时在某个论坛上看到某位大神将的,tb上说他们的模块采用高性能的微处理器和先进的动力学解算与卡尔曼动态滤波算法,能够快速求解出模块当前的实时运动姿态。细心的你就会发现它的这种处理器根本就不能提供这种需求,也就是会所计算不出来。(STM8是8位的单片机,能做姿态解算和滤波吗?)……想了下都有点搞笑.这个论坛上有详细的解说:http://www、geek-workshop、com/thread-5820-1-1、html不要让模块受到碰撞,否则会影响他的性能。MPU6050数据是用IIC进行读取的,So必须学会IIC。类似于USB协议,不过和USB比起来可以说是小巫见大巫。
IIC技术概述
IIC数据传输
IIC总线寻址
IIC总线规定:从机地址有第一个字节的7位组成
(想要插入表格,可是在这里不会用了,直接从world中截张图算了)
IIC总线编号
从机的地址有固定部分和可编程部分组成。在一个系统中可能希望接入多个相同的从机,从机地址中科编程部分决定了可接入总线该类期间的最大数目
例如:一个从机的7位寻址中有4为是固定的,3位是可编程的,那个这时仅能寻址8个同类期间。
STM32F103中的IIC
这里主要看下载STM32中,IIC是怎么个分布:

当时开始做这个东西的时候参考了原子、野火的各个例子,再次感谢你们。
代码块MPU初始化:
void MPU_Init(){ ANBT_I2C_Configuration(); //IIC初始化 delay_ms(30); AnBT_DMP_MPU6050_Init(); //MPU6050 的DMP初始化}
下边是读取陀螺仪的数据函数:
void Read_Gyro_data(short *rxbuf){ unsigned long sensor_timestamp; unsigned char i = 0; short gyro[3], accel[3], sensors;//陀螺仪存放数组,加速度存放数组,返回状态量 unsigned char more; long quat[4]; //四元数存放数组 dmp_read_fifo(gyro, accel, quat, &sensor_timestamp, &sensors,&more); if(sensors & INV_WXYZ_QUAT) { rxbuf[0] = gyro[0]; rxbuf[1] = gyro[1]; rxbuf[2] = gyro[2]; printf("\r\nRead_Gyro_data gyro:\r\n"); for (i = 0; i < 3; i++) { printf(" %d ",gyro[i]); } printf("\r\n"); }}
其实参考了圆点博士的开源代码的,看了下匿名四轴下位机协议,当初试了下自己获取的数据是否正确,很不错的,下面是匿名的协议:
/* * 函数名:Data_Send_Status * 描述 :数据发送 传感器 的状态 根据匿名四轴最新上位机编写的显示姿态的程序 * 输入 :Pitch:俯仰角 Roll :横滚角 Yaw :航向角 gyro :陀螺仪 accel:加速度 * 输出 : * 调用 : */ void Data_Send_Status(float Pitch,float Roll,float Yaw,int16_t *gyro,int16_t *accel){ unsigned char i = 0; unsigned char j = 0; unsigned char _cnt = 0,sum = 0; unsigned int _temp; u8 data_to_send[12] = {0}; //发送数组,初始化为0 data_to_send[_cnt++] = 0xAA; // 帧头 170 data_to_send[_cnt++] = 0xAA; // 170 data_to_send[_cnt++] = 0x01; // 功能字 1 data_to_send[_cnt++] = 0; // 长度 0 //横滚角 _temp = (int)(Roll * 100); data_to_send[_cnt++] = BYTE1(_temp); // 高 8 位 data_to_send[_cnt++] = BYTE0(_temp); // 低8位 //俯仰角 _temp = 0 - (int)(Pitch * 100); data_to_send[_cnt++] = BYTE1(_temp); data_to_send[_cnt++] = BYTE0(_temp); //航向角 _temp = (int)(Yaw * 100); data_to_send[_cnt++] = BYTE1(_temp); data_to_send[_cnt++] = BYTE0(_temp); data_to_send[3] = _cnt - 4; //数据长度 //和校验 for(i = 0;i < _cnt;i++) sum += data_to_send[i]; data_to_send[_cnt++] = sum; data_to_send[_cnt++] = '\0'; //NRF_Tx_Dat(data_to_send); //发送到NRF缓冲区 //printf("\r\nData_Send_Status:\r\n");// for (j = 0; j < 12;j++)// {// printf(" %d ",data_to_send[j]);// } // printf("\r\n");// //串口发送数据 for(i=0;i<_cnt;i++) AnBT_Uart1_Send_Char(data_to_send[i]);} /* * 函数名:Send_Data * 描述 :用于发送传感器的数据 * 输入 :Gyro:陀螺仪存放字符指针 Accel:加速度存放指针 * 输出 : * 调用 : */ void Send_Data(int16_t *Gyro,int16_t *Accel){ unsigned char j = 0; unsigned char i = 0; unsigned char _cnt = 0; unsigned char sum = 0; u8 status;// unsigned int _temp; /* 匿名数据协议: 帧头、功能字、长度(len)、数据、校验和(Sum) 共32字节 接收端在接收到数据的时候进行对应的解析即可 */ u8 data_to_send[12]; data_to_send[_cnt++] = 0xAA; //帧头 AAAA data_to_send[_cnt++] = 0xAA; data_to_send[_cnt++] = 0x02; //功能字 data_to_send[_cnt++] = 0; //长度 data_to_send[_cnt++] = BYTE1(Accel[0]); data_to_send[_cnt++] = BYTE0(Accel[0]); data_to_send[_cnt++] = BYTE1(Accel[1]); data_to_send[_cnt++] = BYTE0(Accel[1]); data_to_send[_cnt++] = BYTE1(Accel[2]); data_to_send[_cnt++] = BYTE0(Accel[2]); data_to_send[_cnt++] = BYTE1(Gyro[0]); data_to_send[_cnt++] = BYTE0(Gyro[0]); data_to_send[_cnt++] = BYTE1(Gyro[1]); data_to_send[_cnt++] = BYTE0(Gyro[1]); data_to_send[_cnt++] = BYTE1(Gyro[2]); data_to_send[_cnt++] = BYTE0(Gyro[2]); data_to_send[_cnt++] = 0; data_to_send[_cnt++] = 0; data_to_send[_cnt++] = 0; data_to_send[3] = _cnt - 4; for(i = 0;i < _cnt;i++) sum += data_to_send[i]; data_to_send[_cnt++] = sum; data_to_send[_cnt++] = '\0';// printf("\r\nSend_Data:\r\n");// for (j = 0; j < 12;j++)// {// printf(" %d ",data_to_send[j]);// }// printf("\r\n");// delay_ms(1000);// status = NRF_Tx_Dat(data_to_send);// // /*判断发送状态*/// switch(status)// {// case MAX_RT:// printf("\r\n 主机端 没接收到应答信号,发送次数超过限定值,发送失败。 \r\n");// break;// case ERROR:// printf("\r\n 未知原因导致发送失败。 \r\n");// break;// case TX_DS:// printf("\r\n 主机端 接收到 从机端 的应答信号,发送成功! \r\n"); // break; // }// // delay_ms(1000);// //串口发送数据 for(i = 0;i <_cnt;i++) AnBT_Uart1_Send_Char(data_to_send[i]);}
在主函数中调用相应的函数即可获取相关数据,做一个简单的测试。
一下是我从串口中获取的数据:
以及其他数据:
因为代码中使用了圆点博士的开源代码,而且都是现成的,就不往出贴了……
以上只是做了个简单介绍,以及获取到了数据,但是并没有说明怎样处理数据,这是很关键的也是最重要的,本次无线飞鼠的数据不好处理,我做到现在数据也不是很稳定,任然有一定幅度的变化。
上一篇:已经是第一篇
| 型号 | 厂商 | 价格 |
|---|---|---|
| EPCOS | 爱普科斯 | / |
| STM32F103RCT6 | ST | ¥461.23 |
| STM32F103C8T6 | ST | ¥84 |
| STM32F103VET6 | ST | ¥426.57 |
| STM32F103RET6 | ST | ¥780.82 |
| STM8S003F3P6 | ST | ¥10.62 |
| STM32F103VCT6 | ST | ¥275.84 |
| STM32F103CBT6 | ST | ¥130.66 |
| STM32F030C8T6 | ST | ¥18.11 |
| N76E003AT20 | NUVOTON | ¥9.67 |