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

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

[复制链接]
侯元祥 发布时间:2020-4-27 22:27
  第一次在ST论坛发帖,以前都是瞎逛,在大佬的帖子里学习了不少东西,这次看到这个什么创意挑战赛,说实话我也没看明白怎么参加这活动,什么格式啥的有啥要求,其实得不得奖无所谓,在这我主要把我做飞控的一些经验分享一下,如果大家喜欢,后期可能或软硬件全部开源。! i  B% @! o" a3 l+ q. @
既然是用STM32 那就用彻底了,而且我整的无人机从遥控到电调,到最终的主控全系列STM32,制版,程序全部自己来,遥控用的STM32F103C8,电调用的STM32F051 ,飞控用的STM32F446." _, H5 U9 o. d% D! q. h( F$ O
1 c- l# H8 X! i; q
1 收藏 3 评论21 发布时间:2020-4-27 22:27

举报

21个回答
侯元祥 回答时间:2020-4-30 12:32:23
a316363723 发表于 2020-4-29 14:185 p# R5 F* ?4 l3 r2 e/ F7 V
大佬,你这个可以飞多久呢?
! M/ H* q& Z- R% Z% h+ C8 Y
目前是3S 2200 电池 测了一下13分钟左右
侯元祥 回答时间:2020-5-6 09:42:29
分享以下无刷电调的设计经验,无刷电调用的STM32F051,选择这个是因为自带比较器,这样采用虚拟中性点过零点换向的方法就比较好实现,另外,STM32自带的高级定时器输入互补PWM也是节省了不少时间,我使用的是传统的方波六步,原理比较粗暴,哪一相关断,直接把对应的GPIO配置为下拉输出,哪一相需要PWM调制,在配置为PWM复用输出,全部寄存器操作,节省了不少时间。利用了比较器的中断,换向事件完全在中断里解决。以下为方波六步的前两步代码,其他的以此类推。
+ x# g6 L% q9 I. z6 M: C7 j( mvoid STEP1( int PWM)
  y( d+ j  \( l' g7 w, W( v' J{8 ^% b( _9 _: g6 ~$ N

7 {" E! b# h: p5 u, ^ TIM1->CCR1=PWM;9 N5 R5 R5 Y7 [% m" d0 e
TIM1->CCR2=PWM;2 r- |# V; U: C  O) P" n8 D! U
TIM1->CCR3=PWM;  //给占空比8 n7 }/ L! `" s- X/ W; R; g
//关T5 $ Z5 F- ^* I/ ^% [' \
GPIOA->MODER=(GPIOA->MODER&0XffDFFFFF)|0X00100000; //PA10输出6 m# K* x. r8 S; w- P
GPIOA->BRR=0X00000400;//PA10置0 % _* D# T6 J7 Q
//关T6
6 a' D6 J/ P: R" X5 L5 `. O2 k( G GPIOB->MODER=(GPIOB->MODER&0XFFFFFFF7)|0X00000004; //PB1输出. t4 U& \1 c$ u1 G! @* R
GPIOB->BRR =0X00000002;//PB1置0
" H% }$ y6 ?; s% H1 a# ^ //常开T41 j$ h5 L0 a( K
GPIOB->MODER=(GPIOB->MODER&0XFFFFFFFD)|0X00000001; //PB0输出 ) X/ g8 |+ q; I8 Q- L
GPIOB->BSRR =0X00000001;//PB0置1
) i% g  T0 B+ Z, P //关T37 ]* g" D6 j. I  S0 [& ]( X: w* ~
GPIOA->MODER=(GPIOA->MODER&0XFFF7FFFF)|0X00040000; //PA9输出+ D2 W) l7 ]  H" _0 j% n
GPIOA->BRR=0X00000200;//PA9置0
/ P' {) E+ E- `/ @8 W //开T1PWM9 [# g) S1 l4 G/ i2 r( B8 ]
GPIOA->MODER=(GPIOA->MODER&0XFFFEFFFF)|0X00020000; //PA8 PWM# r7 D  @( H; r6 C
//关T2
. I! H* M, u: ~* S& y GPIOA->MODER=(GPIOA->MODER&0XFFFF7FFF)|0X00004000; //PA7输出+ A( n/ o/ [% @6 f3 P+ G
GPIOA->BRR =0X00000080;//PA7置0
# }. N2 Z2 E1 V* U0 W% b0 c; Z) e}
& b5 o, j. Z" P2 L1 \' v* ]
9 C% E! V$ ]/ @; P5 K" Zvoid STEP2( int PWM)  F& N. ^  j! L  Y* v* P
{
6 e, I( ^& e) o, m7 W$ ]5 d TIM1->CCR1=PWM;
9 c: s5 e$ L9 |3 s% l TIM1->CCR2=PWM;
; |5 }1 @6 B( ~1 f: @ TIM1->CCR3=PWM;  //给占空比* B' C9 E) [$ @- u6 ^
//关T4
3 w5 S: a# R7 a GPIOB->MODER=(GPIOB->MODER&0XFFFFFFFD)|0X00000001; //PB0输出 % Q. W" j, v; \) E
GPIOB->BRR =0X00000001;//PB0置0
9 S: t- M, T0 S4 B) P9 d //关T3' K7 s4 ]2 a- k) E; T. R1 w
GPIOA->MODER=(GPIOA->MODER&0XFFF7FFFF)|0X00040000; //PA9输出$ P7 }7 m9 J3 {/ [$ Z; |/ @" z
GPIOA->BRR=0X00000200;//PA9置0
- z* _* a& q# J. J) z //T1常开
' r" @, ~( U) }0 c, {3 O GPIOA->MODER=(GPIOA->MODER&0XFFFDFFFF)|0X00010000; //PA8输出
8 Q2 _( X$ N7 Y" L0 i( V* V GPIOA->BSRR=0X00000100;//PA8置1 " ?- T0 `/ S4 X: t4 H5 }, e
//关T2% v; h  ?$ ^$ Y/ N: U
GPIOA->MODER=(GPIOA->MODER&0XFFFF7FFF)|0X00004000; //PA7输出2 X4 m3 z) X: @  x
GPIOA->BRR =0X00000080;//PA7置0  
5 |7 p: A: |- s* l$ Y //开T6PWM
$ l" c; _' R/ B( M+ t& E! K GPIOB->MODER=(GPIOB->MODER&0XFFFFFFFB)|0X00000008; //PB1 PWM
6 f* O+ P: S7 M5 Y+ L //关T5
, p  e8 ~6 U" t+ h: _5 r GPIOA->MODER=(GPIOA->MODER&0XffDFFFFF)|0X00100000; //PA10输出  V% i' z7 O8 K! E% _  @0 g3 [
GPIOA->BRR=0X00000400;//PA10置0  
  \, q9 |- ~1 I5 b}
8 v* K' y: o* S' j* ]4 _
* I0 ~8 s; u8 o& d4 G: a* Z4 W
侯元祥 回答时间:2020-5-2 08:44:31
FDA生成的滤波器滤波器参数本质上是,冲击响应函数,两个系数矩阵,他这里还有一个增益Gain,我们用的时候只需要把这个转为差分方程就可以,下面我直接贴上代码. M4 i" C, l* S! ~' f6 U, O* b/ J" Q
float Butterworth_Low_Pass(float Data_IN) //2阶巴特沃斯低通滤波器截止频率30HZ FS=10009 B9 [' X1 ?$ q1 D2 S3 @0 S
{9 |$ K0 w6 F  _$ K6 ?# ]7 Y! \- I
float Gain=0.0078202080334971915 ;
) W3 p) R$ z' Z: y9 X6 f1 y2 U: b) @6 N+ S8 l8 X
float b[]={1,2,1};' O& \; o: M  n+ a+ ?
float a[]={1, -1.7347257688092752 , 0.76600660094326389 };. W8 j, w8 C% r0 E& S& M
9 @+ T, l! ~, ~- x# G2 O
static float Last_Data_IN=0;
9 `/ ~" l7 ?3 D) o: O1 i$ i# t2 l static float Last_Last_Data_IN=0;) D3 K2 g8 c' n
  float Data_OUT;
3 l+ D: j9 b& ~0 l- o, x8 R, C static float Last_Data_OUT=0;6 }) n. j) V4 H! m7 r
static float Last_Last_Data_OUT=0; 3 Z/ Z. ~( k. @9 p) H$ G/ C
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];
5 R2 d9 V8 e/ ]6 X  c% X  v Last_Last_Data_IN=Last_Data_IN;+ ?8 u8 I+ p2 U* ^6 Z
Last_Data_IN=Data_IN;
8 r* a% W1 G4 G Last_Last_Data_OUT=Last_Data_OUT;% L9 x( c6 g6 l/ M7 S  g
Last_Data_OUT=Data_OUT;# n5 s1 A  ]* _0 f2 S- H$ K; e
  return  Data_OUT;4 x# L4 p) g6 k0 m! e
}
9 E6 Y. O# `0 [, @7 \3 y上面代码Gain即为matlab生成的Gain参数,b和a分别对应matlab中的Num参数与Dem参数,函数输入为带滤波的数据,返回为滤波后的数据,需要注意的是,我是按采样频率为1000HZ设计的,就必须要求该函数的执行周期为1ms,不然滤波效果就与期望的不符了。
8 w( r9 S" B, P& i
侯元祥 回答时间: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丝印层跑偏了,凑合用吧。' H. x3 \5 {! C. _/ z
捕获.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元了,' K0 I' ?4 j6 g/ x# K
MDK截图1.PNG
侯元祥 回答时间:2020-4-27 23:07:13
遥控器用的STM32F103 ,毕竟没有那么高的运算量,简单采集的摇杆电压,通信就行,另外,遥控器部分也加入了陀螺仪与磁力计,可以实现类似重力感应控制的功能。供电采用的是18650电池,USB接口充电,充电芯片烂大街的TP4056,加了一个比较“高大上的屏幕,串口控制”,有上位机编辑界面,感觉挺好用,减轻了不少单片机的负担,再配合上串口DMA,完全不占用CPU资源,另外这里的NRF24L01,使用了带数据的ACK功能,实现了双向传输,飞机也可以把数据回传给遥控,比如姿态信息,剩余电量等。
1 Q, C5 m% A- J# N+ f

遥控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机架上,完美。, x" Q, v6 C1 v2 _' o
电调第一版.PNG
电调第二版.PNG
电调第三版.PNG
电调第4版.PNG
电调安装.jpg
侯元祥 回答时间:2020-4-27 23:34:13
另外电调的协议我介绍一下,传统电调基本都是PWM信号,根据PWM高电平时间决定占空比,新一点的现在都是数字电调,比如Dsht600啥的,鄙人也研究过这个Dshot协议,挺好,但是转到STM32上,我就没整成,其实就是定时器配合DMA,接收数据,后来一寻思,串口不是更好么,DMA不比定时器简单多了,最后就整成串口的了,而且四个电调的RX我接到了一起,接到主控F446的一个TX上,主控一下发送四个电调的油门信息,各个电调把自己的那部分提取出来,舍弃其他的就可以了,这样,四个电调只需要一个数据线,当然保证实时性,串口波特率要比较高,板间通信也无所谓了,缺点就是,这个电调通用性不好,甚至是没有通用性,只能配合我这个飞控2 F4 P: P% A, \6 [7 z( y  D( o* g
电调代码.PNG
侯元祥 回答时间:2020-4-28 08:58:47
自己回复自己的贴子还需要审核
TLLED 回答时间:2020-4-28 09:26:45
侯元祥 发表于 2020-4-28 08:582 L5 ?; I# M( ^, N! a, u/ S" f1 P# j
自己回复自己的贴子还需要审核

1 U/ l; U4 M5 s1 m- @! `* ~发的多了就不用了
李康1202 回答时间:2020-4-28 09:40:30
大老牛
mmuuss586 回答时间:2020-4-28 10:14:23
+ x0 \8 n4 v# X
不错,支持
侯元祥 回答时间:2020-4-28 11:41:12
( M" \1 z& j7 a7 O4 m  V9 y: B

( m; h( C, [+ J( `$ A$ L1 D视频
5 F; |" A; `5 ~, t
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管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版