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

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

[复制链接]
子曰好人 发布时间:2018-9-2 19:17
本帖最后由 子曰好人 于 2018-9-5 08:55 编辑
% D% u; W( E" b7 S* y/ Q+ s) o8 ^2 K( b# h) u
继续做实验,任务3和旋钮控制转速。
首先来看看任务3的要求:
任务3要求.png
这个可通过代码实现也可以通过上位机实现,已经有坛友做过这样的事情了。通过上位机做就是快速拨弄圆盘,这样系统不能在短时间内反转,造成观测器不能收敛,触发速度反馈错误报警,其实我个人觉得这里也是有过流报警存在的,这就看系统优先响应哪一个报警了。
我这里通过代码来实现task3。
任务3代码:
  1. void task_3(void)
    5 O% }" B% L, R3 c& s& }1 G" V
  2. {7 @7 f' [; z) U* D! x* @! X
  3.     MC_ProgramSpeedRampMotor1(-3000/6,1000); //设置-3000rpm的转速,在一秒之内达到- C; g6 k2 B3 W4 N, _7 u% z3 f
  4.     MC_StartMotor1();       //启动电机
    0 r3 z& n# M" E5 P8 o( @( \# c3 p) \
  5.     HAL_Delay(500);         //运行500ms  n7 P# m2 y" q* _) [, e
  6.     while(RUN != MC_GetSTMStateMotor1()); //等待电机处于运行状态,可有可无' Y$ z, J  U* g5 ^+ v7 x3 y
  7.     MC_ProgramSpeedRampMotor1(3000/6,1000); //切换到3000rpm转速
    6 F4 k! [6 `9 w: w' o7 F
  8.     MC_StartMotor1();       //启动电机$ k! M2 ^$ p  |! a+ z
  9.     while(MC_SPEED_FDBK != STM_GetFaultState(&STM[M1])); //等待错误触发
    # d9 I$ b# g* i9 H: e; L
  10.     HAL_Delay(1000);    //延时一秒,方便可以在上位机上看见错误是否发生
    / {2 [" ?: q' f
  11.     MC_AcknowledgeFaultMotor1();    //清除错误
    ' h1 Q0 X: E: ?" b5 ?- e: }
  12.     HAL_Delay(100);     //延时0.1秒
    6 Y% c9 v3 d; |
  13.     MC_ProgramSpeedRampMotor1(MC_GetLastRampFinalSpeedMotor1(),1000);   //重新设置上一次速度值
    : l: i1 {- j- p. D( m9 E) V. t
  14.     MC_StartMotor1();   //启动电机5 u& z% H+ n/ F# m2 d' _7 {% e
  15.     HAL_Delay(5000);    //运行5秒  ]: R5 |( V4 Y+ t1 f3 m( M
  16.     MC_StopMotor1();    //停机
    : X1 x7 _" {' f4 [; {
  17.     HAL_GPIO_WritePin(LED11_GPIO_Port,LED11_Pin,GPIO_PIN_RESET); //拉低LED引脚,表示任务结束
    3 s) {. \8 t$ w2 R% d) k4 s1 ~
  18. }2 c* b; }0 f9 I+ @0 W, Y
复制代码
主函数代码:
  1. /* Infinite loop */5 b' e0 r" |8 l! S, A
  2.   /* USER CODE BEGIN WHILE */
    & l; b. M* N% e" A$ ^
  3.   while (1)
    $ j. Y, D! Q7 u5 ~
  4.   {
    0 ~( d+ X* b) s& v% a
  5.       9 H  c' k' j. J. R5 I
  6.       if(GPIO_PIN_SET == HAL_GPIO_ReadPin(LED11_GPIO_Port,LED11_Pin))
    + i. l* D9 N' o. M4 y( O5 x" D- N/ m
  7.       {( _9 j* {% `: p& g
  8.           task_3();+ c# R' {  |! w
  9.       }- G0 J" M# ?' q( v4 B
  10.       else! q1 C9 O  K+ r. c8 n0 E
  11.       {
    1 J, K6 K( b+ ~$ B
  12.         MC_StopMotor1();" r% R# e: ?- b! u( |* u
  13.       }      
      N4 G0 n7 o( N- E' C# b& s
  14.   /* USER CODE END WHILE */2 h! }2 @( [2 U
复制代码
实验现象:
任务三速度变化截图.png
& ?4 d! {& |4 m2 `2 i
通过速度变化趋势可以看到任务成功实现了,我对比了PPT的预期结果图,有一些差距。当速度设置为3000rpm时,speed reference并没有跟随代码变为3000。另外,我做了延迟清除错误信息,所以在图中可以看到一截零速状态。
/ Y* [8 Q  D1 ~! ~
2 _5 v' o4 `+ |' o0 D" n
好了,任务3完成。
---------------------------------------------------------
现在分享一个开放性实验,旋钮控制转速,我把这个任务定为任务4吧,用旋钮来控制电机转速我觉得才是真正的一个电机控制系统。
由于SDK中并没有考虑旋钮ADC的初始化,所以如果要使用旋钮电位器首先要通过cubemx对ADC进行初始化,在我的第二篇帖子中已经讲过关于套件的硬件资源,也知道了旋钮电位器连接的是PB1引脚。
用户1.png
创建全局变量:
  1. int32_t Speed_Adc = 0;
    1 q1 ^+ E8 r4 y4 T" M$ Y
  2. int32_t Speed_ref = 0;
    : x+ ?$ H; f' ~0 P3 ]/ E
  3. PWMC_Handle_t * MC_SPEED_REF;4 W3 N( s4 R1 d
复制代码
任务4代码:
  1. void task_4(void)" D4 Y- |& L0 t/ H
  2. {
    . ~. N0 x4 u2 \" Z5 K# a7 g
  3.     Speed_Adc = R3_1_F30X_ExecRegularConv(MC_SPEED_REF,ADC_CHANNEL_12);. w: R, c5 a) F# i1 r
  4.     Speed_ref = (15500*Speed_Adc)>>16;
    ; c. r# e8 N4 ^! ^
  5.     if(Speed_ref > 0)' ]3 {" j  b5 c
  6.     {
    ' G. M. v. b- r, d
  7.         MC_ProgramSpeedRampMotor1((Speed_ref+1500)/6,1000);
    4 z. O, }! z$ ~7 ~1 ~( P
  8.         MC_StartMotor1();
    % k8 }! Z: w% }; R9 y7 Q- S" m
  9.     }
    " f- X/ j" G! D7 W# D* y1 K
  10.     else
    , |0 I" z6 |$ S2 @) |
  11.     {! U; D$ v8 e9 c
  12.         MC_StopMotor1();
    6 Q6 c0 E* j$ \
  13.     }
    : N/ r" o$ O' E. A# l
  14.     HAL_Delay(100);5 ^& N3 P2 `6 P5 {3 d+ p
  15. }
复制代码
主函数代码:
4 w2 v1 j# [+ w7 }: C" p
  1. /* Initialize interrupts */
    7 E+ p3 d- w# D5 r  H" o5 j
  2.   MX_NVIC_Init();
    1 r7 l5 ?  E$ ?1 B9 [2 h
  3.   /* USER CODE BEGIN 2 */
    : H8 s# D6 p4 P4 f; H1 o
  4.   MC_SPEED_REF = &PWM_Handle_M1._Super;$ b5 M8 J* }1 p4 n' r! q
  5.   /* USER CODE END 2 */" @- N4 z( v$ \

  6. 9 t. D" |4 Z% T5 W$ m9 v1 s
  7.   /* Infinite loop */
    5 x7 f) T% b4 R8 i6 o" @$ e
  8.   /* USER CODE BEGIN WHILE */; c+ Y8 O3 L# {3 L7 F
  9.   while (1)
    ; t( o7 V' i' H1 ~: V+ r
  10.   {' c! K: O/ S3 R" B% i  O  E8 J1 n
  11. / u8 u& W  D. h8 C$ ]
  12.       if(GPIO_PIN_SET == HAL_GPIO_ReadPin(LED11_GPIO_Port,LED11_Pin))* n# C: t" V. _% e( y$ i) R
  13.       {
    6 l' q1 v) I8 U, `& Z  s9 H  x
  14.           task_4();
    & ]) Z: c; R# V6 Z
  15.       }
    6 l+ L% u8 d3 q  d2 z+ b/ y+ k
  16.       else( W! `& s! K1 @- B
  17.       {( ?1 c% o4 k1 c4 y! e2 w
  18.           MC_ProgramSpeedRampMotor1(0,0);1 t4 v' l5 m% y  a& b0 h7 `% V
  19.           MC_StopMotor1();
    * P7 a* Q% d* b$ z5 y% E0 F
  20.       }
    " _" n2 Q- @" [& [# o& e" h' t& q
  21.   /* USER CODE END WHILE */
    5 N& Q$ T& N2 X/ ^' L/ w8 g

  22. 2 X* T& G$ v! E2 I) d$ O* w' b
  23.   /* USER CODE BEGIN 3 */; B& O: s3 L7 Z* w1 L) b0 C
  24. 8 m+ {+ F# `1 X% B" B
  25.   }2 k1 r8 n. p, V# {  v) C
  26.   /* USER CODE END 3 */* O" Y; {0 E1 L$ `
复制代码
在这里稍微解释一下代码:
Speed_Adc是存储ADC采样值的变量,Speed_ref变量通过ADC采样值转化为速度设定值,MC_SPEED_REF是一个指针变量,用于获取ADC初始化设置,R3_1_F30X_ExecRegularConv这个函数在r3_1_f30x_pwm_curr_fdbk,c这个文件中,用于处理规则ADC采样。速度换算这里可以没什么说的。速度设定的时候加1500偏移是有原因的,当设定速度过低的时候电机系统根本不能正常启动,这是我尝试设置的时候所能达到的最低启动速度。
  d2 {7 t9 Q- `0 M1 M
实验现象:
旋钮调速转速跟踪波形.png
从实验结果看来,这份代码默认速度PID能很好的跟踪给定转速。
我发现一个问题,代码里面在电机运行结束之后有些变量好像没有清零,这个问题留到后面在研究吧。

1 N; r6 J% \' C- Y
本帖两个任务分享就到这里,欢迎大家留言讨论。& h. b( n1 ~" e( Y/ c7 p

  w% S! e1 g1 V& V$ o; s1 {' |. ~
; Y/ P+ i7 D# n4 q

' ]& ^4 s2 Q# u1 K
1 收藏 2 评论118 发布时间:2018-9-2 19:17

举报

118个回答
子曰好人 回答时间:2020-4-15 09:28:07
ysx584085668 发表于 2020-4-14 23:233 q# x( B- `& A' C$ K' `
太感谢了,我发邮件给你看吧

/ {' e4 l! h2 P' y6 z% p看了你发的邮件,新版本的MCSDK生成的代码没有留ADC规则转换的函数接口,可能需要你自己去写了,我把我这边生成的文件发你一份参考吧# r! P, x/ ]; s! ]4 o+ J
r3_1_f30x_pwm_curr_fdbk.zip (16.66 KB, 下载次数: 10)
passby328 回答时间:2018-11-6 11:04:29
子曰好人 发表于 2018-11-6 09:35
' }+ X4 n# y  I; M. z' D+ nSDK5.1.3生成的代码里面没有regular_conversion_manager.c这个文件,5.2.0新增了。获取ADC值的代码是几乎 ...
7 c. z: E0 q( y
1.我之前参考您的函数,如果一直不断在执行转换,会影响电机库的控制时序导致无法开机,后来改为500ms一次,就没有问题。后来检查regular_conversion_manager.c中的内容,发现用户ADC的转换应该是电机库的状态机在调度的,如果连续不断转换或者没有走相应的接口估计会有问题。
5 d, y* k2 m9 I$ L: Z, ^' G2.电机Workbench里面有设置OCP参数,看了原理图应该是通过体验板上面的L6230的内置比较器以及SMT32片内的ADC实现的,但是实际中的程序并没有提供类似的功能。后来查看了代码,OCP保护是通过L6230产生的FO信号进行处理的,不知道我说的是否有偏差,还请指教。
zhdzhd 回答时间:2018-9-2 22:27:32
代码规整,有功底,佩服!; Z. \/ b* _: H! _, k) d* f# K; y
大佬也会有纰漏啊7 p* m" `5 ~! j

* P3 _( |% A+ E, O+ P! r/* Infinite loop */
& o8 a, A; W5 x  /* USER CODE BEGIN WHILE */2 I( t+ U- @. H6 o2 f
  while (1)6 x* y) m# \8 m
  {
9 I# h# G$ K( r  }# _) A      + B- v3 d0 J4 ?- Q
      if(GPIO_PIN_SET == HAL_GPIO_ReadPin(LED11_GPIO_Port,LED11_Pin))
- e% i- i8 ?: Z" J      {' \$ f# L0 u' E, C" P' N
          task_5(); ------>task_3();
* }% [( r  ^, a- q1 L& p% z1 s5 Z      }
, x$ n% Y: x0 f- ^+ Z      else
. B. h- f7 L2 g7 ?9 }: q; `# b      {
. h0 W, U6 V+ L: L* x        MC_StopMotor1();* {: s8 z/ I/ x: E
      }      2 B$ T% q5 m# c+ ]. w
  /* USER CODE END WHILE */
子曰好人 回答时间:2018-9-2 22:36:27
zhdzhd-174422 发表于 2018-9-2 22:27
3 B' P! N7 {+ k; V! a1 K代码规整,有功底,佩服!5 x; s/ `3 e1 O
大佬也会有纰漏啊

! u3 V8 N* }4 |4 c( N. e- B不好意思,感谢指正
STM1024 回答时间:2018-9-3 10:24:43
哈哈,和你观点一样,很多故障报警,都是报的speed feedback,我在测试的时候,连堵转都试过,原本以为是电流过大报警,但没想到居然还是speed feedback故障
子曰好人 回答时间:2018-9-3 10:45:56
stm1024 发表于 2018-9-3 10:24$ Z! e* s* R' A0 J
哈哈,和你观点一样,很多故障报警,都是报的speed feedback,我在测试的时候,连堵转都试过,原本以为是电 ...
, s' A6 ^1 ^0 y% Q9 [" l7 U' I$ ^
去研究一下电机库生成的故障触发机制代码,也许就能明白了,搞清楚是怎么回事之后就能自定义故障报警了
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()?0 G* B" x. h  q+ Q* e) l5 x
子曰好人 回答时间:2018-9-4 22:54:20
LT-386596 发表于 2018-9-4 18:38
8 Y" G( X9 d7 ySpeed_Adc = R3_1_F30X_ExecRegularConv(MC_SPEED_REF,ADC_CHANNEL_12); 5.2.0 找不到  R3_1_F30X_ExecRegu ...

% d: ~2 }- Y. S在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
8 {( B0 D% `2 d( ^5 nVR连接的脚感觉像是PB1,从电路图上来看.

: z7 {5 x1 P8 V& D手误写错了,已更正
花落莫相离 回答时间: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:582 \9 f, p- _* A; ]  S) l9 J
楼主,我不太懂Speed_ref = (15500*Speed_Adc)>>16;这段程序中15500的作用时什么?
1 G4 ?; p* J7 L" m# p% v9 N
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
! K5 O6 S) K7 E" t; b2 I大神,不知道你有没有注意到有一个小细节,这个USB必须要插在主控板上整个程序好像才能运行,然后不插USB的 ...

' x, ]1 K8 l0 V' ~* b- g没遇到过,我的一直是正常的呀,没有USB连接也能正常运行
晴空 回答时间:2018-10-29 15:53:32
学习了  哈哈
花落莫相离 回答时间:2018-10-31 13:51:43
子曰好人 发表于 2018-10-26 09:16" X' f/ U! e- B( y/ J2 V# W& K
15500是电机能达到的最大转速,Speed_Adc的最大值是4096,ADC采样值和速度参考值的换算方式为:(Spped_re ...

' [( G! c1 \" Z$ `$ J4 J多谢楼主解释了。

所属标签

相似分享

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