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

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

[复制链接]
子曰好人 发布时间:2018-9-2 19:17
本帖最后由 子曰好人 于 2018-9-5 08:55 编辑 3 ]+ h1 B# x, p# o7 p% j6 v( `7 e9 O, _
3 M4 i% D* Z8 B. K! k0 h( V
继续做实验,任务3和旋钮控制转速。
首先来看看任务3的要求:
任务3要求.png
这个可通过代码实现也可以通过上位机实现,已经有坛友做过这样的事情了。通过上位机做就是快速拨弄圆盘,这样系统不能在短时间内反转,造成观测器不能收敛,触发速度反馈错误报警,其实我个人觉得这里也是有过流报警存在的,这就看系统优先响应哪一个报警了。
我这里通过代码来实现task3。
任务3代码:
  1. void task_3(void)
    : u2 `' Y6 t4 c0 ]/ K. ]
  2. {  a; _' g' a4 h7 R$ v4 A
  3.     MC_ProgramSpeedRampMotor1(-3000/6,1000); //设置-3000rpm的转速,在一秒之内达到
    5 U- }7 X6 J5 T+ i6 t+ f
  4.     MC_StartMotor1();       //启动电机
    6 ]& t! f' F4 h+ g
  5.     HAL_Delay(500);         //运行500ms" F  s$ E5 I7 J3 ^# O* f* `' w% j% A
  6.     while(RUN != MC_GetSTMStateMotor1()); //等待电机处于运行状态,可有可无# c- v: y8 `7 \- K; Z6 K
  7.     MC_ProgramSpeedRampMotor1(3000/6,1000); //切换到3000rpm转速
    8 y2 A- K4 c" c$ C9 _. Z# ~7 g  d
  8.     MC_StartMotor1();       //启动电机
    ; U2 G3 q8 U/ Y3 o* ]% K
  9.     while(MC_SPEED_FDBK != STM_GetFaultState(&STM[M1])); //等待错误触发3 V2 H. U4 |: e  S6 r
  10.     HAL_Delay(1000);    //延时一秒,方便可以在上位机上看见错误是否发生. T+ s" |/ B2 w7 t! M2 b
  11.     MC_AcknowledgeFaultMotor1();    //清除错误
    3 T: a$ G1 a  `' k
  12.     HAL_Delay(100);     //延时0.1秒6 ?, N3 A9 S7 A3 a- Q' Q4 u2 @
  13.     MC_ProgramSpeedRampMotor1(MC_GetLastRampFinalSpeedMotor1(),1000);   //重新设置上一次速度值0 Z; D1 P# Y5 {
  14.     MC_StartMotor1();   //启动电机
    $ _0 ?+ ?3 Y. B8 s: J: C0 X; ]
  15.     HAL_Delay(5000);    //运行5秒
    : d7 Y3 n& Q) p: K; h6 J# p
  16.     MC_StopMotor1();    //停机
    3 O- ~- X% r3 U. U. P
  17.     HAL_GPIO_WritePin(LED11_GPIO_Port,LED11_Pin,GPIO_PIN_RESET); //拉低LED引脚,表示任务结束; S0 Q0 ]& }+ n2 q( c
  18. }1 G0 }. T. F; q2 c# _1 ~) J% ?
复制代码
主函数代码:
  1. /* Infinite loop */8 E0 j7 X: ]( I8 u9 D
  2.   /* USER CODE BEGIN WHILE */
    ( ^7 O7 s/ e8 M% K; S: d6 ~- Q
  3.   while (1)
      R$ y) u2 t- v
  4.   {
    6 W+ E* G4 v9 t6 U6 N- m
  5.       
    7 K5 o4 p2 N: C8 P5 B- y8 C
  6.       if(GPIO_PIN_SET == HAL_GPIO_ReadPin(LED11_GPIO_Port,LED11_Pin))
    ( e" E3 }( W5 {  \0 h
  7.       {* r6 w0 \  @, Z6 ^3 g" q3 d6 @5 S
  8.           task_3();1 y" G5 @7 G+ C5 ]6 g# f
  9.       }
    $ c7 A+ c  S- K
  10.       else! D6 n' t% q3 r
  11.       {  p3 p* N2 _8 h
  12.         MC_StopMotor1();
    8 @  G% Q5 {9 q) k7 r2 K4 V, R
  13.       }      7 }% w& @5 L% Y8 ?6 D. g
  14.   /* USER CODE END WHILE */: p; N" D% v" d5 G
复制代码
实验现象:
任务三速度变化截图.png
2 b0 O3 }6 }- {$ e' N1 r0 @) a/ f4 @
通过速度变化趋势可以看到任务成功实现了,我对比了PPT的预期结果图,有一些差距。当速度设置为3000rpm时,speed reference并没有跟随代码变为3000。另外,我做了延迟清除错误信息,所以在图中可以看到一截零速状态。
# {$ {+ u& I" V+ \5 o
( i6 E5 o) z( W: ?& x- h
好了,任务3完成。
---------------------------------------------------------
现在分享一个开放性实验,旋钮控制转速,我把这个任务定为任务4吧,用旋钮来控制电机转速我觉得才是真正的一个电机控制系统。
由于SDK中并没有考虑旋钮ADC的初始化,所以如果要使用旋钮电位器首先要通过cubemx对ADC进行初始化,在我的第二篇帖子中已经讲过关于套件的硬件资源,也知道了旋钮电位器连接的是PB1引脚。
用户1.png
创建全局变量:
  1. int32_t Speed_Adc = 0;
    5 J& p3 M5 l- x! Q: ?
  2. int32_t Speed_ref = 0;
    + W/ |' D0 c9 i9 S3 x- J: a7 w
  3. PWMC_Handle_t * MC_SPEED_REF;5 @- C5 S, E/ }) D3 H; g
复制代码
任务4代码:
  1. void task_4(void)' ]1 d4 f4 h/ Q1 R. P
  2. {
    5 {/ i2 E( b* Z& p0 h- J! s
  3.     Speed_Adc = R3_1_F30X_ExecRegularConv(MC_SPEED_REF,ADC_CHANNEL_12);
    . i8 P5 q; X0 `4 R& K3 x
  4.     Speed_ref = (15500*Speed_Adc)>>16;
    7 K3 q' c6 T, |0 ~
  5.     if(Speed_ref > 0)9 Y# c" u6 u9 c* K
  6.     {9 W# U: V% D2 L- Z" {+ T
  7.         MC_ProgramSpeedRampMotor1((Speed_ref+1500)/6,1000);
    & b4 J, Z+ C4 m
  8.         MC_StartMotor1();( Z. {: x1 z* b+ P7 h0 F9 e; s
  9.     }1 J' ]; c: |6 z+ s' ?$ P  Q
  10.     else
    9 l/ c9 U: R5 w4 p. X
  11.     {3 `; s- n! T& V) N  h2 [$ i" a
  12.         MC_StopMotor1();
    ( u  @) i. w% p* O9 f% S
  13.     }
    , y; A" \- q& H+ N+ b2 d
  14.     HAL_Delay(100);5 ]! m6 E& T, J- T
  15. }
复制代码
主函数代码:0 d5 q; c! ]- Q- X1 ?
  1. /* Initialize interrupts */
    ( ~' U6 L, i- w, G6 U
  2.   MX_NVIC_Init();
    ' ?& ~; Z& t0 l
  3.   /* USER CODE BEGIN 2 */; Q8 Z, K# v4 l. s0 T% _
  4.   MC_SPEED_REF = &PWM_Handle_M1._Super;
    ( B% a3 t' t# f+ |, K; G  w  a0 i8 Q. R
  5.   /* USER CODE END 2 */0 ]0 C8 f( S" |7 @) Z# ~0 r& k

  6. 9 c1 V8 V# Z- |/ Z
  7.   /* Infinite loop */
    7 ^- \3 C% E( |+ s* B
  8.   /* USER CODE BEGIN WHILE */
    / [( \; X( ?" K9 |
  9.   while (1), z9 E+ a+ s/ Q) D
  10.   {
    7 y6 N* V  _0 |
  11. " u$ n4 r9 `6 L6 s
  12.       if(GPIO_PIN_SET == HAL_GPIO_ReadPin(LED11_GPIO_Port,LED11_Pin))/ W. T' s6 h( y+ s' _
  13.       {/ k5 u7 [6 t. B6 S" F* K) X% _2 U0 g
  14.           task_4();
    & {. a6 o0 `2 N- N5 i  K' e4 Z6 C
  15.       }1 f" B0 _) ~+ \
  16.       else
    + J2 }3 [) G( ]5 ~& ]
  17.       {; R( M/ O9 g8 C, U, M) P% U' c
  18.           MC_ProgramSpeedRampMotor1(0,0);: ?* R$ A6 d0 w1 J0 M" f: K0 N
  19.           MC_StopMotor1();
    7 o2 R" c1 q4 \: L0 R9 M
  20.       }  H/ n+ x1 G# Z
  21.   /* USER CODE END WHILE */
    ; J% c% J% f  g1 `1 A
  22. 8 B( \% ~( B! n4 Z/ t; I
  23.   /* USER CODE BEGIN 3 */
    - v5 O9 W$ w5 O

  24. " P% J% G* E' R. E3 A$ f
  25.   }0 X5 {" \, Z& |% I
  26.   /* USER CODE END 3 */3 b. R9 Y. o: y
复制代码
在这里稍微解释一下代码:
Speed_Adc是存储ADC采样值的变量,Speed_ref变量通过ADC采样值转化为速度设定值,MC_SPEED_REF是一个指针变量,用于获取ADC初始化设置,R3_1_F30X_ExecRegularConv这个函数在r3_1_f30x_pwm_curr_fdbk,c这个文件中,用于处理规则ADC采样。速度换算这里可以没什么说的。速度设定的时候加1500偏移是有原因的,当设定速度过低的时候电机系统根本不能正常启动,这是我尝试设置的时候所能达到的最低启动速度。
/ `' t$ Z$ c+ k
实验现象:
旋钮调速转速跟踪波形.png
从实验结果看来,这份代码默认速度PID能很好的跟踪给定转速。
我发现一个问题,代码里面在电机运行结束之后有些变量好像没有清零,这个问题留到后面在研究吧。

( p3 X- V1 ?! q6 J4 x0 x
本帖两个任务分享就到这里,欢迎大家留言讨论。: L6 Q! t8 b; M5 A% J: w, o3 w
, k0 L" w* ]! `2 i+ ?
+ N6 g( _% q6 i( s4 E9 |

' n5 [6 \" ~: ]! v$ k) U- q, u
8 V: A- J& v9 ^$ k# B8 N
1 收藏 2 评论118 发布时间:2018-9-2 19:17

举报

118个回答
子曰好人 回答时间:2020-4-15 09:28:07
ysx584085668 发表于 2020-4-14 23:23+ \! o) O0 S. i" J* n: K( v- o
太感谢了,我发邮件给你看吧
6 L$ R5 U8 C$ [
看了你发的邮件,新版本的MCSDK生成的代码没有留ADC规则转换的函数接口,可能需要你自己去写了,我把我这边生成的文件发你一份参考吧* q- N0 c% y4 c8 ~: s% `- u
r3_1_f30x_pwm_curr_fdbk.zip (16.66 KB, 下载次数: 10)
passby328 回答时间:2018-11-6 11:04:29
子曰好人 发表于 2018-11-6 09:358 e9 V2 g' r5 i, @- n
SDK5.1.3生成的代码里面没有regular_conversion_manager.c这个文件,5.2.0新增了。获取ADC值的代码是几乎 ...
" m) ?9 G; o6 Z/ Z# q) k8 v
1.我之前参考您的函数,如果一直不断在执行转换,会影响电机库的控制时序导致无法开机,后来改为500ms一次,就没有问题。后来检查regular_conversion_manager.c中的内容,发现用户ADC的转换应该是电机库的状态机在调度的,如果连续不断转换或者没有走相应的接口估计会有问题。0 @2 N; s) @6 R1 O, E  V3 d
2.电机Workbench里面有设置OCP参数,看了原理图应该是通过体验板上面的L6230的内置比较器以及SMT32片内的ADC实现的,但是实际中的程序并没有提供类似的功能。后来查看了代码,OCP保护是通过L6230产生的FO信号进行处理的,不知道我说的是否有偏差,还请指教。
zhdzhd 回答时间:2018-9-2 22:27:32
代码规整,有功底,佩服!+ j' {0 N, g4 b! G! Y0 P7 z% s
大佬也会有纰漏啊/ F5 h& T# E% m

) Q* _8 i0 m/ A4 E7 _" W( L6 I/* Infinite loop */
( N7 y& p- p" o! B9 B  /* USER CODE BEGIN WHILE */
" V& k: {$ _" D( \  while (1)8 w) o4 J. R0 G) P
  {
! c% U# r  M, L& ^+ n      9 W) A% X/ G; v, t- s: a
      if(GPIO_PIN_SET == HAL_GPIO_ReadPin(LED11_GPIO_Port,LED11_Pin))
0 J1 Z- F, O1 s      {$ z2 T2 n: }) s
          task_5(); ------>task_3();
" B* F2 d& V  j: M  i( q3 i      }
- Y3 C- ]  z) |+ ~      else
' c6 n% `( o  G# S7 t- ]* y      {7 P  V0 D. @% l& G7 M
        MC_StopMotor1();
6 Q  F' @% K. m( m" h      }      
) P; q0 H% L# |  /* USER CODE END WHILE */
子曰好人 回答时间:2018-9-2 22:36:27
zhdzhd-174422 发表于 2018-9-2 22:271 E% ^; o8 ?4 `: \) `7 D; f
代码规整,有功底,佩服!$ d  {8 t* }5 w/ n6 o+ u
大佬也会有纰漏啊

; F; D% Y$ s" s, z不好意思,感谢指正
STM1024 回答时间:2018-9-3 10:24:43
哈哈,和你观点一样,很多故障报警,都是报的speed feedback,我在测试的时候,连堵转都试过,原本以为是电流过大报警,但没想到居然还是speed feedback故障
子曰好人 回答时间:2018-9-3 10:45:56
stm1024 发表于 2018-9-3 10:24
. e, {4 l% q9 e8 d% _哈哈,和你观点一样,很多故障报警,都是报的speed feedback,我在测试的时候,连堵转都试过,原本以为是电 ...

$ g( c! ]9 R% h( E! F去研究一下电机库生成的故障触发机制代码,也许就能明白了,搞清楚是怎么回事之后就能自定义故障报警了
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()?( B1 Z9 d8 j; o5 C& Z: i3 _; m5 k  P
子曰好人 回答时间:2018-9-4 22:54:20
LT-386596 发表于 2018-9-4 18:38
7 J  E2 n$ z9 g5 t! M! _Speed_Adc = R3_1_F30X_ExecRegularConv(MC_SPEED_REF,ADC_CHANNEL_12); 5.2.0 找不到  R3_1_F30X_ExecRegu ...

7 Z" ~' h& [5 x- W3 U2 _5 Y3 W! B在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
/ \3 ?/ A$ z6 }VR连接的脚感觉像是PB1,从电路图上来看.
' ?! m" X! |/ y& K
手误写错了,已更正
花落莫相离 回答时间: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& i; t. O1 v) o! Y; i* x; f+ P
楼主,我不太懂Speed_ref = (15500*Speed_Adc)>>16;这段程序中15500的作用时什么?
) N# R4 r! [! h* Y* m, d, B+ 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
, G( w; A' z6 w( |' A大神,不知道你有没有注意到有一个小细节,这个USB必须要插在主控板上整个程序好像才能运行,然后不插USB的 ...
1 V/ f4 @5 {; @. T$ Z; a
没遇到过,我的一直是正常的呀,没有USB连接也能正常运行
晴空 回答时间:2018-10-29 15:53:32
学习了  哈哈
花落莫相离 回答时间:2018-10-31 13:51:43
子曰好人 发表于 2018-10-26 09:16
7 g' B% q7 }4 j* H/ t15500是电机能达到的最大转速,Speed_Adc的最大值是4096,ADC采样值和速度参考值的换算方式为:(Spped_re ...

( \$ u- d7 x$ G+ |1 O/ Z7 Y多谢楼主解释了。

所属标签

相似分享

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