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

【电机培训】玩个ST牌电调?

[复制链接]
RuiJey 发布时间:2017-8-30 20:56
本帖最后由 RuiJack 于 2017-8-30 21:22 编辑 6 @2 X6 @6 u2 d+ `. N6 o

* m' l0 b: N' b) Y* R      此次培训的视频和工具大家都差不多能介绍的都介绍了诶,我们还可以怎么玩玩?- p! T. H% I5 C3 b; }2 ^
      好像之前一直想把四轴用的电调也做来玩玩,但又不会电机控制咧。这次好像可以捡个便宜,用ST的库来仿照做一个?
, e, E( `9 r0 c4 l3 F9 V8 f4 X
! l+ K/ j$ r  W      那么,初步想法是这样的 -> 原来的工程 + PWM捕获 = 简易电调。" ]  O" L, j% K% U
      连工程都用原来的,可是懒到家了。
- N; t% @1 h( |4 q, ?      好了,首先来看看可用的资源。nucleo-F302的板子,电机驱动库SPN7的示例功工程中已经使用了TIM1,TIM2,TIM6,TIM16,额。为了保证尽可能少的改动,来看看还有哪个定时器可以用吧。( |7 [* o$ G5 _) H* D1 j
QQ截图20170830194600.png

/ u8 E7 J9 U$ P2 j8 v6 F      好吧,至少还有两个定时器可供选择,TIM15,TIM17,但是板子上已经有很多已经都有用了,有些也被电机驱动库作为其他功能用了,对照数据手册和nucleo-F302板子的AD PCB功能,来寻找可用的GPIO,这里就省略耗时的过程。来看下其中一个可用的IO
  e7 c% k( r; m7 r
QQ截图20170830195025.png

# Q- x2 e! m  }* g      是的,你没有看错,这还是UART2的RX引脚,已经被用了,好在可以暂时不用串口2来接收上位机数据,只用于向电脑发送调试数据。对应板子上的插针是0 C  Q0 _( j5 o/ ~
QQ截图20170830195414.png
5 H3 \2 ~  v% Q, h, l* Z! P! b
      刚好还有个插针,后面再介绍下这还有个方便测试的好处。+ P0 g% t1 v/ W7 c

  ?1 x/ L  E( U( K5 n      好了,继续正题。接下来开始初始化TIM15 CH2.之前还没有接触过HAL库,很多地方就参考库中的例程来了。
1 ?; N/ _6 ^7 T- D& j      首先是GPIO初始化。之所以连这个也提出来,是因为一直在纳闷儿引脚要配置为复用上下拉模式,可能有段时间没用32的定时器捕获模式了,有点忘了。( r2 r) e$ v, x
' @9 l  Q8 r, H. O
  1.   GPIO_InitStruct.Pin = GPIO_PIN_3;+ X+ W% h' p1 C( D2 ]
  2.   GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;. j9 r9 I$ V+ E* S! @) M: s6 y$ C
  3.   GPIO_InitStruct.Pull = GPIO_PULLDOWN;
      n8 B. a' U9 m7 ~8 B7 }4 c
  4.   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    ; ?4 h! H! z! |2 v( N2 t0 ]2 Q
  5.   GPIO_InitStruct.Alternate = GPIO_AF9_TIM15;
    # ?5 {( y: w0 X/ L' \3 q
  6.   HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);0 {. u8 @  N5 ?# m$ b1 b
复制代码
     然后是定时器基本参数的初始化。
  1.   htim15.Instance = TIM15;* \9 a: a; t& h& A/ J
  2.   htim15.Init.Prescaler = 72 - 1;
    - Z8 @7 _( o7 k1 V0 Q1 A( l2 _
  3.   htim15.Init.CounterMode = TIM_COUNTERMODE_UP;3 A; z8 g- h& |5 j
  4.   htim15.Init.Period = 0xFFFF;( |0 G# N- n3 O' `
  5.   htim15.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;8 L% ?* H5 J+ [9 w  I
  6.   htim15.Init.RepetitionCounter = 0;
    & I) C9 S! P5 x8 ]% D$ P* J1 G
  7.   htim15.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;' b2 {) h$ }, w4 D9 r8 i
  8.   if(HAL_TIM_IC_Init(&htim15) != HAL_OK)4 U# q) W( R$ ?* u8 x! ~
  9.   {- f+ ^3 u( G/ E* g
  10.         BSP_LED_On(LED2);        % V. M' X4 n" n: C$ |$ G
  11.   }# ]. {6 w1 \$ ?: T
复制代码
     接着是两个定时器通道的配置。这里直接使用了32定时器的PWM输入模式,以前在F1上就用得方便,这里也将两个内部输入通道连接到同一个输入引脚,CH2,通道1用作高电平脉宽采集,通道2用作PWM周期采集。两个通道的配置差异主要是采样边沿,和通道映射。
% T9 o! n+ p9 l
  1.   sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
    ! V0 C% D( F& u4 H
  2.   sConfigIC.ICFilter = 0;2 @9 c/ h2 {3 i% U
  3. ( e. Z: o4 t) C; c9 U4 e
  4.   sConfigIC.ICPolarity = TIM_ICPOLARITY_FALLING;
    % M# P2 F5 N  r; A
  5.   sConfigIC.ICSelection = TIM_ICSELECTION_INDIRECTTI;
      @: x) e, Y4 m1 y; m
  6.   if(HAL_TIM_IC_ConfigChannel(&htim15, &sConfigIC, TIM_CHANNEL_1) != HAL_OK)
    % `9 I% _0 S2 W" }( j2 _
  7.   {                . M* o4 J# j8 b7 S  V$ G& `
  8.         BSP_LED_On(LED2);: p# ]5 m" Y  Q% ?' Y( u' w
  9.   }
    . z+ `6 h0 U+ I0 m. l9 w: D5 O
  10. 8 ^* T/ _, x5 X. X
  11.   sConfigIC.ICPolarity = TIM_ICPOLARITY_RISING;
    * x# i, H" u9 c( F9 U# g
  12.   sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
    4 v1 O) q: O" ^$ g# C) J% y
  13.   if(HAL_TIM_IC_ConfigChannel(&htim15, &sConfigIC, TIM_CHANNEL_2) != HAL_OK)
    : u8 I7 C( |1 E
  14.   {
    % }2 c4 e& U: @
  15.         BSP_LED_On(LED2);8 R! B7 j5 c% }
  16.   }
    ' R7 w% W0 u2 a8 V: c% B
复制代码
    这里有一段是输入捕获的配置,跟以前STD库有些区别,还没细看,直接从HAL库例程中拿过来先用着2 T. W2 U  ?8 b4 E9 l: |) _+ H/ T1 K
  1.   sSlaveConfig.SlaveMode        = TIM_SLAVEMODE_RESET;0 S7 w0 e& @& G% N7 Z
  2.   sSlaveConfig.InputTrigger     = TIM_TS_TI2FP2;: S5 G8 N( G2 R# O
  3.   sSlaveConfig.TriggerPolarity  = TIM_TRIGGERPOLARITY_NONINVERTED;$ r1 e1 H9 m: x1 L) e
  4.   sSlaveConfig.TriggerPrescaler = TIM_TRIGGERPRESCALER_DIV1;
    . _; W& Q) v" o# U7 f" v
  5.   sSlaveConfig.TriggerFilter    = 0;
      w' H: u0 q- D8 f5 t
  6.   if(HAL_TIM_SlaveConfigSynchronization(&htim15, &sSlaveConfig) != HAL_OK)7 k7 Z, L: H& A1 ~+ }
  7.   {4 {0 d" B" }' G' |; f
  8.       BSP_LED_On(LED2);
    3 g5 Z% ]8 ]! ~8 P' r% [1 Q
  9.   }
      v) O( d4 d) {# l! m) Y
复制代码
     还有两个通道输入捕获中断的使能
; p* T1 D! b. X9 c1 R0 x
  1.   if (HAL_TIM_IC_Start_IT(&htim15, TIM_CHANNEL_2) != HAL_OK)
    - n* w" _# Z- B* K, T; w: @& M. o
  2.   {; r+ X& A6 N9 m7 Z) J. a, O! _
  3.       BSP_LED_On(LED2);
    2 F7 ]2 Z3 a4 A; S! Q6 P
  4.       Error_Handler();) l7 c  _) V( M; x; s% ~4 a  d5 z
  5.   }( |% v9 u: b9 N/ M8 i
  6. 4 b5 r; u( p$ j
  7.   if (HAL_TIM_IC_Start_IT(&htim15, TIM_CHANNEL_1) != HAL_OK)
    ! c( x6 w% A/ x2 \% R* A
  8.   {: X! q: D' A" H% T
  9.       BSP_LED_On(LED2);" u7 P1 q% t7 c: u: g2 L, a5 m( Q
  10.       Error_Handler();
    % u% s0 q. ]" c0 I
  11.   }
    + F7 ~. @/ l0 [; Q6 n
复制代码
     我们在按顺序看中断部分,首先是中断向量的使能。这里需要注意的是TIM15的中断和TIM1 BREAK中断是用的同一个中断向量。. a7 @' C* l5 ~! y% V+ K, {
  1. #define TIM15_IRQn       TIM1_BRK_TIM15_IRQn
    8 G7 S  Q" g3 v
复制代码
     所以最终我们还是得对原有工程进行修改,还是按顺序先来看中断服务函数* ?0 l7 T2 g: R" J& s5 P, o
  1. void TIM1_BRK_TIM15_IRQHandler(void)
    $ Z; p0 n# G$ p8 k7 @6 d
  2. {
    ) c% n3 o- @  w' }' h& |5 e

  3. 7 C& {) m" S, k  F2 R2 t
  4.       if(__HAL_TIM_GET_FLAG(&htim1, TIM_FLAG_BREAK) != RESET)
    ) l) z) ]! _9 o! T0 b* i7 r
  5.       {
    - N$ p: N' |# u7 l  H2 t/ w
  6.             MC_StopMotor(); 3 o. m- V, [4 m+ C
  7.             SIXSTEP_parameters.STATUS = OVERCURRENT;        
    & B3 h% f/ H! |* v
  8.       }6 H- t/ x$ w  v( [& o0 \( n
  9. : b% g! ~' O; Q* Q$ Q
  10.       HAL_TIM_IRQHandler(&htim1);8 A6 v% H8 ?. f9 B0 y3 \, _) q
  11.       HAL_TIM_IRQHandler(&htim15);
    6 ?. w9 q: Q0 B, C3 f* _2 x
  12. }
    & s+ J$ t3 o% G- g' r0 c  A% {
复制代码
     最后一行就是添加的TIM15中断服务函数入口。( H4 U9 `% ^5 g2 x" _8 P
      接下来继续刚才提到需要修改的两个地方,由于HAL库中将中断分类处理进行了封装,这里就不贴这个部分,直接来看需要修改的部分。8 u' \0 w6 u2 K
      首先是TIM6的计数器溢出中断,这里改好的,对入口参数进行检查,确认是TIM6的溢出中断,才执行原来的函数。同时为TIM15添加溢出中断的回调函数。% f2 P7 M. w9 [4 Z
  1.   void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)7 ~' O' A8 d1 F2 ~, S; ]) |" n: r
  2.   {4 _; z, i/ k. {  E$ g/ @
  3.     if(htim->Instance == TIM6)
    2 q3 K! F+ R" U( w/ f' B" ?& v+ N- U4 m
  4.     {. v& u; @: u) y9 g) U' q
  5.         MC_TIMx_SixStep_timebase();# _' I+ L/ T- H7 y+ q( z' V" T% n
  6.     }
    ' R* F! a, D& X- ~" C/ P; X
  7.     else if(htim->Instance == TIM15)3 h  Y5 [* {, z- M4 s. U9 W
  8.     {/ H* a$ z0 o5 X  h
  9.         TIM15_PeriodElapsedCallback();
    - l1 J5 _. E" n
  10.     }
    4 d9 a  P9 x4 i7 X+ ^7 S; B6 U" n
  11.                 6 o) E% l& }  K" G: b) W. a, @
  12.   }
复制代码
     话说写到这我突然忘了还有哪个地方的中断服务函数要改,敢信?唉,像我这样思路不清晰的,写代码真是个定时炸弹呀,指不定哪里留了个BUG还记不起来了。 大家待会儿直接对照看工程代码吧。
: M& o% f, U/ p* ?$ x# \, [      TIM15用到了两个中断,一个是溢出中断,记录溢出次数,另一个是读取捕获到的高电平脉宽值和PWM周期值。前面将定时器时钟设置为1/72主频,这样捕获到的值的单位刚好就是us
! f  H1 }5 f6 K
  1. void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)% y  Z' l% W% l  W
  2. {               
      K+ j3 B; |' p* f5 X! t
  3.     if (htim->Instance == TIM15)
    * a+ z3 {& V& w
  4.     {5 m4 t8 u1 K0 @0 H- y' B: \" K
  5.         if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2)
    1 J3 _( D1 ^: S) s; l
  6.         {  z* c  {' k3 O/ W) W" w
  7.             capCnt++;
    6 `! o4 |5 c6 ~! `+ ~: I8 @
  8. 5 y+ ~1 C# d8 w% f% z4 `
  9.             pulsePeriod = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2) + periodCnt * 0xFFFF;3 \7 s6 A9 p' M0 G* F
  10.             pulsePeriod        += 1;8 T/ Z5 Y: r& T
  11.             periodCnt = 0;: X$ J' H/ Y5 }  [' w
  12.             pulseWidth = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);1 y9 i) V) W, B
  13.             pulseWidth += 1;
    $ {* p' c  ]( O6 R8 h% v7 |. c! F
  14. 5 z/ D9 D6 C8 O3 k! v% L, v
  15.             if (pulsePeriod != 0)( L# B* [, U" {" r. c" I
  16.             {
    : ~, v) E  z, N7 E% v% t) j! O
  17.                 uwDutyCycle = (pulseWidth * 100) / pulsePeriod;" N/ ~# C" x8 T$ c
  18.                 uwFrequency = ulTmrClk  / pulsePeriod;3 q% i; S$ {  Q- k& }) g& K+ j
  19.             }
    ; i" g$ C) P8 e) F, r
  20.             else* ?& k: }8 `' d$ T: r
  21.             {
    1 ^* m* i0 \! [' W) q- L, [; M# C
  22.                 uwDutyCycle = 0;
    / O2 C8 d) t' N  r+ A
  23.                 uwFrequency = 0;, X; M6 u0 q6 K$ f
  24.                 pulsePeriod = 0;
    ! @; I* G' n. E! ^1 I8 l: A: d( Y
  25.                 pulseWidth = 0;1 s" }3 U$ D0 Z: i& t: R
  26.             }
    3 B. P5 ~. j+ [, `
  27.         }. |: M/ L1 ~- q- G( M' e: K$ E
  28.     }
    ; o5 o: v4 n# J. l5 F
  29. }        
    - ^$ j3 G' I, e4 k4 O- @" |% j
复制代码
     好了,主要的两个部分就这些,剩下的就是启动停止电机和设置速度。这部分就不贴吧,直接上传功臣压缩包。
6 a$ M9 I' s9 Z) m
9 ^) z# X7 R& _9 G. K      话说我还去移植6步换相的库,浪费的时间都可以熟悉HAL库,然后开始学习FOC库了  g/ v) x% z  i! }: Y7 _
7 J: I/ b& m) N$ q; k3 J
      今天先上传,改天有时间再来完善,大家看了一起讨论讨论。" e5 ?. ^* P; V; Y: v9 N: ~* p
/-------------------------------------------------------------------------------------------------------------------/( {; z5 K; [2 P6 m3 D4 c
      顺便把测试图片和视频上传了
QQ截图20170830210638.png
) V: Y: ^8 Q/ X: Z

1 A% a1 I- P1 K4 w  V8 U" |      测试视频,使用函数发生器给电调信号,周期20ms,油门对应的脉冲宽度1-2ms。
9 a5 v; T6 h% V
$ }6 F. Z% Z2 c/ C0 b6 }' v: N

& \: z! ?$ ?* _% n. t1 M

6 a9 K) ]; b( E& j1 ?

Rui_STM32CubeExpansion_SPN7_V1.1.0.part01.rar

下载

9.5 MB, 下载次数: 82

原来工程上改的,只能打包上传了

Rui_STM32CubeExpansion_SPN7_V1.1.0.part02.rar

下载

9.24 MB, 下载次数: 74

有点大,分个卷

收藏 2 评论5 发布时间:2017-8-30 20:56

举报

5个回答
Grant 回答时间:2017-9-2 19:13:21
出了很久了,一直没发布,最近才公开。
, f$ N- U: s" H& x$ jhttp://www.st.com/content/st_com ... t5571_gl_bn_aug2017, v* c8 `0 q  u
$ A* w, m# Q# U6 Z" Z* w
en.steval-esc001v1_image.jpg
, l- @% ^  X' F0 ]1 Y, Vworkbench界面有改动,电机硬件参数增加了诸如摩擦系数等,看起来速度环下以后PID不用用户改了。# b. I3 R5 F/ k/ ], c; N
, n; M" g) J% R. C$ {
ST其实是有几个版本的ESC的,还有一个是深圳ST做的基于STSPIN32F0的版本,另外说还有一个完整的无人机方案,包括姿态控制和ESC,说是开源的,可能还需要一些时间才能公开。
RuiJey 回答时间:2017-8-30 21:01:37
TIM15 CH2对应的PA3这个引脚,刚好是串口2的接收引脚,所以你会发现这个引脚连接在板载ST-LINK的串口TX引脚上,所以这里还有个方便的调试方法,直接用ST-LINK的串口向板子发送数据,任意数据,这样在这个引脚上就会有方波产生,嘿,还不用接信号源,也不会用手给输出脉冲信号了,直接用串口发送任意数据。简单粗暴还很方便。
zero99 回答时间:2017-8-31 09:06:46
不错,支持一下
五哥 回答时间:2017-8-31 09:28:15
ST新出了电调板,用的是STM32F303做的,比较高端。性能还没有测试。
RuiJey 回答时间:2017-8-31 11:37:53
五哥 发表于 2017-8-31 09:28! H6 Z5 c( i& p7 T% d9 D
ST新出了电调板,用的是STM32F303做的,比较高端。性能还没有测试。

  ^; p0 z8 ~- F' d0 [7 V分享个链接学习下?6 u+ c9 U7 v5 g( x
PCB工程应该是开源的吧

所属标签

相似分享

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版