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

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

[复制链接]
侯元祥 发布时间:2020-4-27 22:27
  第一次在ST论坛发帖,以前都是瞎逛,在大佬的帖子里学习了不少东西,这次看到这个什么创意挑战赛,说实话我也没看明白怎么参加这活动,什么格式啥的有啥要求,其实得不得奖无所谓,在这我主要把我做飞控的一些经验分享一下,如果大家喜欢,后期可能或软硬件全部开源。! l! {6 E% h( h0 a7 O. r4 g
既然是用STM32 那就用彻底了,而且我整的无人机从遥控到电调,到最终的主控全系列STM32,制版,程序全部自己来,遥控用的STM32F103C8,电调用的STM32F051 ,飞控用的STM32F446.& t* Q/ x$ M9 u) A
/ H6 b5 R5 [; a5 Q3 t" }) Q- c& X( T
赞 1 收藏 4 评论21 发布时间:2020-4-27 22:27

举报

21个回答
侯元祥 回答时间:2020-4-30 12:32:23
a316363723 发表于 2020-4-29 14:18
' f7 x$ j- o0 `( Q* P* d: S大佬,你这个可以飞多久呢?
1 o5 [; Y: u! q! R
目前是3S 2200 电池 测了一下13分钟左右
侯元祥 回答时间:2020-5-6 09:42:29
分享以下无刷电调的设计经验,无刷电调用的STM32F051,选择这个是因为自带比较器,这样采用虚拟中性点过零点换向的方法就比较好实现,另外,STM32自带的高级定时器输入互补PWM也是节省了不少时间,我使用的是传统的方波六步,原理比较粗暴,哪一相关断,直接把对应的GPIO配置为下拉输出,哪一相需要PWM调制,在配置为PWM复用输出,全部寄存器操作,节省了不少时间。利用了比较器的中断,换向事件完全在中断里解决。以下为方波六步的前两步代码,其他的以此类推。
" x9 o- M, ?0 kvoid STEP1( int PWM)
. `  Q2 Z& d2 r{+ H$ S9 V$ A% w! ]0 x
# ^5 ^" \$ }( R1 E9 F0 U# i
TIM1->CCR1=PWM;
( k* L; s! v! Z' z TIM1->CCR2=PWM;! F; \0 [9 K" c
TIM1->CCR3=PWM;  //给占空比
: l  b, G, a. c  P //关T5 7 E. S7 W) u2 [. \0 {
GPIOA->MODER=(GPIOA->MODER&0XffDFFFFF)|0X00100000; //PA10输出* {! Z5 F; o: \
GPIOA->BRR=0X00000400;//PA10置0 4 r5 t% P1 N. ]# B% O
//关T6; N4 A0 p3 w0 k0 }0 x
GPIOB->MODER=(GPIOB->MODER&0XFFFFFFF7)|0X00000004; //PB1输出
$ _- `: [1 f% u3 _: Y. j GPIOB->BRR =0X00000002;//PB1置0# I  V( {# s' m7 I; f
//常开T4- C* T4 P6 O8 p$ |" h$ b2 b' _
GPIOB->MODER=(GPIOB->MODER&0XFFFFFFFD)|0X00000001; //PB0输出 0 @% L5 Z( e9 b: X9 t
GPIOB->BSRR =0X00000001;//PB0置15 V- n0 L/ T4 ~: l
//关T3
$ ]* o8 d' N: t; A" b. x GPIOA->MODER=(GPIOA->MODER&0XFFF7FFFF)|0X00040000; //PA9输出
+ D  `; E9 o0 X. N; J% T% \( s# t GPIOA->BRR=0X00000200;//PA9置0. F/ i; [& A$ Q3 f# m8 D0 P) I
//开T1PWM
& P6 V6 i7 {) e9 s GPIOA->MODER=(GPIOA->MODER&0XFFFEFFFF)|0X00020000; //PA8 PWM
. O! ~. H& G4 p. q8 I+ C& O- o8 F: ~ //关T2
: E) `; R# O6 e. Y GPIOA->MODER=(GPIOA->MODER&0XFFFF7FFF)|0X00004000; //PA7输出$ J% Q# i6 ^7 E8 n( X( |. f6 C
GPIOA->BRR =0X00000080;//PA7置0
1 S- N: [8 ]+ y}* S9 J. Z7 `2 {$ G7 |1 ]

  u8 T. {0 T+ M! O$ A8 Evoid STEP2( int PWM)0 K6 r/ `4 s$ _$ w" B+ q5 L' K! p
{
7 r! J: D6 [1 U2 o7 H7 y. C% } TIM1->CCR1=PWM;
4 {. \6 G6 `* e2 w9 H* u2 S TIM1->CCR2=PWM;
* d6 g4 X) R/ w5 W; \$ G/ Z TIM1->CCR3=PWM;  //给占空比$ Z1 \# ^2 ~9 i9 @% `5 U6 H0 [9 G
//关T4, |' C1 _9 W$ j  j. D: d
GPIOB->MODER=(GPIOB->MODER&0XFFFFFFFD)|0X00000001; //PB0输出 4 O# ?* q8 L6 d; d
GPIOB->BRR =0X00000001;//PB0置0
9 B) r3 {: n8 {2 J, c //关T3
5 [& U6 p) m( e; P+ u5 s2 M GPIOA->MODER=(GPIOA->MODER&0XFFF7FFFF)|0X00040000; //PA9输出
6 B# D5 c( e) _) J3 j* f GPIOA->BRR=0X00000200;//PA9置0 ) @+ `6 F1 ]6 P9 T$ s1 j
//T1常开* Y* R9 y. b+ w- ]7 q
GPIOA->MODER=(GPIOA->MODER&0XFFFDFFFF)|0X00010000; //PA8输出
0 Z% H: C5 ~* t" }' e7 o GPIOA->BSRR=0X00000100;//PA8置1
3 e3 ^# c" h2 r3 K0 h6 F //关T2
5 q  J3 Z2 z/ o# p2 n3 h GPIOA->MODER=(GPIOA->MODER&0XFFFF7FFF)|0X00004000; //PA7输出, v4 }$ {0 ~# a& m( V( I3 b; o
GPIOA->BRR =0X00000080;//PA7置0  
& B- F8 l4 q- O //开T6PWM) F" c3 _  M6 b4 w$ Y' `2 n' Q( |# S
GPIOB->MODER=(GPIOB->MODER&0XFFFFFFFB)|0X00000008; //PB1 PWM
9 p1 \. X( t% K6 Z //关T5 ; X# Q5 `; `+ O: K* ^+ O
GPIOA->MODER=(GPIOA->MODER&0XffDFFFFF)|0X00100000; //PA10输出
. C) h6 }% k9 G( s GPIOA->BRR=0X00000400;//PA10置0  . u" }3 k' \, s
}- R0 D( @( b; p6 s; a+ s
% X0 W2 v; e( y/ E  a; m& Q- s# y
侯元祥 回答时间:2020-5-2 08:44:31
FDA生成的滤波器滤波器参数本质上是,冲击响应函数,两个系数矩阵,他这里还有一个增益Gain,我们用的时候只需要把这个转为差分方程就可以,下面我直接贴上代码
( e( `! H) f! @- ]' F, ?+ Nfloat Butterworth_Low_Pass(float Data_IN) //2阶巴特沃斯低通滤波器截止频率30HZ FS=1000
4 D% J& N+ ]. K" A* q& ]: N{9 n. r  c/ \' e9 {6 |4 q4 ]
float Gain=0.0078202080334971915 ;
- r  ^  T$ |' e7 ]; A. [" @& r  ?! Z- e% w; G' y' m
float b[]={1,2,1};
, u$ N! n2 M: @+ H: T& b float a[]={1, -1.7347257688092752 , 0.76600660094326389 };
' |7 P& Z, z8 ~  h& B
9 q! G. B! W# F& Q* Y" o9 g" T3 k2 w static float Last_Data_IN=0;
* P. l5 }; Z5 \& d) [ static float Last_Last_Data_IN=0;7 [+ N1 L! J' e6 D
  float Data_OUT;
: {$ y: m2 @: y* R! R static float Last_Data_OUT=0;
( j, k/ U+ _6 ~" E' T% T static float Last_Last_Data_OUT=0; 7 E6 t, I# T: d
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];
6 f/ S) c, {  k$ O, H1 J9 v" }. P Last_Last_Data_IN=Last_Data_IN;
7 N& x4 D0 _- `  }( R Last_Data_IN=Data_IN;/ f; K& Z7 Z+ M9 I% Q
Last_Last_Data_OUT=Last_Data_OUT;
, c$ Q! g0 m) Y4 X3 ]& E Last_Data_OUT=Data_OUT;
3 V2 y; p0 A) X3 M2 ^9 Q/ G  return  Data_OUT;9 N) P7 ^5 N5 f6 w% X& x9 w* j  O3 M* _
}- t% w% O1 ?  H1 K, l) T# ~
上面代码Gain即为matlab生成的Gain参数,b和a分别对应matlab中的Num参数与Dem参数,函数输入为带滤波的数据,返回为滤波后的数据,需要注意的是,我是按采样频率为1000HZ设计的,就必须要求该函数的执行周期为1ms,不然滤波效果就与期望的不符了。
# E0 `6 @1 U( E3 a$ o5 o& G! h
侯元祥 回答时间: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丝印层跑偏了,凑合用吧。
3 ]5 }! ]+ X0 a
捕获.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元了,% E2 U. O5 L/ x' X% V! r7 ]+ B
MDK截图1.PNG
侯元祥 回答时间:2020-4-27 23:07:13
遥控器用的STM32F103 ,毕竟没有那么高的运算量,简单采集的摇杆电压,通信就行,另外,遥控器部分也加入了陀螺仪与磁力计,可以实现类似重力感应控制的功能。供电采用的是18650电池,USB接口充电,充电芯片烂大街的TP4056,加了一个比较“高大上的屏幕,串口控制”,有上位机编辑界面,感觉挺好用,减轻了不少单片机的负担,再配合上串口DMA,完全不占用CPU资源,另外这里的NRF24L01,使用了带数据的ACK功能,实现了双向传输,飞机也可以把数据回传给遥控,比如姿态信息,剩余电量等。
; k4 t& {9 i! T9 {3 Y0 C

遥控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机架上,完美。5 ]5 R' F$ W/ V+ C) V
电调第一版.PNG
电调第二版.PNG
电调第三版.PNG
电调第4版.PNG
电调安装.jpg
侯元祥 回答时间:2020-4-27 23:34:13
另外电调的协议我介绍一下,传统电调基本都是PWM信号,根据PWM高电平时间决定占空比,新一点的现在都是数字电调,比如Dsht600啥的,鄙人也研究过这个Dshot协议,挺好,但是转到STM32上,我就没整成,其实就是定时器配合DMA,接收数据,后来一寻思,串口不是更好么,DMA不比定时器简单多了,最后就整成串口的了,而且四个电调的RX我接到了一起,接到主控F446的一个TX上,主控一下发送四个电调的油门信息,各个电调把自己的那部分提取出来,舍弃其他的就可以了,这样,四个电调只需要一个数据线,当然保证实时性,串口波特率要比较高,板间通信也无所谓了,缺点就是,这个电调通用性不好,甚至是没有通用性,只能配合我这个飞控。
! Y+ L3 w$ v8 u" B
电调代码.PNG
侯元祥 回答时间:2020-4-28 08:58:47
自己回复自己的贴子还需要审核
TLLED 回答时间:2020-4-28 09:26:45
侯元祥 发表于 2020-4-28 08:589 \* k  [& X% z2 d3 t
自己回复自己的贴子还需要审核

4 ]  H( ?$ N5 D( y, q发的多了就不用了
李康1202 回答时间:2020-4-28 09:40:30
大老牛
mmuuss586 回答时间:2020-4-28 10:14:23
4 S$ \/ s1 H  l5 Y
不错,支持
侯元祥 回答时间:2020-4-28 11:41:12
1 C& m  g, G1 }0 _$ [9 J
5 X- J! l' v9 |- k* ~8 F
视频+ A$ t' B% G, s& y$ }- [6 U
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管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版