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

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

[复制链接]
子曰好人 发布时间:2018-9-2 19:17
本帖最后由 子曰好人 于 2018-9-5 08:55 编辑
3 D5 k3 ~: K* F3 I1 I# \- R) N, b8 R' \9 s0 |' ^+ M* V2 m
继续做实验,任务3和旋钮控制转速。
首先来看看任务3的要求:
任务3要求.png
这个可通过代码实现也可以通过上位机实现,已经有坛友做过这样的事情了。通过上位机做就是快速拨弄圆盘,这样系统不能在短时间内反转,造成观测器不能收敛,触发速度反馈错误报警,其实我个人觉得这里也是有过流报警存在的,这就看系统优先响应哪一个报警了。
我这里通过代码来实现task3。
任务3代码:
  1. void task_3(void)
    6 N4 D' ?, q0 o3 x+ C
  2. {( r( y. c' K, |% L( H0 H3 W
  3.     MC_ProgramSpeedRampMotor1(-3000/6,1000); //设置-3000rpm的转速,在一秒之内达到
    2 i, `8 ~) s: b
  4.     MC_StartMotor1();       //启动电机( r9 B" k' Y/ i4 b" m6 |' X8 N
  5.     HAL_Delay(500);         //运行500ms& `  g8 A: S+ G9 p( V9 p& ^; r
  6.     while(RUN != MC_GetSTMStateMotor1()); //等待电机处于运行状态,可有可无
    # L& y2 o. w9 w% O# \# d
  7.     MC_ProgramSpeedRampMotor1(3000/6,1000); //切换到3000rpm转速6 C0 @( |. Y. _1 d( {$ R. w, N
  8.     MC_StartMotor1();       //启动电机
    - G  \0 \: T, a
  9.     while(MC_SPEED_FDBK != STM_GetFaultState(&STM[M1])); //等待错误触发
    6 t8 X) C7 T0 `# ?5 y7 u
  10.     HAL_Delay(1000);    //延时一秒,方便可以在上位机上看见错误是否发生
    ( [( Z. R) H& P8 r
  11.     MC_AcknowledgeFaultMotor1();    //清除错误
      S- F4 o/ b! u8 U8 ~
  12.     HAL_Delay(100);     //延时0.1秒
    + q# g- I# t  I  C
  13.     MC_ProgramSpeedRampMotor1(MC_GetLastRampFinalSpeedMotor1(),1000);   //重新设置上一次速度值/ R( a4 N3 W+ e0 h
  14.     MC_StartMotor1();   //启动电机3 [7 J2 m3 ?$ y2 x- y4 S' w
  15.     HAL_Delay(5000);    //运行5秒
    ( j- u8 @: ?# W" B# e
  16.     MC_StopMotor1();    //停机
    * n1 i. J' B/ E0 u- a7 C
  17.     HAL_GPIO_WritePin(LED11_GPIO_Port,LED11_Pin,GPIO_PIN_RESET); //拉低LED引脚,表示任务结束
      c6 R* ~  Z$ O. Q
  18. }
    / g1 E4 o4 a0 p3 e* m8 h
复制代码
主函数代码:
  1. /* Infinite loop */* T. [1 ~+ s: U$ M: K8 e( l
  2.   /* USER CODE BEGIN WHILE */( Q7 E. ]  e9 D+ R# e6 _. }0 i" S
  3.   while (1)
    % L1 l/ \6 \0 {; e7 s; G/ t
  4.   {/ T# |3 X, e, L& d! H
  5.       # e2 d- ?( t9 Q) t
  6.       if(GPIO_PIN_SET == HAL_GPIO_ReadPin(LED11_GPIO_Port,LED11_Pin))
    ; R( S" q. ]& t: n
  7.       {( E1 ^  m2 P( Y, t
  8.           task_3();/ T9 ~1 Z# j; h0 G4 n9 B; m
  9.       }9 L1 m! I4 R) [1 r! r6 }. x; y0 m
  10.       else
    7 M1 r# g; P2 v4 B
  11.       {
    3 I8 `7 l3 W5 ~
  12.         MC_StopMotor1();( Z- t, ]3 c: P3 \3 |: Y
  13.       }      1 r$ |4 c6 [) o' N8 u& @
  14.   /* USER CODE END WHILE */
    ) F( i. F" k+ s
复制代码
实验现象:
任务三速度变化截图.png + y9 Z) b( ^; u0 J
通过速度变化趋势可以看到任务成功实现了,我对比了PPT的预期结果图,有一些差距。当速度设置为3000rpm时,speed reference并没有跟随代码变为3000。另外,我做了延迟清除错误信息,所以在图中可以看到一截零速状态。
9 T' @; e6 n9 D0 F+ f
. K9 m0 m- p  \8 }& Z' f
好了,任务3完成。
---------------------------------------------------------
现在分享一个开放性实验,旋钮控制转速,我把这个任务定为任务4吧,用旋钮来控制电机转速我觉得才是真正的一个电机控制系统。
由于SDK中并没有考虑旋钮ADC的初始化,所以如果要使用旋钮电位器首先要通过cubemx对ADC进行初始化,在我的第二篇帖子中已经讲过关于套件的硬件资源,也知道了旋钮电位器连接的是PB1引脚。
用户1.png
创建全局变量:
  1. int32_t Speed_Adc = 0;
    ( R5 J0 f9 V3 Q" n' L/ s
  2. int32_t Speed_ref = 0;% q1 ~/ x, K+ q% G& |. d+ t6 d
  3. PWMC_Handle_t * MC_SPEED_REF;
    ! L7 t  Y1 A# C/ T/ A9 K5 _
复制代码
任务4代码:
  1. void task_4(void)
    3 g9 t! O# ^% K0 o. u% q
  2. {
    $ E) f6 z7 g' e# \0 ^
  3.     Speed_Adc = R3_1_F30X_ExecRegularConv(MC_SPEED_REF,ADC_CHANNEL_12);
    3 J& R1 {' @, I
  4.     Speed_ref = (15500*Speed_Adc)>>16;. m. m2 v. q7 `: Q
  5.     if(Speed_ref > 0)( N4 U' [0 _+ F8 k8 E* U
  6.     {
    3 b$ Q! p* A' ?2 X, Y9 `7 v
  7.         MC_ProgramSpeedRampMotor1((Speed_ref+1500)/6,1000);* Q8 K  e; w# B  `/ J0 x" G
  8.         MC_StartMotor1();  Q5 J: V( ]+ |, g0 w+ B9 i6 T+ ^
  9.     }& g$ X$ M* ^: t# q/ q0 T; J
  10.     else3 M; M+ q8 x# w
  11.     {$ s9 [6 E+ @) n, s3 P. b( R& s
  12.         MC_StopMotor1();0 b( W4 z$ w; _9 O- F
  13.     }
    9 q/ _) C) A2 V) _
  14.     HAL_Delay(100);6 v2 U& T* I2 s- l$ W
  15. }
复制代码
主函数代码:6 ^3 A/ I& E+ _! q. y( H
  1. /* Initialize interrupts */
    ' J% o  Q) m+ U* N
  2.   MX_NVIC_Init();; d. H# H; m# y1 O+ ~( H
  3.   /* USER CODE BEGIN 2 */, f8 a  y/ p5 A- ^( r8 m, q
  4.   MC_SPEED_REF = &PWM_Handle_M1._Super;& l1 @% X; x4 }
  5.   /* USER CODE END 2 */4 R0 a! n& o% w7 g- U( S

  6. % R/ d( ~9 w  z- g3 V7 F3 c
  7.   /* Infinite loop */0 c7 W7 y5 N. T, B
  8.   /* USER CODE BEGIN WHILE */
    . W8 E0 I# F2 m2 @
  9.   while (1)
    6 c. u* ?  ?& _1 z' c) l
  10.   {1 B% a" [3 j, ]4 d2 m# m
  11. . H6 ?3 G4 H# ?& \. C3 M
  12.       if(GPIO_PIN_SET == HAL_GPIO_ReadPin(LED11_GPIO_Port,LED11_Pin))+ m# `- M# I0 u4 \9 W9 a
  13.       {4 x, h# b, G1 r8 E2 D8 ?8 ?
  14.           task_4();
    ; O1 O4 [5 }7 i0 V; M
  15.       }. Q7 f: K" E* [) ~1 v0 @. U
  16.       else
    6 i9 _% I( q3 B* _; k2 n
  17.       {  P& @7 E1 p6 ~, a  u5 p
  18.           MC_ProgramSpeedRampMotor1(0,0);
    ) h) x1 z* G" h, E9 m. }* s
  19.           MC_StopMotor1();
    ' `5 v' F/ e( ?! Q8 v
  20.       }% e+ \. R1 E# J( ?8 @
  21.   /* USER CODE END WHILE */
    2 I9 H  `: A8 x5 q. w; r5 w* T# v5 i

  22. , Q: n- B' I8 \, I% j: O
  23.   /* USER CODE BEGIN 3 */
    ; y, q3 z/ M6 f0 p4 x
  24. ' [' @  |' C- z! C- ^6 i# {# |
  25.   }
    5 {$ V- x5 s1 P# z9 V" Y
  26.   /* USER CODE END 3 */) G6 s' D9 U% A6 k" _( C- \' s
复制代码
在这里稍微解释一下代码:
Speed_Adc是存储ADC采样值的变量,Speed_ref变量通过ADC采样值转化为速度设定值,MC_SPEED_REF是一个指针变量,用于获取ADC初始化设置,R3_1_F30X_ExecRegularConv这个函数在r3_1_f30x_pwm_curr_fdbk,c这个文件中,用于处理规则ADC采样。速度换算这里可以没什么说的。速度设定的时候加1500偏移是有原因的,当设定速度过低的时候电机系统根本不能正常启动,这是我尝试设置的时候所能达到的最低启动速度。

3 l" v5 k( R  o. c- K2 N# X
实验现象:
旋钮调速转速跟踪波形.png
从实验结果看来,这份代码默认速度PID能很好的跟踪给定转速。
我发现一个问题,代码里面在电机运行结束之后有些变量好像没有清零,这个问题留到后面在研究吧。
* e. ^9 b- ]3 p, ^6 `: x8 ~; ]" V# n
本帖两个任务分享就到这里,欢迎大家留言讨论。
8 R, X/ Q$ c$ @) ~

+ \, l7 B: F( U# |) l. }9 J) c. C
4 y: t( m; j& a& H) O. g
0 F! d7 J& ~7 @3 z
( t$ \: c* E0 i: ~
1 收藏 2 评论118 发布时间:2018-9-2 19:17

举报

118个回答
子曰好人 回答时间:2020-4-15 09:28:07
ysx584085668 发表于 2020-4-14 23:23
. o0 @# q9 n7 K% q( }; |太感谢了,我发邮件给你看吧
" P  {- U; O. h) H) S& i/ \: Q
看了你发的邮件,新版本的MCSDK生成的代码没有留ADC规则转换的函数接口,可能需要你自己去写了,我把我这边生成的文件发你一份参考吧: Y# G5 r) s& G  d- }! V
r3_1_f30x_pwm_curr_fdbk.zip (16.66 KB, 下载次数: 10)
passby328 回答时间:2018-11-6 11:04:29
子曰好人 发表于 2018-11-6 09:35* i; d* }, w- F9 f
SDK5.1.3生成的代码里面没有regular_conversion_manager.c这个文件,5.2.0新增了。获取ADC值的代码是几乎 ...

% s& L+ j! }% i3 |1.我之前参考您的函数,如果一直不断在执行转换,会影响电机库的控制时序导致无法开机,后来改为500ms一次,就没有问题。后来检查regular_conversion_manager.c中的内容,发现用户ADC的转换应该是电机库的状态机在调度的,如果连续不断转换或者没有走相应的接口估计会有问题。7 \$ ?% B1 s1 J1 b( V$ s1 w2 m! m
2.电机Workbench里面有设置OCP参数,看了原理图应该是通过体验板上面的L6230的内置比较器以及SMT32片内的ADC实现的,但是实际中的程序并没有提供类似的功能。后来查看了代码,OCP保护是通过L6230产生的FO信号进行处理的,不知道我说的是否有偏差,还请指教。
zhdzhd 回答时间:2018-9-2 22:27:32
代码规整,有功底,佩服!- y: Z3 m2 f4 J+ U3 Z
大佬也会有纰漏啊
7 R% ], P6 o( H  W
- o9 s: H4 C1 n4 V/* Infinite loop */" B  K, J& \# o& E' L& S; a8 W1 u
  /* USER CODE BEGIN WHILE */3 e% O+ ~( Y2 W# E
  while (1)
! K2 k0 l8 [# k- e1 s* R9 H  {
# o# Q: r0 k* ^$ n/ J) g      
5 Q( U: A5 z) v      if(GPIO_PIN_SET == HAL_GPIO_ReadPin(LED11_GPIO_Port,LED11_Pin))
4 u2 H' B" r* G* G7 |0 B      {# [, V8 W/ M+ x+ C8 r  E& T% O8 P
          task_5(); ------>task_3();8 F' n7 I+ @- n& e
      }
2 L/ J: Y, |6 L; E3 _4 @      else, W+ T3 O: B$ q* A
      {
8 _. [! W+ \  ^7 D! i5 k        MC_StopMotor1();
/ ]- a; S9 o* z6 ~- _      }      % @/ \% P3 a% ~- i8 n( f5 Q
  /* USER CODE END WHILE */
子曰好人 回答时间:2018-9-2 22:36:27
zhdzhd-174422 发表于 2018-9-2 22:27
% q3 H" Q) X( U9 m2 h1 e6 \/ y- u代码规整,有功底,佩服!
8 B5 u1 g0 N% T2 L; y大佬也会有纰漏啊
" x& O" G4 F- A! J
不好意思,感谢指正
STM1024 回答时间:2018-9-3 10:24:43
哈哈,和你观点一样,很多故障报警,都是报的speed feedback,我在测试的时候,连堵转都试过,原本以为是电流过大报警,但没想到居然还是speed feedback故障
子曰好人 回答时间:2018-9-3 10:45:56
stm1024 发表于 2018-9-3 10:24
: y0 k' r' i) H2 S! a" D哈哈,和你观点一样,很多故障报警,都是报的speed feedback,我在测试的时候,连堵转都试过,原本以为是电 ...
' T& N- p. s/ D# q& J( y! L5 |- V
去研究一下电机库生成的故障触发机制代码,也许就能明白了,搞清楚是怎么回事之后就能自定义故障报警了
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 ?+ b: U! W# i# Z5 H& M
子曰好人 回答时间:2018-9-4 22:54:20
LT-386596 发表于 2018-9-4 18:38& D: m$ N- T# Z1 `3 \2 g! ]7 h
Speed_Adc = R3_1_F30X_ExecRegularConv(MC_SPEED_REF,ADC_CHANNEL_12); 5.2.0 找不到  R3_1_F30X_ExecRegu ...
4 k/ N5 g0 s! s# {1 V0 Y
在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:279 n5 I2 O* b9 Z7 P- }/ X
VR连接的脚感觉像是PB1,从电路图上来看.

1 i; Y( W5 D/ |8 k, B手误写错了,已更正
花落莫相离 回答时间: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
4 U+ C# q# F1 ]- }楼主,我不太懂Speed_ref = (15500*Speed_Adc)>>16;这段程序中15500的作用时什么?

% C; D2 y9 M3 U+ e) o6 `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
& g0 P3 _0 U  y4 [4 @/ ]大神,不知道你有没有注意到有一个小细节,这个USB必须要插在主控板上整个程序好像才能运行,然后不插USB的 ...

* I- d/ s8 c/ m2 m' `+ c$ Y没遇到过,我的一直是正常的呀,没有USB连接也能正常运行
晴空 回答时间:2018-10-29 15:53:32
学习了  哈哈
花落莫相离 回答时间:2018-10-31 13:51:43
子曰好人 发表于 2018-10-26 09:16
0 W. W. @8 }8 I15500是电机能达到的最大转速,Speed_Adc的最大值是4096,ADC采样值和速度参考值的换算方式为:(Spped_re ...
9 I+ q. C6 D: J1 ?, T
多谢楼主解释了。

所属标签

相似分享

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