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

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

[复制链接]
子曰好人 发布时间:2018-9-2 19:17
本帖最后由 子曰好人 于 2018-9-5 08:55 编辑 % \0 u/ j2 s% Z% b
; P5 b& I' }! B: E5 D4 t& h
继续做实验,任务3和旋钮控制转速。
首先来看看任务3的要求:
任务3要求.png
这个可通过代码实现也可以通过上位机实现,已经有坛友做过这样的事情了。通过上位机做就是快速拨弄圆盘,这样系统不能在短时间内反转,造成观测器不能收敛,触发速度反馈错误报警,其实我个人觉得这里也是有过流报警存在的,这就看系统优先响应哪一个报警了。
我这里通过代码来实现task3。
任务3代码:
  1. void task_3(void)
    8 m9 K0 r9 a/ A) J1 k5 M
  2. {  _4 P/ B. B' j/ ?. g: Q8 \9 r
  3.     MC_ProgramSpeedRampMotor1(-3000/6,1000); //设置-3000rpm的转速,在一秒之内达到
    ! ^' G  e' K+ u4 ^
  4.     MC_StartMotor1();       //启动电机0 I% b$ t, ?- F. O* X2 `. _0 C
  5.     HAL_Delay(500);         //运行500ms- H- s( O' |) J+ d8 a1 s
  6.     while(RUN != MC_GetSTMStateMotor1()); //等待电机处于运行状态,可有可无
    4 a  U2 m: Q* L( ~7 \5 ^! ^1 P
  7.     MC_ProgramSpeedRampMotor1(3000/6,1000); //切换到3000rpm转速
    ; ?9 q. y) W- w( ?& P" B' A+ k
  8.     MC_StartMotor1();       //启动电机
      h7 s/ E# z% |8 v0 }; G
  9.     while(MC_SPEED_FDBK != STM_GetFaultState(&STM[M1])); //等待错误触发
    1 z, w! {& Y/ O' `
  10.     HAL_Delay(1000);    //延时一秒,方便可以在上位机上看见错误是否发生
    * O) K- {) q& N& E7 i! }; ?
  11.     MC_AcknowledgeFaultMotor1();    //清除错误
    / p1 r* h" a6 {$ E* g* n
  12.     HAL_Delay(100);     //延时0.1秒
    % ^6 W4 g1 X% _/ t* N/ r' c6 Q
  13.     MC_ProgramSpeedRampMotor1(MC_GetLastRampFinalSpeedMotor1(),1000);   //重新设置上一次速度值, x9 Q6 H( `; D! E
  14.     MC_StartMotor1();   //启动电机2 J" b0 v! r8 n/ h' q5 E( m
  15.     HAL_Delay(5000);    //运行5秒( z; Q8 i/ ?4 T0 s' F! i# e0 t+ h# z
  16.     MC_StopMotor1();    //停机: l3 q: T7 w1 \* D  M& e$ M; _1 @( s
  17.     HAL_GPIO_WritePin(LED11_GPIO_Port,LED11_Pin,GPIO_PIN_RESET); //拉低LED引脚,表示任务结束
    $ z, u& h" q+ I5 E" X0 i
  18. }
    8 R+ i1 [; H0 r# E* z2 ]
复制代码
主函数代码:
  1. /* Infinite loop */; n- A- g- r' G
  2.   /* USER CODE BEGIN WHILE */2 m* Y9 c1 X+ [& C
  3.   while (1): E/ Y& @9 C# Z+ J; B* S
  4.   {9 Y+ F) [: y, P( `8 u% [
  5.       
      d' d3 l+ J! T! \# R: h
  6.       if(GPIO_PIN_SET == HAL_GPIO_ReadPin(LED11_GPIO_Port,LED11_Pin))6 ^: F. X+ U6 [+ P$ n- e
  7.       {, m9 Y2 W! M( B; h8 ]. H" c
  8.           task_3();
    0 t1 U5 M2 |- a! R
  9.       }
    9 C' v- L5 h! m: X0 [( [
  10.       else
      |+ s/ e" D; q! i
  11.       {3 D1 r: N4 g7 |, A& w9 a' x3 u
  12.         MC_StopMotor1();; o# N; E! n  A0 I) e8 _6 a# c
  13.       }      
    # |+ ?# Y: M6 ?# D
  14.   /* USER CODE END WHILE */: B* U" r& Q3 x1 a
复制代码
实验现象:
任务三速度变化截图.png
% w7 X' R8 A, L3 |6 {
通过速度变化趋势可以看到任务成功实现了,我对比了PPT的预期结果图,有一些差距。当速度设置为3000rpm时,speed reference并没有跟随代码变为3000。另外,我做了延迟清除错误信息,所以在图中可以看到一截零速状态。

) Q* j7 {+ |8 F( ^& L' ]

4 h1 I4 j( g8 b, ], m: N* Y, U好了,任务3完成。
---------------------------------------------------------
现在分享一个开放性实验,旋钮控制转速,我把这个任务定为任务4吧,用旋钮来控制电机转速我觉得才是真正的一个电机控制系统。
由于SDK中并没有考虑旋钮ADC的初始化,所以如果要使用旋钮电位器首先要通过cubemx对ADC进行初始化,在我的第二篇帖子中已经讲过关于套件的硬件资源,也知道了旋钮电位器连接的是PB1引脚。
用户1.png
创建全局变量:
  1. int32_t Speed_Adc = 0;
    5 J/ p" w$ H0 p
  2. int32_t Speed_ref = 0;
    8 e# F; Y  V* M4 M) e
  3. PWMC_Handle_t * MC_SPEED_REF;
    , P6 [4 l4 X) R/ v; J, ]# J$ c
复制代码
任务4代码:
  1. void task_4(void)
    + B$ N/ D( M! |; P
  2. {
    , l+ Y& F; [! C
  3.     Speed_Adc = R3_1_F30X_ExecRegularConv(MC_SPEED_REF,ADC_CHANNEL_12);
    & k' {" a. E' q6 N3 R
  4.     Speed_ref = (15500*Speed_Adc)>>16;
    ! `' k5 {6 b: u1 j0 i
  5.     if(Speed_ref > 0)
    0 M0 K% B% w  U) U
  6.     {; c& O" @  u% V
  7.         MC_ProgramSpeedRampMotor1((Speed_ref+1500)/6,1000);. C+ z  _4 s4 B, [( W; K
  8.         MC_StartMotor1();+ Z; ?& d* m2 O
  9.     }
    ( r; C% p+ l# \- M$ W
  10.     else
    1 t5 a9 P& K4 u8 w# P
  11.     {
    2 Q# y& V! }! s% Y
  12.         MC_StopMotor1();5 ?  H9 ?$ t& y+ a
  13.     }) ~" N! Y" v+ V% g" B, S
  14.     HAL_Delay(100);
    / w" Z# \0 F8 }! H/ Q1 D
  15. }
复制代码
主函数代码:
. |* |: A, ^0 {/ B# p$ O1 s8 y0 G: B
  1. /* Initialize interrupts */! j( B/ ?8 }* `  C
  2.   MX_NVIC_Init();
    ) Y$ |8 _8 z, s. K
  3.   /* USER CODE BEGIN 2 */
    * W) @, U# P! q
  4.   MC_SPEED_REF = &PWM_Handle_M1._Super;, e$ h( x& Y& g
  5.   /* USER CODE END 2 */; V( O! ]$ y% q/ Q0 ^

  6. 3 }; K1 K2 |4 `! t+ ?
  7.   /* Infinite loop */
    8 j3 |6 ^: D5 g- X% H) u: z& \& b
  8.   /* USER CODE BEGIN WHILE */
    & a, p) m# i5 O; Y/ N
  9.   while (1)
    & ^2 H% t; d* B7 ^, u# ^# I) Q
  10.   {
    ( Y. L' m0 `: ?  u

  11. ' R3 }0 ~& Z. _" l3 D0 R
  12.       if(GPIO_PIN_SET == HAL_GPIO_ReadPin(LED11_GPIO_Port,LED11_Pin)): T. _! ]8 M: |0 P$ F& B4 |4 V2 P
  13.       {# z2 ^0 c" C$ V, `5 k  O
  14.           task_4();
    3 p' C7 E  N+ h2 b, b
  15.       }# e9 _" E9 i9 h
  16.       else
    * J8 z' H- C6 w! P, V! d7 G  Y
  17.       {4 K5 w# k  u% y0 b" C
  18.           MC_ProgramSpeedRampMotor1(0,0);8 ~0 _" {6 K) `" H, m2 z
  19.           MC_StopMotor1();
    1 ~  O5 R0 h& G
  20.       }
    6 `, e( h) o! @/ m
  21.   /* USER CODE END WHILE */
    , l) B) X. T$ \

  22. * c" U5 `) {2 Q  b1 g
  23.   /* USER CODE BEGIN 3 */
    $ Q- p0 a& `1 j; @& S+ _
  24. # h' ?9 v( C. b+ {) j/ M' D
  25.   }
    6 H1 j$ D' W/ e
  26.   /* USER CODE END 3 */1 {" A/ X6 c( H( E, g& e5 m( @5 K
复制代码
在这里稍微解释一下代码:
Speed_Adc是存储ADC采样值的变量,Speed_ref变量通过ADC采样值转化为速度设定值,MC_SPEED_REF是一个指针变量,用于获取ADC初始化设置,R3_1_F30X_ExecRegularConv这个函数在r3_1_f30x_pwm_curr_fdbk,c这个文件中,用于处理规则ADC采样。速度换算这里可以没什么说的。速度设定的时候加1500偏移是有原因的,当设定速度过低的时候电机系统根本不能正常启动,这是我尝试设置的时候所能达到的最低启动速度。

3 t: H3 a" M5 D3 L. O9 d5 ^
实验现象:
旋钮调速转速跟踪波形.png
从实验结果看来,这份代码默认速度PID能很好的跟踪给定转速。
我发现一个问题,代码里面在电机运行结束之后有些变量好像没有清零,这个问题留到后面在研究吧。
1 O: w6 t5 I5 ^5 i$ g' v5 \1 U
本帖两个任务分享就到这里,欢迎大家留言讨论。& e' b. K1 r8 k8 R- n. q% p

. a; c% d8 P! @! Z. T6 R( ^6 W. N; l  R; y4 X- }
* o3 K! ?- P# z& R- P) \
$ k* F6 s$ s. F% x% r
1 收藏 2 评论118 发布时间:2018-9-2 19:17

举报

118个回答
子曰好人 回答时间:2020-4-15 09:28:07
ysx584085668 发表于 2020-4-14 23:23
$ q0 c2 y: \, N7 j2 ~: p; J太感谢了,我发邮件给你看吧

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

* d$ s9 B1 ^. m: d去研究一下电机库生成的故障触发机制代码,也许就能明白了,搞清楚是怎么回事之后就能自定义故障报警了
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()?
) l) k3 f) m8 H' N& y
子曰好人 回答时间:2018-9-4 22:54:20
LT-386596 发表于 2018-9-4 18:38
- ^; G$ i% H, P4 T0 o+ B! hSpeed_Adc = R3_1_F30X_ExecRegularConv(MC_SPEED_REF,ADC_CHANNEL_12); 5.2.0 找不到  R3_1_F30X_ExecRegu ...
* K" m; q( D* N- A) P
在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
1 Q  P9 w3 |3 `7 ]/ j' C4 a% Y3 XVR连接的脚感觉像是PB1,从电路图上来看.
8 D3 _: K% t) @3 S+ Z
手误写错了,已更正
花落莫相离 回答时间: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:581 K1 j: }! A, P9 B" v& d2 b( w
楼主,我不太懂Speed_ref = (15500*Speed_Adc)>>16;这段程序中15500的作用时什么?
  Z1 @! v- b. u
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$ \5 H$ p% \' M- g
大神,不知道你有没有注意到有一个小细节,这个USB必须要插在主控板上整个程序好像才能运行,然后不插USB的 ...
8 }/ Z) o$ t: e) P, ]5 C! a
没遇到过,我的一直是正常的呀,没有USB连接也能正常运行
晴空 回答时间:2018-10-29 15:53:32
学习了  哈哈
花落莫相离 回答时间:2018-10-31 13:51:43
子曰好人 发表于 2018-10-26 09:16
3 `* }! D$ E; A1 x9 ?) J) B15500是电机能达到的最大转速,Speed_Adc的最大值是4096,ADC采样值和速度参考值的换算方式为:(Spped_re ...
. G. r( B; [7 [# n4 p9 F
多谢楼主解释了。

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版