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

No.5 电机套件实验任务3&旋钮控制转速  

[复制链接]
子曰好人 发布时间:2018-9-2 19:17
本帖最后由 子曰好人 于 2018-9-5 08:55 编辑
$ l- G8 @2 r0 R5 K6 r- v8 }- g+ T  ^; {+ ?5 C
继续做实验,任务3和旋钮控制转速。
首先来看看任务3的要求:
任务3要求.png
这个可通过代码实现也可以通过上位机实现,已经有坛友做过这样的事情了。通过上位机做就是快速拨弄圆盘,这样系统不能在短时间内反转,造成观测器不能收敛,触发速度反馈错误报警,其实我个人觉得这里也是有过流报警存在的,这就看系统优先响应哪一个报警了。
我这里通过代码来实现task3。
任务3代码:
  1. void task_3(void)# y7 J. F' T1 r$ {
  2. {
    ! T0 P+ g/ L" e! s
  3.     MC_ProgramSpeedRampMotor1(-3000/6,1000); //设置-3000rpm的转速,在一秒之内达到
    - k, H7 x9 g# ]
  4.     MC_StartMotor1();       //启动电机) r" R  L3 F! z5 c& K$ F/ t
  5.     HAL_Delay(500);         //运行500ms; Y7 O0 J9 G: a$ S
  6.     while(RUN != MC_GetSTMStateMotor1()); //等待电机处于运行状态,可有可无
    3 y. x( W- i. a1 X! h/ G
  7.     MC_ProgramSpeedRampMotor1(3000/6,1000); //切换到3000rpm转速
    2 |8 n! a1 V0 \! v$ L; l
  8.     MC_StartMotor1();       //启动电机
    # e# ^$ t! B* n# P  u. {: \' D8 K8 z
  9.     while(MC_SPEED_FDBK != STM_GetFaultState(&STM[M1])); //等待错误触发
    . m' y3 q5 I4 u; L9 c" g  `  e, Y
  10.     HAL_Delay(1000);    //延时一秒,方便可以在上位机上看见错误是否发生
    % R* j. Z5 }! w; T0 @- |+ n! i
  11.     MC_AcknowledgeFaultMotor1();    //清除错误
    - K/ D: j* q. h  o' \1 n0 J
  12.     HAL_Delay(100);     //延时0.1秒+ L1 A' e0 F- i2 T
  13.     MC_ProgramSpeedRampMotor1(MC_GetLastRampFinalSpeedMotor1(),1000);   //重新设置上一次速度值
    9 v8 N+ g# c+ K3 u1 I3 {/ Z
  14.     MC_StartMotor1();   //启动电机
    + X& h9 Y3 {2 d) d& }/ B
  15.     HAL_Delay(5000);    //运行5秒5 k: ^* t9 i( C7 y  z* ?! u
  16.     MC_StopMotor1();    //停机
    # F4 k2 R+ l- w+ t) f$ F( }2 l( F
  17.     HAL_GPIO_WritePin(LED11_GPIO_Port,LED11_Pin,GPIO_PIN_RESET); //拉低LED引脚,表示任务结束
    # Y/ D5 }- r* ^* C6 j: _. Q
  18. }8 W" v& X1 G6 E! E6 U, o( e, R
复制代码
主函数代码:
  1. /* Infinite loop */
    $ `, k6 O8 u: w3 l; {
  2.   /* USER CODE BEGIN WHILE */9 J% n6 \' a* r# w. R; S5 r+ m
  3.   while (1)4 S; i& w" t8 k  P
  4.   {# Y/ g8 S) A% @3 K; i* W9 j4 g
  5.       8 C8 n6 u& q- ]. @# e
  6.       if(GPIO_PIN_SET == HAL_GPIO_ReadPin(LED11_GPIO_Port,LED11_Pin))1 U: b" l6 h- \( A- G* b1 i& a
  7.       {" j+ j' i/ A  S& ^! h, G' J: V
  8.           task_3();
    * T$ v+ ]* Z3 `6 L5 m: c. b7 ~
  9.       }
    6 A3 x7 U# d+ h2 @7 C8 q
  10.       else
      i# v% q: @  G6 |: C
  11.       {
    * d* `# Y7 G) z! G
  12.         MC_StopMotor1();
    8 y1 f0 l" U5 [. ^" r8 ~+ `% c
  13.       }      
    - q/ \4 R2 ]4 h/ N2 p9 I( l) f
  14.   /* USER CODE END WHILE */+ E! _4 L3 p. Q2 D  C, C
复制代码
实验现象:
任务三速度变化截图.png
8 g& @3 a1 S4 @7 ?! T$ O* q
通过速度变化趋势可以看到任务成功实现了,我对比了PPT的预期结果图,有一些差距。当速度设置为3000rpm时,speed reference并没有跟随代码变为3000。另外,我做了延迟清除错误信息,所以在图中可以看到一截零速状态。
/ q3 Q5 o3 O% ]

$ a& W( \, a' b* ~! `) G. I好了,任务3完成。
---------------------------------------------------------
现在分享一个开放性实验,旋钮控制转速,我把这个任务定为任务4吧,用旋钮来控制电机转速我觉得才是真正的一个电机控制系统。
由于SDK中并没有考虑旋钮ADC的初始化,所以如果要使用旋钮电位器首先要通过cubemx对ADC进行初始化,在我的第二篇帖子中已经讲过关于套件的硬件资源,也知道了旋钮电位器连接的是PB1引脚。
用户1.png
创建全局变量:
  1. int32_t Speed_Adc = 0;, ]' K. P1 _: P
  2. int32_t Speed_ref = 0;+ H) E1 }, q3 z, x) _+ {+ c
  3. PWMC_Handle_t * MC_SPEED_REF;$ C$ @* F5 Q/ Q+ ^( h% V* z, H; }
复制代码
任务4代码:
  1. void task_4(void)
    4 C) g5 j6 ^- f6 V, R3 N; t
  2. {
    ! Y$ ^( B( U1 f  F5 P' h
  3.     Speed_Adc = R3_1_F30X_ExecRegularConv(MC_SPEED_REF,ADC_CHANNEL_12);5 I1 A# f. v. t( H2 B, w" ?2 }
  4.     Speed_ref = (15500*Speed_Adc)>>16;9 K1 j, A/ ^2 j' y
  5.     if(Speed_ref > 0)
    , \" H: K; j4 j
  6.     {
    6 `& m/ a+ B7 q& f" |2 ^. e
  7.         MC_ProgramSpeedRampMotor1((Speed_ref+1500)/6,1000);
    8 p- y4 }6 t8 c+ J9 w
  8.         MC_StartMotor1();& w$ n% @2 N# |7 B
  9.     }
    9 e7 X- q! r# |0 S% J* b, r
  10.     else1 r- w' E0 m' \2 n) n# s( B
  11.     {. P$ I% f5 o  y# q1 c! l9 _" U
  12.         MC_StopMotor1();/ {" U/ _- J0 A% u% |' Q& J! S
  13.     }+ Q7 Q2 q& f: w& E6 A6 \0 }6 [% w
  14.     HAL_Delay(100);
    0 z' `0 U8 v  L7 z8 f& \5 g
  15. }
复制代码
主函数代码:
* v2 j5 |9 A5 B+ e- X) t; [6 }! b
  1. /* Initialize interrupts */
    ) `4 d9 K1 G2 v0 i2 B) u% d9 M/ y
  2.   MX_NVIC_Init();
    7 F. U5 n1 ^8 c  {  j
  3.   /* USER CODE BEGIN 2 */  b1 A6 S/ m5 h5 l0 V
  4.   MC_SPEED_REF = &PWM_Handle_M1._Super;
    # I/ d5 [6 A% m- l& i6 O  k; y' b
  5.   /* USER CODE END 2 */, g7 r( K, S0 i0 Y

  6. 5 g& v) m/ t# F: h3 X/ ?
  7.   /* Infinite loop */  P  o6 G3 ^6 G" s) j
  8.   /* USER CODE BEGIN WHILE */9 a9 I! M4 G2 A$ ~! |
  9.   while (1)
    1 q. R+ S7 i2 x* ^
  10.   {
    / M8 D5 N) M) ?4 e4 H

  11. # d! H1 V) ^4 v$ I" V* I- s
  12.       if(GPIO_PIN_SET == HAL_GPIO_ReadPin(LED11_GPIO_Port,LED11_Pin))' \4 d( B2 a+ ~+ G7 i
  13.       {
    * m, r! f0 w$ |& F1 A, ]3 f7 q6 R
  14.           task_4();' }! ]- Y. W' d; W6 Z
  15.       }
    6 F" j+ x1 M* h8 S4 D# L( `0 `( [, ~
  16.       else
    3 P5 s+ G+ g/ H6 `. M  h, @3 g
  17.       {
    . z+ l1 m0 N; A' @- P
  18.           MC_ProgramSpeedRampMotor1(0,0);8 C% `7 u' Z2 Q, A
  19.           MC_StopMotor1();
    % x7 N2 h1 U% U9 i: D9 y: g
  20.       }
    9 y5 X$ n7 u# d& c
  21.   /* USER CODE END WHILE */' o' Y) v% p; f* f3 ~

  22. ) T) ~: x! r; n5 x1 ~4 n
  23.   /* USER CODE BEGIN 3 */
    ( w& K( a0 d$ L

  24. 1 r9 z' i2 g9 }
  25.   }
    7 _  S" ~, |  _8 Q' T" |
  26.   /* USER CODE END 3 */3 X! X9 S6 `/ N/ Z
复制代码
在这里稍微解释一下代码:
Speed_Adc是存储ADC采样值的变量,Speed_ref变量通过ADC采样值转化为速度设定值,MC_SPEED_REF是一个指针变量,用于获取ADC初始化设置,R3_1_F30X_ExecRegularConv这个函数在r3_1_f30x_pwm_curr_fdbk,c这个文件中,用于处理规则ADC采样。速度换算这里可以没什么说的。速度设定的时候加1500偏移是有原因的,当设定速度过低的时候电机系统根本不能正常启动,这是我尝试设置的时候所能达到的最低启动速度。
5 v1 A. A, Q( q; m
实验现象:
旋钮调速转速跟踪波形.png
从实验结果看来,这份代码默认速度PID能很好的跟踪给定转速。
我发现一个问题,代码里面在电机运行结束之后有些变量好像没有清零,这个问题留到后面在研究吧。

4 f# k3 Z+ G; `9 q; T7 z$ F6 c
本帖两个任务分享就到这里,欢迎大家留言讨论。
& `) W. q; Y. p  Y6 O

- `% k& s+ c* s* A
, R' A# ?$ Z7 ]( r
4 W& j% }& H# Z- {
9 r2 N9 d' n  \$ K. \
1 收藏 2 评论118 发布时间:2018-9-2 19:17

举报

118个回答
子曰好人 回答时间:2020-4-15 09:28:07
ysx584085668 发表于 2020-4-14 23:23
3 B% I) P! F- i' {0 u太感谢了,我发邮件给你看吧
* w+ r8 `0 H0 T: P( o: \4 r( O
看了你发的邮件,新版本的MCSDK生成的代码没有留ADC规则转换的函数接口,可能需要你自己去写了,我把我这边生成的文件发你一份参考吧
( {& l6 [" z! z7 V: M1 Y r3_1_f30x_pwm_curr_fdbk.zip (16.66 KB, 下载次数: 10)
passby328 回答时间:2018-11-6 11:04:29
子曰好人 发表于 2018-11-6 09:35
, D3 P$ t1 n2 K+ m+ P) F3 D( eSDK5.1.3生成的代码里面没有regular_conversion_manager.c这个文件,5.2.0新增了。获取ADC值的代码是几乎 ...

6 M6 |2 h" U- p9 y, e0 b. C1.我之前参考您的函数,如果一直不断在执行转换,会影响电机库的控制时序导致无法开机,后来改为500ms一次,就没有问题。后来检查regular_conversion_manager.c中的内容,发现用户ADC的转换应该是电机库的状态机在调度的,如果连续不断转换或者没有走相应的接口估计会有问题。
2 Y- K( Z7 b( c$ h- J( ^- g2.电机Workbench里面有设置OCP参数,看了原理图应该是通过体验板上面的L6230的内置比较器以及SMT32片内的ADC实现的,但是实际中的程序并没有提供类似的功能。后来查看了代码,OCP保护是通过L6230产生的FO信号进行处理的,不知道我说的是否有偏差,还请指教。
zhdzhd 回答时间:2018-9-2 22:27:32
代码规整,有功底,佩服!
; H/ f" g: F: m大佬也会有纰漏啊5 T- ]' ^8 b) P3 Q1 F+ [
; w) l3 y' ]; M- J4 M2 f
/* Infinite loop */
. t* _4 h) B/ L; n9 ^  /* USER CODE BEGIN WHILE */$ \1 K4 @8 {: v/ G, v
  while (1)4 [6 r, V2 \' K3 H$ \& i
  {
; C, J7 l; z. @' }4 c, u" U5 R2 |      
: Z0 ~8 s2 f3 d/ O      if(GPIO_PIN_SET == HAL_GPIO_ReadPin(LED11_GPIO_Port,LED11_Pin))% M* K5 G8 @& m$ K* o; u4 u$ R
      {
0 _- t0 z# p1 @: ?: v7 ~0 c. \* A          task_5(); ------>task_3();
& H/ I! E: [3 H      }
" }- ?4 I; w1 m) b+ `      else# S9 Y& }" h7 \1 K
      {: m* z( m7 s; s% L7 j* |
        MC_StopMotor1();* I) l) C- Z. Q# [
      }      * y1 q% h) @) ~6 A; g
  /* USER CODE END WHILE */
子曰好人 回答时间:2018-9-2 22:36:27
zhdzhd-174422 发表于 2018-9-2 22:27. }0 ?1 t- O) Y
代码规整,有功底,佩服!
$ r3 h9 a1 d% E, r4 X, L大佬也会有纰漏啊
) p' L, ^* n/ P' t# k. y
不好意思,感谢指正
STM1024 回答时间:2018-9-3 10:24:43
哈哈,和你观点一样,很多故障报警,都是报的speed feedback,我在测试的时候,连堵转都试过,原本以为是电流过大报警,但没想到居然还是speed feedback故障
子曰好人 回答时间:2018-9-3 10:45:56
stm1024 发表于 2018-9-3 10:24- ], o9 H* N. |+ b7 I" ]/ i
哈哈,和你观点一样,很多故障报警,都是报的speed feedback,我在测试的时候,连堵转都试过,原本以为是电 ...

1 r, q* {* \7 e$ M0 K去研究一下电机库生成的故障触发机制代码,也许就能明白了,搞清楚是怎么回事之后就能自定义故障报警了
LT-386596 回答时间:2018-9-4 18:38:17
Speed_Adc = R3_1_F30X_ExecRegularConv(MC_SPEED_REF,ADC_CHANNEL_12); 5.2.0 找不到  R3_1_F30X_ExecRegularConv()?
  J+ y1 d8 h1 W6 ?6 }) T
子曰好人 回答时间:2018-9-4 22:54:20
LT-386596 发表于 2018-9-4 18:38
+ `& g, y: A- z" ^5 h/ F2 Y: ISpeed_Adc = R3_1_F30X_ExecRegularConv(MC_SPEED_REF,ADC_CHANNEL_12); 5.2.0 找不到  R3_1_F30X_ExecRegu ...

' \" ]9 D1 u, H在r3_1_f30x_pwm_curr_fdbk.c这个文件里面,要调用这个函数需要包含头文件r3_1_f30x_pwm_curr_fdbk.h
zhdzhd 回答时间:2018-9-4 23:27:57
VR连接的脚感觉像是PB1,从电路图上来看.
子曰好人 回答时间:2018-9-5 08:56:32
zhdzhd-174422 发表于 2018-9-4 23:279 D- B* Z1 C4 N1 z
VR连接的脚感觉像是PB1,从电路图上来看.
0 j! M3 A9 e: }7 e
手误写错了,已更正
花落莫相离 回答时间:2018-10-25 19:58:06
楼主,我不太懂Speed_ref = (15500*Speed_Adc)>>16;这段程序中15500的作用时什么?
花落莫相离 回答时间:2018-10-25 20:59:33
大神,不知道你有没有注意到有一个小细节,这个USB必须要插在主控板上整个程序好像才能运行,然后不插USB的时候只按开关启动电机,电机启动不起来,不知道大神出现过这情况吗?
子曰好人 回答时间:2018-10-26 09:16:20
花落莫相离 发表于 2018-10-25 19:58
- D: r2 A2 `$ E; N/ [+ \楼主,我不太懂Speed_ref = (15500*Speed_Adc)>>16;这段程序中15500的作用时什么?
% O& _9 H( q  p- o3 J
15500是电机能达到的最大转速,Speed_Adc的最大值是4096,ADC采样值和速度参考值的换算方式为:(Spped_ref-0)/(Speed_Adc-0)=15500/4096=15500>>16;
子曰好人 回答时间:2018-10-26 20:20:40
花落莫相离 发表于 2018-10-25 20:59
% o$ d( q/ n. q大神,不知道你有没有注意到有一个小细节,这个USB必须要插在主控板上整个程序好像才能运行,然后不插USB的 ...

2 c6 g% t0 q; _没遇到过,我的一直是正常的呀,没有USB连接也能正常运行
晴空 回答时间:2018-10-29 15:53:32
学习了  哈哈
花落莫相离 回答时间:2018-10-31 13:51:43
子曰好人 发表于 2018-10-26 09:169 f( S( h1 g( ?% _1 V
15500是电机能达到的最大转速,Speed_Adc的最大值是4096,ADC采样值和速度参考值的换算方式为:(Spped_re ...
# L6 \" Q0 O2 k: v$ ~
多谢楼主解释了。

所属标签

相似分享

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