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

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

[复制链接]
RuiJey 发布时间:2017-8-30 20:56
本帖最后由 RuiJack 于 2017-8-30 21:22 编辑
/ q2 r5 F9 t0 \% ~
, }4 {5 f2 @* {$ P+ u2 e( i      此次培训的视频和工具大家都差不多能介绍的都介绍了诶,我们还可以怎么玩玩?
1 E' y; E, {  e3 r      好像之前一直想把四轴用的电调也做来玩玩,但又不会电机控制咧。这次好像可以捡个便宜,用ST的库来仿照做一个?7 {, J% v8 ~( R5 R, c
: b1 T* I; W, n1 O
      那么,初步想法是这样的 -> 原来的工程 + PWM捕获 = 简易电调。$ J  |! ^8 H: W6 _0 I
      连工程都用原来的,可是懒到家了。1 d7 L& k( `& T; _" H
      好了,首先来看看可用的资源。nucleo-F302的板子,电机驱动库SPN7的示例功工程中已经使用了TIM1,TIM2,TIM6,TIM16,额。为了保证尽可能少的改动,来看看还有哪个定时器可以用吧。
) h, j6 j/ _1 J* @: z
QQ截图20170830194600.png
8 z7 L" l; c9 L+ Y2 w, j+ d
      好吧,至少还有两个定时器可供选择,TIM15,TIM17,但是板子上已经有很多已经都有用了,有些也被电机驱动库作为其他功能用了,对照数据手册和nucleo-F302板子的AD PCB功能,来寻找可用的GPIO,这里就省略耗时的过程。来看下其中一个可用的IO3 I( j9 D' w5 N- @: {
QQ截图20170830195025.png

) o( |' F8 w( F1 C      是的,你没有看错,这还是UART2的RX引脚,已经被用了,好在可以暂时不用串口2来接收上位机数据,只用于向电脑发送调试数据。对应板子上的插针是# C1 `( q. T4 }
QQ截图20170830195414.png
$ }' J3 y, v; ^( A
      刚好还有个插针,后面再介绍下这还有个方便测试的好处。# O/ Z: A; j9 d2 f' U5 d* b

( c: A% I4 H4 M4 x      好了,继续正题。接下来开始初始化TIM15 CH2.之前还没有接触过HAL库,很多地方就参考库中的例程来了。
1 O7 t2 K2 [1 \3 Y      首先是GPIO初始化。之所以连这个也提出来,是因为一直在纳闷儿引脚要配置为复用上下拉模式,可能有段时间没用32的定时器捕获模式了,有点忘了。
; r) Q; W6 ]4 ?9 U2 ]4 F$ v# K8 C" O
  1.   GPIO_InitStruct.Pin = GPIO_PIN_3;  u8 e* {) U: L  Q$ T
  2.   GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;: K' o' L  c2 H% Q% W8 e
  3.   GPIO_InitStruct.Pull = GPIO_PULLDOWN;
    , ^0 W0 y1 B8 e
  4.   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;. W0 S- l( M) E2 e8 U
  5.   GPIO_InitStruct.Alternate = GPIO_AF9_TIM15;; d4 x$ {- n& o9 b5 q1 }! f
  6.   HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    4 o# k9 i% a, t# G; Y
复制代码
     然后是定时器基本参数的初始化。
  1.   htim15.Instance = TIM15;' \* U1 q  }4 J9 u8 i3 ~' A6 O
  2.   htim15.Init.Prescaler = 72 - 1;% f+ _" n9 _% d8 c; |( o
  3.   htim15.Init.CounterMode = TIM_COUNTERMODE_UP;
    , b$ X0 \; ]) `) I. D* P; |, k* F' K
  4.   htim15.Init.Period = 0xFFFF;
      q8 E0 k, s, V
  5.   htim15.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
    5 M5 }4 ^! \! M2 e4 l; @: y
  6.   htim15.Init.RepetitionCounter = 0;
      M: C; X& u4 {( e
  7.   htim15.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
    ; q. o! j$ U* H% o4 f
  8.   if(HAL_TIM_IC_Init(&htim15) != HAL_OK)1 \& S/ b, z, U
  9.   {
    3 S( F% Z' Z4 M
  10.         BSP_LED_On(LED2);        5 O( }' D& y/ K: P. A6 T
  11.   }
    * R8 P) E8 W; J
复制代码
     接着是两个定时器通道的配置。这里直接使用了32定时器的PWM输入模式,以前在F1上就用得方便,这里也将两个内部输入通道连接到同一个输入引脚,CH2,通道1用作高电平脉宽采集,通道2用作PWM周期采集。两个通道的配置差异主要是采样边沿,和通道映射。
2 T+ M0 C( u7 |/ v! R7 T3 d' I! Q
  1.   sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
    , W4 _+ N" O% D$ J# i
  2.   sConfigIC.ICFilter = 0;
    2 L% n  z8 V9 Z9 ?/ L6 v
  3. % B; C; Z& z, e1 X5 f
  4.   sConfigIC.ICPolarity = TIM_ICPOLARITY_FALLING;
    $ s0 Z$ v0 Z" S: n/ y# `
  5.   sConfigIC.ICSelection = TIM_ICSELECTION_INDIRECTTI;
    5 s. Z' r+ n6 @; ]
  6.   if(HAL_TIM_IC_ConfigChannel(&htim15, &sConfigIC, TIM_CHANNEL_1) != HAL_OK)% x& d6 W) Q0 Q
  7.   {               
    / Z! i4 r$ `& A( S
  8.         BSP_LED_On(LED2);' {" Z2 M( K7 J7 Y! ~
  9.   }4 A" v2 a% S* }* H, P- D
  10. 1 p: J: ]4 l- @, M( d2 u
  11.   sConfigIC.ICPolarity = TIM_ICPOLARITY_RISING;7 P" h. {' T5 f( ~
  12.   sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
    $ @+ p0 _  M2 r, A+ q
  13.   if(HAL_TIM_IC_ConfigChannel(&htim15, &sConfigIC, TIM_CHANNEL_2) != HAL_OK)
    4 C8 y# Y3 Q9 k, m; K# ^
  14.   {
    & B% z8 t5 K1 ], I. g" ^( E, |3 V
  15.         BSP_LED_On(LED2);* W, n+ B$ B, F
  16.   }" X5 n' X) z0 y* Z' A
复制代码
    这里有一段是输入捕获的配置,跟以前STD库有些区别,还没细看,直接从HAL库例程中拿过来先用着" G7 q4 B7 t# u5 g1 M+ v* y
  1.   sSlaveConfig.SlaveMode        = TIM_SLAVEMODE_RESET;
    ' q; ~. a( R, v+ W1 D1 H3 `
  2.   sSlaveConfig.InputTrigger     = TIM_TS_TI2FP2;. z' {6 \7 p: t7 r
  3.   sSlaveConfig.TriggerPolarity  = TIM_TRIGGERPOLARITY_NONINVERTED;
    . g' B" f" u0 `4 x7 ]
  4.   sSlaveConfig.TriggerPrescaler = TIM_TRIGGERPRESCALER_DIV1;
    , X4 B# _+ A: _3 m; o- g
  5.   sSlaveConfig.TriggerFilter    = 0;
    * p/ {1 J: s% M' H& R
  6.   if(HAL_TIM_SlaveConfigSynchronization(&htim15, &sSlaveConfig) != HAL_OK)
      X" S' w7 m' S5 H- D' a
  7.   {
    7 N, M! x# e/ C' h6 K' o
  8.       BSP_LED_On(LED2);0 ]; N. a, Q# l! n0 M5 k
  9.   }( ]% r0 q6 f; S; z9 e7 F
复制代码
     还有两个通道输入捕获中断的使能
8 A; d: R" G4 G+ E. {6 f
  1.   if (HAL_TIM_IC_Start_IT(&htim15, TIM_CHANNEL_2) != HAL_OK)
    & y- r3 M* g( M
  2.   {
    - O) ^0 U) X5 v) X! B
  3.       BSP_LED_On(LED2);
    " N/ q2 Z6 B8 K) e5 x( \
  4.       Error_Handler();
    ( C2 B2 a4 M+ E, s% ^
  5.   }
    ; q  T8 W" ?4 T' T1 E1 v

  6. : J( X9 D! x9 `5 ]5 @
  7.   if (HAL_TIM_IC_Start_IT(&htim15, TIM_CHANNEL_1) != HAL_OK)
    . I4 Q% E' q$ I: [4 d: i
  8.   {) W/ t4 F0 {& U( V$ n; w
  9.       BSP_LED_On(LED2);. |( N7 L- g5 {, m
  10.       Error_Handler();
    , Y3 F, \; q) g* T9 |9 ^7 d
  11.   }
    ! {3 V6 O" x; B- N0 Y* m2 G3 j
复制代码
     我们在按顺序看中断部分,首先是中断向量的使能。这里需要注意的是TIM15的中断和TIM1 BREAK中断是用的同一个中断向量。" \7 I& t. e+ ?9 `+ y) X
  1. #define TIM15_IRQn       TIM1_BRK_TIM15_IRQn9 L. `1 y- S/ ~, \, l) n% h
复制代码
     所以最终我们还是得对原有工程进行修改,还是按顺序先来看中断服务函数
( V3 R% E) r* r, a
  1. void TIM1_BRK_TIM15_IRQHandler(void)
    ( _6 a6 |; U9 ^% _
  2. {
    ! l* r! i: k9 @" \/ G9 g, G
  3. / k% P5 S0 {; Z: H1 O. g$ P
  4.       if(__HAL_TIM_GET_FLAG(&htim1, TIM_FLAG_BREAK) != RESET)
    2 T4 t* x2 V. c& H* m
  5.       {
    $ t  i, s/ o6 `( ~
  6.             MC_StopMotor(); # F+ b( g/ f' j$ x" l) c
  7.             SIXSTEP_parameters.STATUS = OVERCURRENT;        
    3 w# u/ ]6 q! r3 z  \: Z& ~& H
  8.       }
    . W# E- R8 _5 k( ]- {( {
  9. 7 P; g$ [# H7 S; \
  10.       HAL_TIM_IRQHandler(&htim1);! z1 C- \5 F6 e  [3 w5 w
  11.       HAL_TIM_IRQHandler(&htim15);
    1 \9 k% C( e4 n, E4 N
  12. }0 V+ Z4 ^# m- q3 Q3 F
复制代码
     最后一行就是添加的TIM15中断服务函数入口。3 i: t/ ]- l6 @1 m4 _# w
      接下来继续刚才提到需要修改的两个地方,由于HAL库中将中断分类处理进行了封装,这里就不贴这个部分,直接来看需要修改的部分。
* y; }8 r1 l8 n# @/ u4 E      首先是TIM6的计数器溢出中断,这里改好的,对入口参数进行检查,确认是TIM6的溢出中断,才执行原来的函数。同时为TIM15添加溢出中断的回调函数。9 `* I% u  t8 W, h& h: Y& N$ y* Q4 J
  1.   void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
    * q. M! c+ W# p+ ?6 @. T
  2.   {
    2 ~; z& K4 ]7 d7 X# s8 q
  3.     if(htim->Instance == TIM6). w- O5 i" W+ l" ?8 m
  4.     {
    1 R, P0 u/ l' \* X! c8 n% o% y
  5.         MC_TIMx_SixStep_timebase();
    4 x" G: d, x! h  H" l
  6.     }
    ' B: k" {5 l$ E/ k" k
  7.     else if(htim->Instance == TIM15)5 e# @' _9 o/ w0 E3 i% H  g; p
  8.     {& P3 V* Z9 `9 x3 {! D: b- x* S% o
  9.         TIM15_PeriodElapsedCallback();
    5 A) o8 X% W) l) J
  10.     }& h! x3 Y/ u/ L
  11.                 7 i2 ?2 S6 F" c0 J( U$ e5 _
  12.   }
复制代码
     话说写到这我突然忘了还有哪个地方的中断服务函数要改,敢信?唉,像我这样思路不清晰的,写代码真是个定时炸弹呀,指不定哪里留了个BUG还记不起来了。 大家待会儿直接对照看工程代码吧。, \* }7 |& @% e
      TIM15用到了两个中断,一个是溢出中断,记录溢出次数,另一个是读取捕获到的高电平脉宽值和PWM周期值。前面将定时器时钟设置为1/72主频,这样捕获到的值的单位刚好就是us
$ _: p0 |! m$ G. F% s, o1 e% K
  1. void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)5 O' m( x0 N% a# ~" K- c& |
  2. {                0 \% o: C0 K7 o0 f- e& Y6 R
  3.     if (htim->Instance == TIM15)9 j/ s) v1 Q3 z: f
  4.     {
    7 O4 L2 U+ R* K, e, o
  5.         if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2)
    . S! ]3 O  g  U% {" ~1 I: p
  6.         {1 q3 ]: ^6 F5 M8 a1 j! h
  7.             capCnt++;" J1 r/ p3 X9 q5 P$ h# O
  8. % ^4 p! x* v; o
  9.             pulsePeriod = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2) + periodCnt * 0xFFFF;' m) u- l0 \* f- H8 Q" X
  10.             pulsePeriod        += 1;
    * k3 P- B' @8 }0 s* W
  11.             periodCnt = 0;
    + C" M. x7 x. c! L$ r. A$ Z- ~  F
  12.             pulseWidth = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);
    : A3 C3 b  d0 x. [; g- X
  13.             pulseWidth += 1;* u/ w* _% T2 P

  14. 0 s1 [! E. [- V  g8 I. j
  15.             if (pulsePeriod != 0)
    3 N7 ~4 ^# ~; g4 Y4 `/ O. |
  16.             {
    1 j2 Q1 o0 s. C. d  {, U* d
  17.                 uwDutyCycle = (pulseWidth * 100) / pulsePeriod;4 t5 s: ]* z: `) U4 Z
  18.                 uwFrequency = ulTmrClk  / pulsePeriod;6 p7 X' ]. ?# v7 {# n7 s7 c
  19.             }, H$ p# j% x& ]# L: r
  20.             else
    . Q$ n4 U% [2 c1 }' C
  21.             {$ Q% S$ v4 J' X3 D; B  q
  22.                 uwDutyCycle = 0;7 p5 V/ g3 e% N  @. q
  23.                 uwFrequency = 0;+ n3 h% T9 t7 Q# W* K+ [3 d
  24.                 pulsePeriod = 0;- v. F& R7 A" M% K
  25.                 pulseWidth = 0;
    ( k: S* g9 i6 @, y% a$ r' l, m' C
  26.             }
    ) ^# C) G5 t7 s6 J
  27.         }
    " @7 h# b/ V0 E5 N" z5 ^/ z
  28.     }: Q; R* |* D- ^$ z3 i- I. q
  29. }        
    0 N3 T% P2 g( f9 Q  X
复制代码
     好了,主要的两个部分就这些,剩下的就是启动停止电机和设置速度。这部分就不贴吧,直接上传功臣压缩包。
1 E) ~" S& W, J/ _* |" t
' a4 j! V& T( r5 \, O' F      话说我还去移植6步换相的库,浪费的时间都可以熟悉HAL库,然后开始学习FOC库了6 b0 {* N- ^* i% w1 J# ^' r, h

! p" `& M) C8 S# E      今天先上传,改天有时间再来完善,大家看了一起讨论讨论。
) @9 m; c2 n1 o+ m3 x3 [2 l/-------------------------------------------------------------------------------------------------------------------/
, t4 W0 f4 w0 w- F+ @2 c      顺便把测试图片和视频上传了
QQ截图20170830210638.png
8 V. i) t% z/ v
( Y9 H& n+ g; K# y' M* o
      测试视频,使用函数发生器给电调信号,周期20ms,油门对应的脉冲宽度1-2ms。% V, [6 e# `' M6 ^" g" \& o
0 U* ~* X  v# ]
) s. M  p: ^7 b! ~3 M
# I/ a1 `4 x8 `; w$ h9 L. i

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
出了很久了,一直没发布,最近才公开。
# D# ~* k# ?6 Z' ?http://www.st.com/content/st_com ... t5571_gl_bn_aug2017
0 p4 O8 k! F8 c& `) c9 U* q5 c; Z- K) i- O8 u
en.steval-esc001v1_image.jpg 3 K( l2 p# b( c" X: `. ?
workbench界面有改动,电机硬件参数增加了诸如摩擦系数等,看起来速度环下以后PID不用用户改了。
6 U4 q, x$ D; Q; R1 ]+ f  @2 `2 a0 `
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
; B0 G/ e0 n% i5 j. i: aST新出了电调板,用的是STM32F303做的,比较高端。性能还没有测试。

  Y# ?. \1 V( i: ]3 q. E! b2 K分享个链接学习下?
, e; W* F  y0 X2 |+ k% _PCB工程应该是开源的吧

所属标签

相似分享

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