四轴飞行器1.3 MPU6050(大端)和M4的FPU开启方法

 原创文章,欢迎转载,转载请注明出处
      最近时间花在最多的地方就是STM32的I2C上了。之前就知道STM32的I2C并不好用,因为之前用过模拟的I2C,也写过AVR的I2C也就是TWI的硬件驱动,所以想试试写STM32的硬件I2C。。。为了避免库带来的麻烦,之前和特意将STM32F4的标准库升级到了1.3.0,但是貌似问题依旧。于是在网上找到了ST转为I2C写的CPAL的库,拿着它的英文手册和例子看了下,觉得很不错,功能相当的齐全,按照手册配置用起来应该不错,于是开始加载到自己的项目中。它需要一个定时器,用来管理超时,当通讯出现问题的时候,通过这个超时机制可以见得到,从而可以做一些简单的处理,它默认用的是systick中断,这个好办啊,用RTT的一个线程来替代systick或者用另外一个定时器就可以了,它还有一个要求,需要用到I2C相关的两个中断设置为最高优先级,虽然觉得优点不舒服哈,但是只能这样设置了,其实STM32中I2C的硬件缺陷就在这,需要第一时间响应I2C中断,否则就可能出现问题,就算自己写STM32的I2C,这两个中断优先级也需要设定的很高,可是之后发现了一个我认为可能接受不了的东西,就是在中断里面有一个宏,__CPAL_I2C_TIMEOUT ,定义如下

 1 #define __CPAL_I2C_TIMEOUT_DETECT                ((pDevInitStruct->wCPAL_Timeout == CPAL_I2C_TIMEOUT_MIN) || 2                                                  (pDevInitStruct->wCPAL_Timeout == CPAL_I2C_TIMEOUT_DEFAULT))
 3
 4 #define __CPAL_I2C_TIMEOUT(cmd, timeout)         pDevInitStruct->wCPAL_Timeout = CPAL_I2C_TIMEOUT_MIN + (timeout); 5                                                  while (((cmd) == 0) && (!__CPAL_I2C_TIMEOUT_DETECT)); 6                                                  if (__CPAL_I2C_TIMEOUT_DETECT) 7                                                  { 8                                                    return CPAL_I2C_Timeout (pDevInitStruct);  9                                                  }10                                                  pDevInitStruct->wCPAL_Timeout = CPAL_I2C_TIMEOUT_DEFAULT 

也就是说,这个CPAL库需要试用最高优先级的中断,而且在最高优先级的中断里面有个while,这可是最高优先级中断好么,我其他的中断还要不要响应了?RTT的线程调度还能不能愉快的调度了?积分还能不能在正确的时间内完成了, 积分出来的数据会不会漂的更厉害?果断弃之。。
      放弃CPAL库后,还有三个选择,买的板子是有写好的I2C的硬件库的,没有开源,为了快点做出来,就用他的库吧,当放进来编译好没错误后,下到板子里面运行,发现会卡死。。用不了。。当时不知道什么问题,后来想应该是没有用c99的原因,MDK默认是c89。还有两个选择,自己写硬件I2C或者用简单暴力的模拟I2C。。。折腾了好几天,进度太慢,我们首要任务是先飞起来,后面慢慢改,于是决定用模拟I2C,只要好点封装起来,后面把写好的更好的I2C放进去还是很容易的。
     模拟I2C就不多说了, 说下MPU6050吧。。。MPU6050网络上的资料那是非常的多,设置什么的都比较简单,我比较懒哈,没用FIFO,懒得设置,就打算从0x3B移植读到0X48,把所有数据读出来,简单的方法就是一个byte一个byte的读出来,然后强制转换成U16格式的再进行计算就可以了,可是这真的行得通吗?用union测试了下,STM32F4的是小端模式,也就是说数据的低位保存在内存的低地址中,而数据的高位保存在内存的高地址中,可是看看MPU6050的手册,你会发现它是大端模式,数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中。如下图:

如果全部顺序读出来,LSB和MSB是反的,要转换一次。。于是又懒了,I2C连续读都已经写好了,但是不用算了,利用struct和union解决这个问题好了,用如下的方式定义一个struct和union的混合结构:

 1 typedef struct
 2 {
 3 union
 4 {
 5 struct
 6 {
 7       u8 data_L;
 8   u8 data_H;
 9 } b;
10 u16 data;
11 } acce_x;
12 union
13 {
14 struct
15 {
16       u8 data_L;
17   u8 data_H;
18 } b;
19 u16 data;
20 } acce_y;
21 union
22 {
23 struct
24 {
25       u8 data_L;
26   u8 data_H;
27 } b;
28 u16 data;
29 } acce_z;
30
31 union
32 {
33 struct
34 {
35   u8 data_L;
36   u8 data_H;
37 } b;
38 u16 data;
39 } temp;
40
41 union
42 {
43 struct
44 {
45   u8 data_L;
46   u8 data_H;
47 } b;
48 u16 data;
49 } gyro_x;
50 union
51 {
52 struct
53 {
54   u8 data_L;
55   u8 data_H;
56 } b;
57 u16 data;
58 } gyro_y;
59 union
60 {
61 struct
62 {
63   u8 data_L;
64   u8 data_H;
65 } b;
66 u16 data;
67 } gyro_z;
68
69 }MPU6050_DATA_T;

读数据的时候就容易了,一个字节一个字节的读,例如读ACCX的高字节,读到mpu6050_data_t->acce_x.b.data_H中, 低字节读到mpu6050_data_t->acce_x.b.data_L中,而我们取数据的时候用mpu6050_data_t.acce_x.data就可以了,不需要进行LSB和MSB的数据转换了,哈,懒人用懒人的方法,不过这个方法毕竟效率不高,等飞机飞起来再改。。哈。。
读到的数据如下:

好像gyro_z的数据有点问题哈,后面再细看下,这些数值都是没有处理过的,裸数据,还要根据我们选的量程来进行转换才行。。

以前用过lsm303dlh算出过姿态数据的哈,就是反三角函数算,用的场合不一样,数据也没有滤波什么的,就这样算了。。这里终点是我们要用到反三角函数,M4可是带FPU的,不用白不用。。用了速度快很多。。哈。。开启FPU。。需要下面几个步骤:
在SystemIni 中有如下一句话

1   /* FPU settings ------------------------------------------------------------*/
2   #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
3     SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));  /* set CP10 and CP11 Full Access */
4   #endif

所以第一步需要设置这两个宏,__FPU_PRESENT,__FPU_USED,寻找一番,发现在STM32F4XX.h中

1 #define __MPU_PRESENT             1       /*!< STM32F4XX provides an MPU
2 #define __FPU_PRESENT             1       /*!< FPU present 已经定义好了

如果我们需要用到FPU,我们需要使用ARM为我们提供的数学函数,我们需要包涵arm_math.h头文件,
还需要添加arm_cortexMxx_math.lib到工程文件中,位于\Libraries\CMSIS\Lib\ARM中。

* The library installer contains prebuilt versions of the libraries in the <code>Lib</code> folder.
   * - arm_cortexM4lf_math.lib (Little endian and Floating Point Unit on Cortex-M4)
   * - arm_cortexM4bf_math.lib (Big endian and Floating Point Unit on Cortex-M4)
   * - arm_cortexM4l_math.lib (Little endian on Cortex-M4)
   * - arm_cortexM4b_math.lib (Big endian on Cortex-M4)
   * - arm_cortexM3l_math.lib (Little endian on Cortex-M3)
   * - arm_cortexM3b_math.lib (Big endian on Cortex-M3)
   * - arm_cortexM0l_math.lib (Little endian on Cortex-M0)

* - arm_cortexM0b_math.lib (Big endian on Cortex-M3)

STM32F407我们用的是小端模式,并且带FPU,支持浮点运算的,所以我们要添加的库是 arm_cortexM4lf_math.lib ,编译后会发现有错误,需要添加 ARM_MATH_CM4宏,好了,一切准备就绪,可以使用M4的FPU了。。哈。。
看一下stm32f40x\Libraries\CMSIS\DSP_Lib\Source目录,发现有不少文件,如下图:

解释看个名字也能直到大概哈,草靠网上的解释,矩阵计算,滤波函数说不定后面可以用到。。瞬间感觉高大上。。

BasicMathFunctions
提供浮点数的各种基本运算函数,如加减乘除等运算。
CommonTables
arm_common_tables.c文件提供位翻转或相关参数表。
ComplexMathFunctions
复述数学功能,如向量处理,求模运算的。
ControllerFunctions
控制功能,主要为PID控制函数。arm_sin_cos_f32/-q31.c函数提供360点正余弦函数表和任意角度的正余弦函数值计算功能。
FastMathFunctions
快速数学功能函数,提供256点正余弦函数表和任意任意角度的正余弦函数值计算功能,和Q值开平方运算:
Arm_cos_f32/_q15/_q31.c:提供256点余弦函数表和任意角度余弦值计算功能。
Arm_sin_f32/_q15/_q31.c:提供256点正弦函数表和任意角度正弦值计算功能。
Arm_sqrt_q15/q31.c:提供迭代法计算平方根的函数。对于M4F的平方根运算,通过执行VSQRT指令完成。
FilteringFunctions
滤波函数功能,主要为FIR和LMS(最小均方根)滤波函数。
MatrixFunctions
矩阵处理函数。
StatisticsFunctions
统计功能函数,如求平均值、计算RMS、计算方差/标准差等。
SupportFunctions
支持功能函数,如数据拷贝,Q格式和浮点格式相互转换,Q任意格式相互转换。
TransformFunctions
变换功能。包括复数FFT(CFFT)/复数FFT逆运算(CIFFT)、实数FFT(RFFT)/实数FFT逆运算(RIFFT)、和DCT(离散余弦变换)和配套的初始化函数。

接下来要做的就是把MPU6050裸数据处理下,传到matlab进行数据处理了。。要写matlab的串口咯。。。。

通讯协议也可能开始需要简单的策划下了,因为后面准备自己通过2401做遥控器的,通讯协议也应该开始考虑了。。

四轴飞行器1.3 MPU6050(大端)和M4的FPU开启方法,布布扣,bubuko.com

时间: 2024-08-08 22:05:44

四轴飞行器1.3 MPU6050(大端)和M4的FPU开启方法的相关文章

四轴飞行器1.4 姿态解算和Matlab实时姿态显示

原创文章,欢迎转载,转载请注明出处 MPU6050数据读取出来后,经过一个星期的努力,姿态解算和在matlab上的实时显示姿态终于完成了. 1:完成matlab的串口,并且实时通过波形显示数据 2:添加RTT查看CPU使用率的扩展功能,MPU6050读取数据的优化 3:四元素表示的坐标变化,四元素与欧拉角的关系和Madgwick的IMUupdate算法 4:飞控数据采集线程和数据处理线程的安排,类似于生产者与消费者的关系. 先放个效果视频... 如果看不了视频,请打开视屏网址:http://v.

四轴飞行器飞行原理与双闭环PID控制

四轴轴飞行器是微型飞行器的其中一种,相对于固定翼飞行器,它的方向控制灵活.抗干扰能力强.飞行稳定,能够携带一定的负载和有悬停功能,因此能够很好地进行空中拍摄.监视.侦查等功能,在军事和民用上具备广泛的运用前景. 四轴飞行器关键技术在于控制策略.由于智能控制算法在运行复杂的浮点型运算以及矩阵运算时,微处理器计算能力受限,难以达到飞行控制实时性的要求:而PID控制简单,易于实现,且技术成熟,因此目前主流的控制策略主要是围绕传统的PID控制展开. 1 四轴飞行器的结构与基本飞行原理 四轴飞行器结构主要

超酷MWC四轴飞行器DIY全套教程

本帖最后由 hitor 于 2013-8-17 22:06 编辑一.自己玩四轴的经历介绍.      各位模友大家好,我是哈工大航院的一名学生.我接触四轴的时间较早,由于我室友大二做科创就是做四轴的,那时候我们俩一人负责一个项目,他做四轴我做电动独轮车,我不太喜欢我的项目,烧了好多钱,最后也只能草草了事.我对四轴倒是很感兴趣,所以他一焊电路.写程序或是调试PID参数,我都像跟班似的死死的盯着他做的东西,有不懂的就向他请教,时间长了我也掌握了四轴的一些基本知识.几个月前我突发了做四轴的想法,但我不

四轴飞行器设计报告

单片机应用技术实训设计报告(四轴飞行器) 所属系部: 电气信息工程系 班 级: (2014)通信技术1班 姓 名: 彭世秋 指导老师: 施 芸 摘 要 为了满足四轴飞行器的设计要求,设计了以微控制器为核心的控制系统和算法.首先进行了各单元电路方案的比较论证,确定了硬件设计方案.四轴飞行器采用了固连在刚性十字架交叉结构上的4个无刷电机驱动的一种飞行器,以ARM公司的Context-M3 CPU內核为基础,围绕新的Context-M3 CPU內核演化而来的意法半导体公司的STM32F103高容量单片

四轴飞行器6050六轴传感器软件姿态解算

使用MPU6050硬件DMP解算姿态是非常简单的,下面介绍由三轴陀螺仪和加速度计的值来使用四元数软件解算姿态的方法. 我们先来看看如何用欧拉角描述一次平面旋转(坐标变换): 设坐标系绕旋转α角后得到坐标系,在空间中有一个矢量在坐标系中的投影为,在内的投影为由于旋转绕进行,所以Z坐标未变,即有. 转换成矩阵形式表示为: 整理一下: 所以从旋转到可以写成 上面仅仅是绕一根轴的旋转,如果三维空间中的欧拉角旋转要转三次: 上面得到了一个表示旋转的方向余弦矩阵. 不过要想用欧拉角解算姿态,其实我们套用欧拉

四轴飞行器1.2.3 STM32F407时钟配置和升级标准库文件

原创文章,欢迎转载,转载请注明出处 这个星期进度比较慢哈,只有周末和晚上下班回来才能做,事件不连续,琐碎的事情又比较多,挺烦的,有多琐碎呢?           1.本人有点小强迫症哈,虽然RTT将文件夹已经分类的很好了,但是在一个项目跟目录下这样放着看起来还是很不舒服的哈,于是强迫症范了,要整理下它.按照以前做项目的习惯,将程序分为四个层次,硬件层,驱动层,系统层和应用层,我们就整理下,对三个文件夹,其中硬件层和驱动层放在BSP文件夹里面,BSP文件里面再分硬件和驱动的文件夹,同时添加一个库文

四轴飞行器1.1 Matlab 姿态显示

四轴飞行器1.1 Matlab 姿态显示 开始做四轴了,一步一步来,东西实在很多,比较杂.先做matlab上位机,主要用来做数据分析,等板子到了可以写飞控的程序了,从底层一层一层开始写..希望能好好的完成它...关于matlab上位机,首先做个姿态显示,然后等板子来了,把板子底层程序写好后,加上matlab的串口接收部分,基本的环境就算搭建好了.... 这个代码写了一天,写到最后出现戏剧性的一幕,实在是太恶心了哈..开始自己的想法就是通过输入pitch roll yaw三个欧拉角,然后在空间中现

四轴飞行器1.2.1 RT-Thread 环境搭建

买的飞控板到了,开始写下位机的程序了,本来打算用UCOS的,因为以前用过,比较熟悉,可以很快上手,不过板子的卖家推荐了RT-Thread,以前虽然有接触过,但是没用过,于是去官网看了下,感觉还不错.其一这是咱们国人写的,其二USOS有的基本任务调度功能它都有了,其三它的GUI貌似原生支持中文(不确定),其四他有很多的附加组件,虽然这些组建大部分在以前做项目的时候都自己完成过,并且我并不怎么喜欢集成度太高的RTOS,但是这次可以尝试看看.还有它有些好的环形buffer,可以用来做串口的缓冲,哈,这

教你从零开始制作四轴飞行器

航模非玩具,请遵守法律法规及论坛四句箴言!安全飞行! *阅读不同的教程帖有助于更快地入门 *玩模型需要一颗淡定的心,请做好逐字逐句阅读数百页说明书甚至自学外语的准备,如果不能静下心来阅读.琢磨.研究,那么模型这个爱好不适合你 发帖不易,顶贴容易,且看且珍惜 8.17更新:3楼,什么是进角? 1.  如果你想享受飞行的乐趣,不想被装机,修机折磨,并且又有一定的经济条件的话,那么大疆精灵是你不二的选择.如果你想体验飞行和动手的双重乐趣,或者RMB是个问题,那么自己动手吧! 2.  善用论坛搜索功能事