你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【创意】用STM32搞定无人机飞控系统(遥控、电调、主控)

[复制链接]
侯元祥 发布时间:2020-4-27 22:27
  第一次在ST论坛发帖,以前都是瞎逛,在大佬的帖子里学习了不少东西,这次看到这个什么创意挑战赛,说实话我也没看明白怎么参加这活动,什么格式啥的有啥要求,其实得不得奖无所谓,在这我主要把我做飞控的一些经验分享一下,如果大家喜欢,后期可能或软硬件全部开源。5 x# E2 S6 m( v
既然是用STM32 那就用彻底了,而且我整的无人机从遥控到电调,到最终的主控全系列STM32,制版,程序全部自己来,遥控用的STM32F103C8,电调用的STM32F051 ,飞控用的STM32F446.9 a  d4 u' ~5 s: H% K* J

& w3 X$ {# T3 G' T3 `
1 收藏 4 评论21 发布时间:2020-4-27 22:27

举报

21个回答
侯元祥 回答时间:2020-4-30 12:32:23
a316363723 发表于 2020-4-29 14:18: M4 j( i2 a% \" H3 ^3 i. d
大佬,你这个可以飞多久呢?

! L1 |) ~4 i- g6 g& x" y目前是3S 2200 电池 测了一下13分钟左右
侯元祥 回答时间:2020-5-6 09:42:29
分享以下无刷电调的设计经验,无刷电调用的STM32F051,选择这个是因为自带比较器,这样采用虚拟中性点过零点换向的方法就比较好实现,另外,STM32自带的高级定时器输入互补PWM也是节省了不少时间,我使用的是传统的方波六步,原理比较粗暴,哪一相关断,直接把对应的GPIO配置为下拉输出,哪一相需要PWM调制,在配置为PWM复用输出,全部寄存器操作,节省了不少时间。利用了比较器的中断,换向事件完全在中断里解决。以下为方波六步的前两步代码,其他的以此类推。  w1 v1 ?% V1 H3 ]% e; i* q. y
void STEP1( int PWM)
: `, g! L7 }  }( @; f, |2 |{
( e( `; O6 `0 k" i8 h5 Y8 d0 ~ * `3 I7 Y* j4 @! B* o3 A1 v
TIM1->CCR1=PWM;. C( _9 ^! G' j8 O* l
TIM1->CCR2=PWM;1 X- E1 f3 H* L# j9 L. B8 i
TIM1->CCR3=PWM;  //给占空比
  \" J, O/ }  C6 m  j, t //关T5 $ F. ^  d! M1 g( K
GPIOA->MODER=(GPIOA->MODER&0XffDFFFFF)|0X00100000; //PA10输出
3 L% n- }: _4 K; o3 ]" m GPIOA->BRR=0X00000400;//PA10置0 3 M& y# P6 Y6 P% ~7 N3 B
//关T6% ?8 Q; K: v8 f2 E& S" |/ z
GPIOB->MODER=(GPIOB->MODER&0XFFFFFFF7)|0X00000004; //PB1输出: G) T$ }1 p4 z0 |0 a+ h
GPIOB->BRR =0X00000002;//PB1置0
) |6 J/ V/ i7 w4 y9 d# A( f //常开T4! ?' i. O7 E/ k, a4 Z# x' K
GPIOB->MODER=(GPIOB->MODER&0XFFFFFFFD)|0X00000001; //PB0输出 % s% L' I+ ?0 _4 J) c! t5 K5 `' `4 C$ G
GPIOB->BSRR =0X00000001;//PB0置1
8 F: ^% r" ]; \3 r0 y% N8 @ //关T3; i) o- ]5 C; g4 s
GPIOA->MODER=(GPIOA->MODER&0XFFF7FFFF)|0X00040000; //PA9输出
: d, i6 ?/ O) Z3 k' Q GPIOA->BRR=0X00000200;//PA9置0" C* G5 Y, A: b# R4 z) x
//开T1PWM& w& B  y4 ?1 y5 c6 U* a3 W
GPIOA->MODER=(GPIOA->MODER&0XFFFEFFFF)|0X00020000; //PA8 PWM0 z! q& b3 Q- l2 }0 x1 \& n4 Q
//关T2
9 @9 t4 J5 H7 T8 S! E$ E" ?! Y1 g GPIOA->MODER=(GPIOA->MODER&0XFFFF7FFF)|0X00004000; //PA7输出9 h7 ?, s7 `- R6 D  M( Y# N- F+ m
GPIOA->BRR =0X00000080;//PA7置0 1 I0 F! R/ Z+ Y5 F7 d7 K) R: \- o4 L
}8 f# {5 Z' B8 U1 M1 @, e
0 X, {1 ^4 G' D9 N: n
void STEP2( int PWM)
. \0 m% v% L' g2 S1 D0 K{
: S. s+ l" L& w$ _ TIM1->CCR1=PWM;
; h" P* Q- y( S7 L TIM1->CCR2=PWM;- D. n6 N2 [3 e6 }
TIM1->CCR3=PWM;  //给占空比
7 n+ S* ]6 g" ` //关T4
; C' H! P  y/ ?" w+ e GPIOB->MODER=(GPIOB->MODER&0XFFFFFFFD)|0X00000001; //PB0输出 2 V" b+ F5 z7 |# r* a7 [
GPIOB->BRR =0X00000001;//PB0置0
4 `( K9 n( G; @ //关T3+ w0 I* a  r% }8 E5 _5 M
GPIOA->MODER=(GPIOA->MODER&0XFFF7FFFF)|0X00040000; //PA9输出. h+ M. c8 D0 w( ?6 O
GPIOA->BRR=0X00000200;//PA9置0 : s: L8 d- r* M. k+ b! b; {; `
//T1常开4 m$ P- |; U# r! n, M+ q. ]
GPIOA->MODER=(GPIOA->MODER&0XFFFDFFFF)|0X00010000; //PA8输出
9 ~' O* p6 B3 {3 W$ g GPIOA->BSRR=0X00000100;//PA8置1   |8 R6 W/ M6 J9 L2 ~# _
//关T21 n. b) X$ c( f& c% d# r) Z4 S5 P
GPIOA->MODER=(GPIOA->MODER&0XFFFF7FFF)|0X00004000; //PA7输出
. Y! \+ g$ i3 I+ j9 b- E1 l GPIOA->BRR =0X00000080;//PA7置0  ! Z- \* e8 @& n3 R2 A
//开T6PWM8 h6 U7 |( _% M* O# f- }
GPIOB->MODER=(GPIOB->MODER&0XFFFFFFFB)|0X00000008; //PB1 PWM8 _' h% h- M1 m/ z7 V0 l
//关T5 * o( j. Z6 j; T9 u# x/ x6 C
GPIOA->MODER=(GPIOA->MODER&0XffDFFFFF)|0X00100000; //PA10输出5 C/ t& D; E) n4 b6 X" Q$ |7 P* x
GPIOA->BRR=0X00000400;//PA10置0  
" o: k6 c% ?3 x}8 M$ u: W9 }4 u2 S
8 E7 g6 T. g, P! C
侯元祥 回答时间:2020-5-2 08:44:31
FDA生成的滤波器滤波器参数本质上是,冲击响应函数,两个系数矩阵,他这里还有一个增益Gain,我们用的时候只需要把这个转为差分方程就可以,下面我直接贴上代码
$ k3 ?: L2 ]* @7 w' |6 hfloat Butterworth_Low_Pass(float Data_IN) //2阶巴特沃斯低通滤波器截止频率30HZ FS=1000
9 [% G- W4 |: A* ~4 ]4 S{
- h+ ^5 T2 I0 I! N% K# W float Gain=0.0078202080334971915 ;
; h$ \  W$ n/ R% l. ]8 H5 O
# S7 I; V2 D5 N& Q2 I$ [ float b[]={1,2,1};, r, X5 j! u( _( p. Y
float a[]={1, -1.7347257688092752 , 0.76600660094326389 };
& Y8 z$ \" c4 N; ]) a
* X) A4 j- g$ e) R! A0 k static float Last_Data_IN=0;
" J9 q; M4 L5 [* w static float Last_Last_Data_IN=0;2 [# ~9 v9 a3 _. w* W0 l; ]% ?
  float Data_OUT;
3 h. R" K1 T, \2 {' H% H5 Z static float Last_Data_OUT=0;# z2 @, a. D" q: y) _
static float Last_Last_Data_OUT=0;
  j% O; G2 u, w9 H Data_OUT=(Gain*(b[0]*Data_IN + b[1]*Last_Data_IN + b[2]*Last_Last_Data_IN) - a[1]*Last_Data_OUT - a[2]*Last_Last_Data_OUT)/a[0];& a% M' u; W. |9 c* V
Last_Last_Data_IN=Last_Data_IN;
5 r- R7 ]6 b2 k6 U& A0 m Last_Data_IN=Data_IN;
, H" u+ f! D$ `5 ?$ ~, i Last_Last_Data_OUT=Last_Data_OUT;" f$ Q+ m5 }8 H: @  l9 @
Last_Data_OUT=Data_OUT;1 ^% Y" F7 J9 w! l' U5 d8 R  R0 t
  return  Data_OUT;
9 d! @; s4 V' F}
- \: C  _+ N8 h" W' t- |9 q) c; P上面代码Gain即为matlab生成的Gain参数,b和a分别对应matlab中的Num参数与Dem参数,函数输入为带滤波的数据,返回为滤波后的数据,需要注意的是,我是按采样频率为1000HZ设计的,就必须要求该函数的执行周期为1ms,不然滤波效果就与期望的不符了。
$ H6 J6 ]! z/ @) ~2 c7 p
侯元祥 回答时间:2020-4-27 22:38:23
先来个整体图片吧,首先,最关注的可能是飞控,简单介绍一下硬件情况,主控此次用的是STM32F446 180MHZ主频,陀螺仪ICM20689(后期换为精度更高的BMI088),磁力计AK8975,气压计MS5611(后期换为精度更高的SPL06)。

整机照片

整机照片
侯元祥 回答时间:2020-4-27 22:47:30
两张图,降压模块用的TPS5430 ,通信模块用的NRF24L1+,预留了ST_LINK的调试接口,飞控部分硬件其实没啥,主要在于软件,注意:图中的PCB和原理图不是完全对应,由于我后期再接在PCB界面更改了部分芯片,原理图没有更新,以PCB为准。不知为何打样回的PCB丝印层跑偏了,凑合用吧。, A4 `$ f4 Q9 K  Q- m" V, F; Q
捕获.PNG
捕获2.PNG
PCB.jpg
侯元祥 回答时间:2020-4-27 22:57:29
用到F446主要是因为飞控算法会用到大量的浮点运算以及三角函数等,32F4系列的DSP功能,还是不错的,特别是三角函数库,快的一批,底层的话主要是传感器驱动,陀螺仪SPI, NRF24L01 SPI ,还有个flash也是SPI, 正好把F446的三个SPI全占用了,其余磁力计和气压计 走的IIC,模拟IIC ,毕竟这两种传感器实时性要求不是特别高,对于陀螺仪的选取,很多飞控用的都是MPU6000系列的,算得上是经典了,资料也多,其实最新的ICM系列(MPU系列升级系列)性能上更好,比如ICM20602,20689等,我一开始也是按ICM20689设计的,后来偶然发现博士的一款BMI888陀螺仪,参数更好,而且据说超强抗震,所以就临时换了博士的,但是,说实话,和ICM系列相比飞起来差别不大感觉,除了加速度计数据能好看点,但博士的一片块陀螺仪30元了,
/ F2 k3 I- o" K8 K) h; |& |8 Q
MDK截图1.PNG
侯元祥 回答时间:2020-4-27 23:07:13
遥控器用的STM32F103 ,毕竟没有那么高的运算量,简单采集的摇杆电压,通信就行,另外,遥控器部分也加入了陀螺仪与磁力计,可以实现类似重力感应控制的功能。供电采用的是18650电池,USB接口充电,充电芯片烂大街的TP4056,加了一个比较“高大上的屏幕,串口控制”,有上位机编辑界面,感觉挺好用,减轻了不少单片机的负担,再配合上串口DMA,完全不占用CPU资源,另外这里的NRF24L01,使用了带数据的ACK功能,实现了双向传输,飞机也可以把数据回传给遥控,比如姿态信息,剩余电量等。8 W% ^1 a& h: G3 Y, K

遥控PCB

遥控PCB

串口屏上位机

串口屏上位机
遥控1.jpg
遥控2.jpg
侯元祥 回答时间:2020-4-27 23:25:50
先说一下,等明天我上传个飞行视频,,接下来是电调,其实我主要学的就是电机控制这方面,做飞控主要是兴趣爱好,但是电调就偏硬件比较多了,(感觉电调比飞控难啊)涉及到无刷电机的控制,调速等等,这个电调来来回回我也做了好几版,最初的是用N+P结构的,后来换成全N结构,上了独立的MOS驱动,由于32F051自带比较器,这个真是太好了,话说除了F3和现在的G0,G4系列,其他的32系列都没有硬件比较器了吧,这个东起感觉用途还是非常大的,大家看看,我这电调前三板都是牺牲品,第三版其实基本没有问题了采用的是全NMOS,STM32F051+FD6288芯片,但是我嫌放飞机上走线不方便了,就有了最后的第四版,把四个电调放一起,放到飞机中心支架上,这样好处是,稳压芯片可以共用,滤波电容也不用单独放,正好放在我的330机架上,完美。/ P- j& k, B9 E
电调第一版.PNG
电调第二版.PNG
电调第三版.PNG
电调第4版.PNG
电调安装.jpg
侯元祥 回答时间:2020-4-27 23:34:13
另外电调的协议我介绍一下,传统电调基本都是PWM信号,根据PWM高电平时间决定占空比,新一点的现在都是数字电调,比如Dsht600啥的,鄙人也研究过这个Dshot协议,挺好,但是转到STM32上,我就没整成,其实就是定时器配合DMA,接收数据,后来一寻思,串口不是更好么,DMA不比定时器简单多了,最后就整成串口的了,而且四个电调的RX我接到了一起,接到主控F446的一个TX上,主控一下发送四个电调的油门信息,各个电调把自己的那部分提取出来,舍弃其他的就可以了,这样,四个电调只需要一个数据线,当然保证实时性,串口波特率要比较高,板间通信也无所谓了,缺点就是,这个电调通用性不好,甚至是没有通用性,只能配合我这个飞控6 A' {# p) W9 z: \8 O+ U$ v- c
电调代码.PNG
侯元祥 回答时间:2020-4-28 08:58:47
自己回复自己的贴子还需要审核
TLLED 回答时间:2020-4-28 09:26:45
侯元祥 发表于 2020-4-28 08:58" u2 B0 }7 s# O- d! q- Z  E
自己回复自己的贴子还需要审核
, M" M& p. z! C" J
发的多了就不用了
李康1202 回答时间:2020-4-28 09:40:30
大老牛
mmuuss586 回答时间:2020-4-28 10:14:23
- m5 \( K1 L& ~% L1 n9 V: E
不错,支持
侯元祥 回答时间:2020-4-28 11:41:12
+ m+ k0 S# o9 D& H+ c4 Z

' T* P; w& M9 T6 v; ^: Z6 F( G视频
" i$ G- r4 c; R" p4 a8 K
a316363723 回答时间:2020-4-29 14:18:16
大佬,你这个可以飞多久呢?
侯元祥 回答时间:2020-5-2 08:37:59
分享一下滤波器的设计把,特别是飞控中,不论是陀螺仪还是加速度计都含有大量的高频噪声,怎样设计滤波器是关键,这里我推荐用matlab自带的FDA滤波器设计工具,打开FDA,可以配置滤波器参数,以飞机常用的IIR巴特沃斯滤波器为例,采样频率FS根据你的陀螺仪输出速率而定我这里是1000HZ,Fc为截止频率,即高于该频率的信号一律滤除,我这里选择30HZ,点击下面的Design Filter,即可生成滤波器,点击Analysis_Coefficientts 就可以查看滤波器的参数了,有了这个参数,怎么用在单片机上,下面再说。
matlab1.PNG
matlab2.PNG
matlab3.PNG
matlab4.PNG
12下一页
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版