crazepony-gitbook

Crazepony软件框架讲解

飞控源代码部分,截止目前为止,都是属于一砖一瓦敲出来的。没有使用实时操作系统,我们称之为裸机代码,未使用操作系统裸跑的意思。为了满足各个层次用户的需求和体现出我们的努力,后续会试着移植一个FreeRtos的实时操作系统内核,因为bitcraze 团队就用的这个内核,向他们无限靠近是我们的目标。

那么,现在就结合裸机代码,来说说Crazepony的软件框架。

软件流程图

总体的流程图,就是这么简单。定时器4里面的任务,是整个飞机的核心。下面具体介绍实现细节。

初始化

学过 51单片机的都知道,任何一个处理器要正常运行后面的代码,首先必须得有一大段设备初始化的代码先运行,这些代码用于初始化处 理器的内部时钟、中断优先级、I/O 口的输入输出方向等等,也就是为后续代码正常运行,做了一个环境配置准备。

Crazepony 的主控是Crotex-M3内核,其实就是ARM架构发展到一定阶段的产物。Crotex-M3那是什么呢?还是ARM架构。于是,对ARM的初始化,首先必须要做的就是系统时钟初始化,中断向量表初始化,中断优先级初始化,I/O方向初始化,如下:

STM32内部模拟EEPROM初始化→LED初始化→延时函数初始化→蓝牙电源使能初始化→电机PWM输出初始化→电池电压AD初始化→IIC总线初始化→传感器初始化→PID参数初始化→无线收发模块初始化为接受模式→开 蓝牙→开定时器3→开定时器4。

初始化看起来很繁杂,很多,也没啥好说的。

接下来 ,程序运行到死循环while(1);程序会一直停在这里,等待数据中断的到来,而不是死机死在这里,这是有区别的,学过51的人都知道,我不再多说。

在初始化代码段,我们说到初始化了两个定时器,一个定时器3,一个定时器4,这两个定时器都可以打断死循环while(1)。定时器3用于广播机身姿态信息,定时器4的任务要繁重得多,用于 更新遥控数据+机身姿态融合+PID计算输出+PWM输出。可以看到,定时器4里面任务的优先级明显要比定时器3实时性要求更高,所以。中断优先级的顺序是:定时器4 > 串口中断 > 定时器3。姿态更新频率为1000Hz,广播信息更新频率为1Hz。

综上,有点乱,但是我们缕一缕。很简单,只有3个中断。定时器4是核心中断,所有的算法都是在这里实现的,机身的稳定也是靠这个中断来实现的

定时器4

可以看到定时器4的中断服务函数TIM4_IRQHandler()中,有个一Controler()

Controler()内部,DMP姿态输出→接收遥控器数据→接收串口数据→PID计算+PWM输出,这些任务构成了Controler()函数。

定时器3

Crazepony在飞行过程中,会向上位机发送姿态数据。于是,我们用了一个定时器来处理串口发送数据的问题。

在Crazepony上,ISP下载是通过UART1来实现的,有线串口打印用的UART1,2.1蓝牙透传也是接的UART1。所以,为了避免蓝牙透传和有线串口之间的数据冲突,我将蓝牙的供电设计成了软件使能方式启动蓝牙电源。这样一来,就可以程控切换数据通道,保证数据正常。

在回到定时器3的功能上来,先看具体程序段:

从定时器3的中断服务子程序可以看到,每进一次中断,向串口打印一次logo以及相关的姿态信息数据。此时,如果连接的是mircousb线,那么用串口助手可以看到如图所示的姿态信息反馈。

说到这里,有必要说一个事情就是,中断优先级的问题。

由于姿态数据对实时性要求是最高的,所以,处理姿态的代码应该是优先执行的,所以,定时器4的优先级要高于串口打印的优先级,即定时器4 > 串口中断 > 定时器3。