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

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

[复制链接]
子曰好人 发布时间:2018-9-2 19:17
本帖最后由 子曰好人 于 2018-9-5 08:55 编辑
/ U* S! H- }4 z" |$ W7 d+ N- L
5 P+ K. d0 c5 K" j. P
继续做实验,任务3和旋钮控制转速。
首先来看看任务3的要求:
任务3要求.png
这个可通过代码实现也可以通过上位机实现,已经有坛友做过这样的事情了。通过上位机做就是快速拨弄圆盘,这样系统不能在短时间内反转,造成观测器不能收敛,触发速度反馈错误报警,其实我个人觉得这里也是有过流报警存在的,这就看系统优先响应哪一个报警了。
我这里通过代码来实现task3。
任务3代码:
  1. void task_3(void)
    9 b6 M  x& k) X% }% z) A7 k
  2. {
    0 W# _/ g; T6 m# O' v$ ]: }
  3.     MC_ProgramSpeedRampMotor1(-3000/6,1000); //设置-3000rpm的转速,在一秒之内达到
    & P7 ?2 I8 W" z' h6 s
  4.     MC_StartMotor1();       //启动电机
    3 F  T8 Y# x5 U6 {+ L" Y/ Y. R8 J
  5.     HAL_Delay(500);         //运行500ms
    2 D6 c0 ?0 n1 P! l( O7 Q
  6.     while(RUN != MC_GetSTMStateMotor1()); //等待电机处于运行状态,可有可无
    0 w8 w+ Q" z6 C  E' F
  7.     MC_ProgramSpeedRampMotor1(3000/6,1000); //切换到3000rpm转速0 v8 s- T1 j8 R4 x
  8.     MC_StartMotor1();       //启动电机# y' x8 L6 p$ Y1 b6 {: _
  9.     while(MC_SPEED_FDBK != STM_GetFaultState(&STM[M1])); //等待错误触发
    7 U+ W: p5 W2 V; W2 [- B
  10.     HAL_Delay(1000);    //延时一秒,方便可以在上位机上看见错误是否发生
    * @/ k& L4 n2 |  J, N
  11.     MC_AcknowledgeFaultMotor1();    //清除错误
    4 G! E! C: u6 r' n" [7 g3 v) D1 K) f* ~
  12.     HAL_Delay(100);     //延时0.1秒
    * S! ^6 \) {7 M" F1 u1 @/ I5 m" |0 F( S
  13.     MC_ProgramSpeedRampMotor1(MC_GetLastRampFinalSpeedMotor1(),1000);   //重新设置上一次速度值
    , j0 g# s. ?% R; r+ w' @
  14.     MC_StartMotor1();   //启动电机' c6 X9 L: R8 d8 r8 g, O/ |! G
  15.     HAL_Delay(5000);    //运行5秒
    ' D8 X2 w: y3 j7 _7 O8 ^, T, Q
  16.     MC_StopMotor1();    //停机0 H1 C& b- {+ \$ ~# }8 w, K
  17.     HAL_GPIO_WritePin(LED11_GPIO_Port,LED11_Pin,GPIO_PIN_RESET); //拉低LED引脚,表示任务结束
    ; G/ M; ?8 n  @' B% e8 d* O+ h2 o
  18. }' W# y# i; a0 A7 _# ~6 x& R8 R
复制代码
主函数代码:
  1. /* Infinite loop */
    ' E! E% S, a7 r2 u4 @
  2.   /* USER CODE BEGIN WHILE */' [- E6 L3 W  g% ~
  3.   while (1)
    4 c* J2 w/ R/ f& ?/ [3 Z( |
  4.   {
    ' u% n' |% p% p9 S0 z. A
  5.       
    3 A/ \( p2 W4 {/ w! ?. X
  6.       if(GPIO_PIN_SET == HAL_GPIO_ReadPin(LED11_GPIO_Port,LED11_Pin))
    2 x- R3 L8 U( I9 @# X9 i
  7.       {# O6 `$ u# u6 b8 r2 Z# q# P
  8.           task_3();
    : a% N& w* P* Q. X4 u. t
  9.       }8 B' |  L) w7 @0 w- S+ K7 J, C
  10.       else% Q  N- D) F& f* _' z
  11.       {: ?( d0 N5 A+ M0 o+ X7 Y" z
  12.         MC_StopMotor1();8 R# g, F& i' w3 l( u
  13.       }      / {: J- `% K0 E8 H5 Y0 u/ }1 L+ d# i
  14.   /* USER CODE END WHILE */2 F1 E5 z6 F8 U
复制代码
实验现象:
任务三速度变化截图.png ; E9 W7 b  Y8 F# F' \7 A" }/ \5 @
通过速度变化趋势可以看到任务成功实现了,我对比了PPT的预期结果图,有一些差距。当速度设置为3000rpm时,speed reference并没有跟随代码变为3000。另外,我做了延迟清除错误信息,所以在图中可以看到一截零速状态。

. _/ I6 A! Z& @' @
( P: B3 K) c% ^: C% f
好了,任务3完成。
---------------------------------------------------------
现在分享一个开放性实验,旋钮控制转速,我把这个任务定为任务4吧,用旋钮来控制电机转速我觉得才是真正的一个电机控制系统。
由于SDK中并没有考虑旋钮ADC的初始化,所以如果要使用旋钮电位器首先要通过cubemx对ADC进行初始化,在我的第二篇帖子中已经讲过关于套件的硬件资源,也知道了旋钮电位器连接的是PB1引脚。
用户1.png
创建全局变量:
  1. int32_t Speed_Adc = 0;
    % G* \& a1 x: u
  2. int32_t Speed_ref = 0;
    ' u2 z3 u: N4 ^0 v; t8 m/ V9 Z' w. @
  3. PWMC_Handle_t * MC_SPEED_REF;3 k1 e7 B' }" h) K2 c7 h
复制代码
任务4代码:
  1. void task_4(void)
      c5 V/ B; C6 X
  2. {
    ' K3 u# A) l7 J2 t$ p8 r0 J# u4 f
  3.     Speed_Adc = R3_1_F30X_ExecRegularConv(MC_SPEED_REF,ADC_CHANNEL_12);
    % e- D6 r" w; M8 V- D
  4.     Speed_ref = (15500*Speed_Adc)>>16;
    7 {  i% Y$ E( |7 U% U( E
  5.     if(Speed_ref > 0)# N% G3 p' E" i! g: Y! p; |: W( v9 x
  6.     {
      I2 c  v. o. {' ^; l- u& L
  7.         MC_ProgramSpeedRampMotor1((Speed_ref+1500)/6,1000);
    4 H; M, H: w9 i2 L
  8.         MC_StartMotor1();+ v  H+ x; r& G* a
  9.     }
    $ i8 x% d  C" v6 @
  10.     else
    . Z7 ~- R3 V4 I! [: S+ S
  11.     {
    3 T8 J( ^% A* X' b0 V, g8 ?& a* k
  12.         MC_StopMotor1();  S! ^$ {6 {& O9 T' z' j. y! A6 `) z
  13.     }
    . [' b  e- X: O7 K8 i
  14.     HAL_Delay(100);' n7 J. w" }1 `
  15. }
复制代码
主函数代码:
5 _3 v4 x: l( _  o2 i. u# n
  1. /* Initialize interrupts */
    ( b! i  J7 B( W& ~8 Y8 V* y
  2.   MX_NVIC_Init();: R. m% U3 d0 |+ f- k0 ~
  3.   /* USER CODE BEGIN 2 */0 h4 D0 K0 N2 l
  4.   MC_SPEED_REF = &PWM_Handle_M1._Super;% f: t1 Q) v. r
  5.   /* USER CODE END 2 */  h2 d  @; s- e! N

  6. . [0 T/ H5 i* N2 `* b
  7.   /* Infinite loop */% s3 @8 f. t' _! n$ K1 \# F
  8.   /* USER CODE BEGIN WHILE */. q, j/ D2 J- ~7 r; C
  9.   while (1)
    ; t6 F' ^8 p' o7 j
  10.   {
    % i2 M- }5 ~/ y6 @/ q% C) q/ L

  11. / q+ C. w* j& G3 ?3 K$ B' [. j8 q
  12.       if(GPIO_PIN_SET == HAL_GPIO_ReadPin(LED11_GPIO_Port,LED11_Pin))8 O9 |( F+ T# O- L7 z
  13.       {
    3 k5 ?( @1 H2 n' o
  14.           task_4();  L4 z4 J; o$ P
  15.       }/ y! r& R/ v+ j; i# u
  16.       else' \+ s9 k/ |) \; J& a- [
  17.       {
    7 d4 b( N% g4 }( w
  18.           MC_ProgramSpeedRampMotor1(0,0);
    4 ?' q' I/ y; [3 k- z* K4 l3 J
  19.           MC_StopMotor1();
    ' a' ]+ P  f3 l. v! f
  20.       }  W. O: W, F+ c  y: k  d5 A
  21.   /* USER CODE END WHILE */
    , e0 c, m, s- L3 N6 \
  22. ! W9 d1 K# l  g; E3 N: u
  23.   /* USER CODE BEGIN 3 */! ^* \( p- \4 @3 p2 X9 Z3 A4 D
  24. 7 W0 k  I8 @0 Q* o, X. r
  25.   }( X& M8 I- C( |
  26.   /* USER CODE END 3 */8 A4 h" Q9 d6 I2 a
复制代码
在这里稍微解释一下代码:
Speed_Adc是存储ADC采样值的变量,Speed_ref变量通过ADC采样值转化为速度设定值,MC_SPEED_REF是一个指针变量,用于获取ADC初始化设置,R3_1_F30X_ExecRegularConv这个函数在r3_1_f30x_pwm_curr_fdbk,c这个文件中,用于处理规则ADC采样。速度换算这里可以没什么说的。速度设定的时候加1500偏移是有原因的,当设定速度过低的时候电机系统根本不能正常启动,这是我尝试设置的时候所能达到的最低启动速度。
. ~; H! E; y# d2 v* [+ G% D" ]
实验现象:
旋钮调速转速跟踪波形.png
从实验结果看来,这份代码默认速度PID能很好的跟踪给定转速。
我发现一个问题,代码里面在电机运行结束之后有些变量好像没有清零,这个问题留到后面在研究吧。
1 R& `0 y; n" b' D. @
本帖两个任务分享就到这里,欢迎大家留言讨论。' w) m: d" }/ u' X* z4 \$ a) E* F
6 D/ z( P4 A% ^# R& Q4 D
+ K9 \! B2 X5 e/ X' V1 Z
) p2 p" G& ]# U' M, K0 `% c& a6 {9 W4 v

' v3 z4 i- m) ^9 I( D1 d
1 收藏 2 评论118 发布时间:2018-9-2 19:17

举报

118个回答
子曰好人 回答时间:2020-4-15 09:28:07
ysx584085668 发表于 2020-4-14 23:23& o: w7 E5 X% A9 l6 u) w' Q
太感谢了,我发邮件给你看吧

) J) Q6 [# C/ Y, |, m) D' j$ a看了你发的邮件,新版本的MCSDK生成的代码没有留ADC规则转换的函数接口,可能需要你自己去写了,我把我这边生成的文件发你一份参考吧7 K- g0 R+ s! p0 g: T* x" s5 T
r3_1_f30x_pwm_curr_fdbk.zip (16.66 KB, 下载次数: 10)
passby328 回答时间:2018-11-6 11:04:29
子曰好人 发表于 2018-11-6 09:357 }1 f6 `5 y3 M* y7 R
SDK5.1.3生成的代码里面没有regular_conversion_manager.c这个文件,5.2.0新增了。获取ADC值的代码是几乎 ...
: `9 p& V- B( o  |
1.我之前参考您的函数,如果一直不断在执行转换,会影响电机库的控制时序导致无法开机,后来改为500ms一次,就没有问题。后来检查regular_conversion_manager.c中的内容,发现用户ADC的转换应该是电机库的状态机在调度的,如果连续不断转换或者没有走相应的接口估计会有问题。
: I/ j* ?4 P, R, b  {  r+ J, F2.电机Workbench里面有设置OCP参数,看了原理图应该是通过体验板上面的L6230的内置比较器以及SMT32片内的ADC实现的,但是实际中的程序并没有提供类似的功能。后来查看了代码,OCP保护是通过L6230产生的FO信号进行处理的,不知道我说的是否有偏差,还请指教。
zhdzhd 回答时间:2018-9-2 22:27:32
代码规整,有功底,佩服!( s9 G; Y, @" x( u( y% I
大佬也会有纰漏啊6 Y+ V4 o: L8 S) d# e, U" t- V; Z( [# Z. F) c
' P. ^/ o7 z+ t) ^: N9 B" |
/* Infinite loop */! g& h" F% c4 [
  /* USER CODE BEGIN WHILE */, t/ k8 I% w& b& g" u
  while (1)" N9 u2 a- X* g
  {
) u$ U, H" y" l2 e6 C      0 V& o* E1 U& S
      if(GPIO_PIN_SET == HAL_GPIO_ReadPin(LED11_GPIO_Port,LED11_Pin))
3 x/ a* i) V" q/ W8 s      {2 _; H4 |" G! I6 `# d
          task_5(); ------>task_3();
' _$ R3 f5 u9 `% }) K      }
4 q* o* {0 M4 Z* O5 P      else$ K4 v  ~1 a, d5 e, k( X
      {9 ]; z* `* I6 q& i( ^& S
        MC_StopMotor1();
4 ]" S1 ^$ ^8 b: O# ?      }      
; U' y( ?' k! [9 c& p6 @/ Q; z! h9 D  /* USER CODE END WHILE */
子曰好人 回答时间:2018-9-2 22:36:27
zhdzhd-174422 发表于 2018-9-2 22:27
& l; `" I( t% ~- G2 o$ n代码规整,有功底,佩服!
, t% f8 k) H3 r# d" t% o- E7 i大佬也会有纰漏啊
( o2 X$ x. H1 ]* f. t
不好意思,感谢指正
STM1024 回答时间:2018-9-3 10:24:43
哈哈,和你观点一样,很多故障报警,都是报的speed feedback,我在测试的时候,连堵转都试过,原本以为是电流过大报警,但没想到居然还是speed feedback故障
子曰好人 回答时间:2018-9-3 10:45:56
stm1024 发表于 2018-9-3 10:24
# K9 R& J, ?) w3 J5 h: t哈哈,和你观点一样,很多故障报警,都是报的speed feedback,我在测试的时候,连堵转都试过,原本以为是电 ...

, M  @/ @' H  y0 `$ i  Q去研究一下电机库生成的故障触发机制代码,也许就能明白了,搞清楚是怎么回事之后就能自定义故障报警了
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()?1 \- R& D9 |2 B7 U0 {) O( B1 n* u
子曰好人 回答时间:2018-9-4 22:54:20
LT-386596 发表于 2018-9-4 18:38. W1 V( u# q8 a0 C
Speed_Adc = R3_1_F30X_ExecRegularConv(MC_SPEED_REF,ADC_CHANNEL_12); 5.2.0 找不到  R3_1_F30X_ExecRegu ...

! [. D8 i, m. 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:27
7 B+ P3 i/ q6 q7 h+ o, R2 L, VVR连接的脚感觉像是PB1,从电路图上来看.

# a) W* M7 I' \& j手误写错了,已更正
花落莫相离 回答时间: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
- M3 L4 `3 }: r9 }楼主,我不太懂Speed_ref = (15500*Speed_Adc)>>16;这段程序中15500的作用时什么?

% Z! Z+ M$ X: Y# G15500是电机能达到的最大转速,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( o7 I7 Y+ H! m% @
大神,不知道你有没有注意到有一个小细节,这个USB必须要插在主控板上整个程序好像才能运行,然后不插USB的 ...

, \7 P" l, v% |( u没遇到过,我的一直是正常的呀,没有USB连接也能正常运行
晴空 回答时间:2018-10-29 15:53:32
学习了  哈哈
花落莫相离 回答时间:2018-10-31 13:51:43
子曰好人 发表于 2018-10-26 09:16
& \& t5 y$ j5 `) S# O1 f' C15500是电机能达到的最大转速,Speed_Adc的最大值是4096,ADC采样值和速度参考值的换算方式为:(Spped_re ...

# j9 a0 E% V4 ]多谢楼主解释了。

所属标签

相似分享

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