请选择 进入手机版 | 继续访问电脑版

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

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

[复制链接]
子曰好人 发布时间:2018-9-2 19:17
本帖最后由 子曰好人 于 2018-9-5 08:55 编辑
# ?4 s  s9 ?, r( Q6 M
4 Q7 B9 p  u5 o
继续做实验,任务3和旋钮控制转速。
首先来看看任务3的要求:
任务3要求.png
这个可通过代码实现也可以通过上位机实现,已经有坛友做过这样的事情了。通过上位机做就是快速拨弄圆盘,这样系统不能在短时间内反转,造成观测器不能收敛,触发速度反馈错误报警,其实我个人觉得这里也是有过流报警存在的,这就看系统优先响应哪一个报警了。
我这里通过代码来实现task3。
任务3代码:
  1. void task_3(void)
    " x* p# V0 m  D* Y- D+ T' x
  2. {
    / }1 ^; b, u+ w# B: S- W
  3.     MC_ProgramSpeedRampMotor1(-3000/6,1000); //设置-3000rpm的转速,在一秒之内达到8 f& v; P# n2 E0 q1 z) j* ^: N
  4.     MC_StartMotor1();       //启动电机
    3 H; _$ Y/ p% e2 K! i: K
  5.     HAL_Delay(500);         //运行500ms
    5 t2 [% }1 f1 v: z0 D% h
  6.     while(RUN != MC_GetSTMStateMotor1()); //等待电机处于运行状态,可有可无
    2 s) ?6 J0 a/ t* [5 \  s
  7.     MC_ProgramSpeedRampMotor1(3000/6,1000); //切换到3000rpm转速
    , e" j. g" A8 @6 [
  8.     MC_StartMotor1();       //启动电机
    ( u6 k: N% @$ k5 |9 y
  9.     while(MC_SPEED_FDBK != STM_GetFaultState(&STM[M1])); //等待错误触发. ^9 _  E( C/ N# z( Q3 ^7 {3 A; z
  10.     HAL_Delay(1000);    //延时一秒,方便可以在上位机上看见错误是否发生/ O5 I6 h" B# h) O/ R
  11.     MC_AcknowledgeFaultMotor1();    //清除错误5 k1 u, c, m: O0 ?" n
  12.     HAL_Delay(100);     //延时0.1秒8 p. |% T/ ~+ O$ b
  13.     MC_ProgramSpeedRampMotor1(MC_GetLastRampFinalSpeedMotor1(),1000);   //重新设置上一次速度值# q" O- `- J2 R1 V. ^" |
  14.     MC_StartMotor1();   //启动电机
    & Z# f4 I8 \+ d! h' i4 S" x
  15.     HAL_Delay(5000);    //运行5秒
    ) C4 g$ ]) i6 T; G! p6 u. |0 }
  16.     MC_StopMotor1();    //停机
    2 h0 b! E/ W, y9 {
  17.     HAL_GPIO_WritePin(LED11_GPIO_Port,LED11_Pin,GPIO_PIN_RESET); //拉低LED引脚,表示任务结束0 I" L. p) D) f3 d+ F1 n' ]
  18. }
    6 ~: i2 J* t7 u$ s2 o* _: q
复制代码
主函数代码:
  1. /* Infinite loop */
    * s5 z1 H/ P) B1 l
  2.   /* USER CODE BEGIN WHILE */
    ( S2 W/ a* ]7 E  h/ {
  3.   while (1)
    $ w2 e/ Z3 V* A& q& G5 y7 A
  4.   {
    . F& ?1 Z7 K9 V2 p2 d
  5.       
    9 _5 F% t/ N2 L$ g9 b: j6 r7 w# m
  6.       if(GPIO_PIN_SET == HAL_GPIO_ReadPin(LED11_GPIO_Port,LED11_Pin))% k# T. P. u/ r( z) G
  7.       {& L2 r# t& P" g; \
  8.           task_3();
    # ]7 _6 A1 \& W6 ?9 C! S
  9.       }' M/ j8 m! s. b. c
  10.       else' \$ n! O) J- S9 F7 B( i' g& h
  11.       {. v+ d, [9 j# ?) j
  12.         MC_StopMotor1();
    5 Z* o  k4 a% V
  13.       }      / i8 ?) h  ~% y( S
  14.   /* USER CODE END WHILE */9 X9 Q' T1 f3 t! d& u9 y9 X
复制代码
实验现象:
任务三速度变化截图.png
) W2 @& N9 ?  }
通过速度变化趋势可以看到任务成功实现了,我对比了PPT的预期结果图,有一些差距。当速度设置为3000rpm时,speed reference并没有跟随代码变为3000。另外,我做了延迟清除错误信息,所以在图中可以看到一截零速状态。

, `' {9 T/ i4 _: s

- T. O3 L! h% m7 O8 z* k& K好了,任务3完成。
---------------------------------------------------------
现在分享一个开放性实验,旋钮控制转速,我把这个任务定为任务4吧,用旋钮来控制电机转速我觉得才是真正的一个电机控制系统。
由于SDK中并没有考虑旋钮ADC的初始化,所以如果要使用旋钮电位器首先要通过cubemx对ADC进行初始化,在我的第二篇帖子中已经讲过关于套件的硬件资源,也知道了旋钮电位器连接的是PB1引脚。
用户1.png
创建全局变量:
  1. int32_t Speed_Adc = 0;
    3 p& Z/ y3 U$ T4 b" f& V
  2. int32_t Speed_ref = 0;
    2 N, C( U' t0 l% G  x+ D
  3. PWMC_Handle_t * MC_SPEED_REF;8 N6 K' O! N4 a7 j1 |$ S
复制代码
任务4代码:
  1. void task_4(void)
    0 A, _# Y; a1 ~
  2. {! ^/ N) R' q+ [9 n( Z
  3.     Speed_Adc = R3_1_F30X_ExecRegularConv(MC_SPEED_REF,ADC_CHANNEL_12);
    9 R) O  G6 V. ^8 f) y# f1 C
  4.     Speed_ref = (15500*Speed_Adc)>>16;
    $ @' t* I# `3 T6 L% r9 W
  5.     if(Speed_ref > 0)
    - j0 E. l  s& h, a; T
  6.     {
      `  r  `- G/ z; f( d- x' c' d5 Y# g
  7.         MC_ProgramSpeedRampMotor1((Speed_ref+1500)/6,1000);5 l- U+ z) u1 ~( V3 H1 Y
  8.         MC_StartMotor1();0 T5 q6 M; S$ q. X1 c9 r; m
  9.     }
    3 p. x  E) V% {5 K
  10.     else9 Y! e7 j# ?5 O& M" Q1 j: }. j, W, \
  11.     {0 \% W# j6 R; U
  12.         MC_StopMotor1();) w" @  T" V" J7 W
  13.     }$ f3 I% U8 Y4 {5 I) y
  14.     HAL_Delay(100);
    ) S0 A6 D9 J# \7 p
  15. }
复制代码
主函数代码:
1 B# p0 A2 t$ m  }
  1. /* Initialize interrupts */
    / E- @4 a0 n+ A+ O! V
  2.   MX_NVIC_Init();8 A+ _7 G! ^7 i" x3 x
  3.   /* USER CODE BEGIN 2 */! l0 V2 ^4 w, R+ G- ]4 z5 u
  4.   MC_SPEED_REF = &PWM_Handle_M1._Super;
    3 w9 B& ^; L- [' V( K
  5.   /* USER CODE END 2 */5 E7 ]% `$ p7 ?! e  @
  6. 8 R' \1 n* b4 D# @& y3 G
  7.   /* Infinite loop */
    1 s- ^! f6 ]( O  I
  8.   /* USER CODE BEGIN WHILE */0 X; _+ ~/ m# ^. X  Y  n
  9.   while (1)* N3 z+ X* T5 E" z- \4 J1 d
  10.   {8 |: Y  [; O! [) L! J! n

  11. 5 F( A* H% W- q0 d+ y2 `7 b5 I4 O
  12.       if(GPIO_PIN_SET == HAL_GPIO_ReadPin(LED11_GPIO_Port,LED11_Pin))
    " ?4 x: v) o1 V0 a4 `
  13.       {
    8 n1 l5 W# I* Q% ?( S' c
  14.           task_4();9 n3 t" d; y2 M% a
  15.       }
    , l, K7 J# F6 r) G- |( k) D
  16.       else7 ]6 l' m1 R! Q, t) r4 a, _6 S
  17.       {; f0 o) ^/ _0 G$ C4 g
  18.           MC_ProgramSpeedRampMotor1(0,0);
    * h  Y, g$ f7 u1 b! {4 g( F
  19.           MC_StopMotor1();
    3 w) J7 L, L; T5 f* q
  20.       }. x5 q+ R) l8 S! _- G
  21.   /* USER CODE END WHILE */( V" \8 R1 G6 w" l) ]+ d& n' {
  22. 3 D2 @% B7 w2 f- O- r$ S
  23.   /* USER CODE BEGIN 3 */) F+ c8 S0 R& }0 \- q9 i
  24. ; r# f" k/ ?8 O3 j' {
  25.   }3 w, ^, b1 I+ D) q; K; ?1 Q7 k
  26.   /* USER CODE END 3 */1 t$ a2 F1 H# O1 `8 G
复制代码
在这里稍微解释一下代码:
Speed_Adc是存储ADC采样值的变量,Speed_ref变量通过ADC采样值转化为速度设定值,MC_SPEED_REF是一个指针变量,用于获取ADC初始化设置,R3_1_F30X_ExecRegularConv这个函数在r3_1_f30x_pwm_curr_fdbk,c这个文件中,用于处理规则ADC采样。速度换算这里可以没什么说的。速度设定的时候加1500偏移是有原因的,当设定速度过低的时候电机系统根本不能正常启动,这是我尝试设置的时候所能达到的最低启动速度。

8 l7 Q1 ^! d7 W3 f& r+ ?/ c* {; z
实验现象:
旋钮调速转速跟踪波形.png
从实验结果看来,这份代码默认速度PID能很好的跟踪给定转速。
我发现一个问题,代码里面在电机运行结束之后有些变量好像没有清零,这个问题留到后面在研究吧。

1 v1 G( {2 r8 |: f0 X
本帖两个任务分享就到这里,欢迎大家留言讨论。( ^! O6 k% q: j
  G; S7 s' D3 }
9 X) {) x( N; m) d- G

- r$ _& ]8 F9 T9 a( F* @
8 P0 ^9 B& k& U
1 收藏 2 评论118 发布时间:2018-9-2 19:17

举报

118个回答
子曰好人 回答时间:2020-4-15 09:28:07
ysx584085668 发表于 2020-4-14 23:233 f% k* ?2 C5 U- X- [
太感谢了,我发邮件给你看吧
! E" y" \+ n% y" M% G6 |) G+ J
看了你发的邮件,新版本的MCSDK生成的代码没有留ADC规则转换的函数接口,可能需要你自己去写了,我把我这边生成的文件发你一份参考吧
: q$ \! |. [( a  `0 I r3_1_f30x_pwm_curr_fdbk.zip (16.66 KB, 下载次数: 10)
passby328 回答时间:2018-11-6 11:04:29
子曰好人 发表于 2018-11-6 09:35
2 c- z, H& J# f1 r; A2 W' n' ^SDK5.1.3生成的代码里面没有regular_conversion_manager.c这个文件,5.2.0新增了。获取ADC值的代码是几乎 ...

9 b7 |; m7 d, l7 A" R1.我之前参考您的函数,如果一直不断在执行转换,会影响电机库的控制时序导致无法开机,后来改为500ms一次,就没有问题。后来检查regular_conversion_manager.c中的内容,发现用户ADC的转换应该是电机库的状态机在调度的,如果连续不断转换或者没有走相应的接口估计会有问题。* S, h" T& ?# n2 ^' i
2.电机Workbench里面有设置OCP参数,看了原理图应该是通过体验板上面的L6230的内置比较器以及SMT32片内的ADC实现的,但是实际中的程序并没有提供类似的功能。后来查看了代码,OCP保护是通过L6230产生的FO信号进行处理的,不知道我说的是否有偏差,还请指教。
zhdzhd 回答时间:2018-9-2 22:27:32
代码规整,有功底,佩服!
- E0 Z8 l" A: W7 s大佬也会有纰漏啊
& S/ `+ T( Z* n" L  N3 J* L' y4 ?5 I' f' r8 A! d
/* Infinite loop */4 \8 R& w, }: s4 A# I" P
  /* USER CODE BEGIN WHILE */
) R' H+ G/ h7 Y8 V9 H* K# a  while (1)
8 s0 A9 V% K/ w5 T+ w  {; l* A1 m# u8 f7 u% H5 k
      ) c" v8 ~+ N+ F; [6 N
      if(GPIO_PIN_SET == HAL_GPIO_ReadPin(LED11_GPIO_Port,LED11_Pin))
+ c- G& G6 ]5 v: V      {
7 y) \5 \* P7 b1 m2 A7 H4 e3 T          task_5(); ------>task_3();
" {+ D4 T4 c: {: d0 X$ Z4 u* R      }% @9 u/ m9 P9 m
      else# O1 y" P! H9 D1 N0 G
      {0 G) w0 g9 f' }' }4 X3 [% e! }& j
        MC_StopMotor1();  N/ h# S# s/ u( t, z
      }      
0 j' D2 J4 F3 y2 W! M. x9 r  /* USER CODE END WHILE */
子曰好人 回答时间:2018-9-2 22:36:27
zhdzhd-174422 发表于 2018-9-2 22:27
1 w' a# A) K9 Q/ n9 A) g& ?代码规整,有功底,佩服!
7 g7 \1 S6 P1 t: Z% u4 s大佬也会有纰漏啊
9 ?0 k5 `: h, m+ S* d: M8 T' Z2 i
不好意思,感谢指正
STM1024 回答时间:2018-9-3 10:24:43
哈哈,和你观点一样,很多故障报警,都是报的speed feedback,我在测试的时候,连堵转都试过,原本以为是电流过大报警,但没想到居然还是speed feedback故障
子曰好人 回答时间:2018-9-3 10:45:56
stm1024 发表于 2018-9-3 10:24
+ q$ W- |! ?* P+ M哈哈,和你观点一样,很多故障报警,都是报的speed feedback,我在测试的时候,连堵转都试过,原本以为是电 ...
! m) S( g2 D& w
去研究一下电机库生成的故障触发机制代码,也许就能明白了,搞清楚是怎么回事之后就能自定义故障报警了
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()?
! k0 O; W- M) {1 B# O! _" T
子曰好人 回答时间:2018-9-4 22:54:20
LT-386596 发表于 2018-9-4 18:38( @. @  Q8 V3 e
Speed_Adc = R3_1_F30X_ExecRegularConv(MC_SPEED_REF,ADC_CHANNEL_12); 5.2.0 找不到  R3_1_F30X_ExecRegu ...

, M) R. g2 i+ b3 m! L. A* [在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+ i5 K; y( i1 q% T! S  C# |
VR连接的脚感觉像是PB1,从电路图上来看.
7 U# j( ~* K: M/ q7 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:58
+ U3 A: J2 e3 a# w8 I7 M6 F楼主,我不太懂Speed_ref = (15500*Speed_Adc)>>16;这段程序中15500的作用时什么?

7 @" D; j; P2 w8 b/ t% o+ c15500是电机能达到的最大转速,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! j. x7 W0 _+ H& l
大神,不知道你有没有注意到有一个小细节,这个USB必须要插在主控板上整个程序好像才能运行,然后不插USB的 ...
3 M1 V& N7 e" i7 c9 J' ^
没遇到过,我的一直是正常的呀,没有USB连接也能正常运行
晴空 回答时间:2018-10-29 15:53:32
学习了  哈哈
花落莫相离 回答时间:2018-10-31 13:51:43
子曰好人 发表于 2018-10-26 09:16. A4 {( {, m4 ~& j2 V; R
15500是电机能达到的最大转速,Speed_Adc的最大值是4096,ADC采样值和速度参考值的换算方式为:(Spped_re ...

  n, E6 ]" l0 n- @多谢楼主解释了。

所属标签

相似分享

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