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

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

[复制链接]
子曰好人 发布时间:2018-9-2 19:17
本帖最后由 子曰好人 于 2018-9-5 08:55 编辑
9 E5 g0 Q5 M  a# F! T, ~0 X/ U# v; [" U' l& V( b
继续做实验,任务3和旋钮控制转速。
首先来看看任务3的要求:
任务3要求.png
这个可通过代码实现也可以通过上位机实现,已经有坛友做过这样的事情了。通过上位机做就是快速拨弄圆盘,这样系统不能在短时间内反转,造成观测器不能收敛,触发速度反馈错误报警,其实我个人觉得这里也是有过流报警存在的,这就看系统优先响应哪一个报警了。
我这里通过代码来实现task3。
任务3代码:
  1. void task_3(void)3 Q# L! V. ?* }/ j- Z# g0 s& q% v
  2. {+ w+ ?0 o2 i" ]( _
  3.     MC_ProgramSpeedRampMotor1(-3000/6,1000); //设置-3000rpm的转速,在一秒之内达到4 r6 O$ T8 v% }+ u1 h
  4.     MC_StartMotor1();       //启动电机
    * B9 L# t- }: S, f7 H) a  |6 d: q! ~
  5.     HAL_Delay(500);         //运行500ms; o: l) Q  K: ?5 k( d
  6.     while(RUN != MC_GetSTMStateMotor1()); //等待电机处于运行状态,可有可无# T& L  i& `+ j. u5 M
  7.     MC_ProgramSpeedRampMotor1(3000/6,1000); //切换到3000rpm转速
    " d8 x' _! V$ |! u+ W% J. V
  8.     MC_StartMotor1();       //启动电机
    , b8 k$ w; q6 m8 _' R
  9.     while(MC_SPEED_FDBK != STM_GetFaultState(&STM[M1])); //等待错误触发( i& B) r( F3 S* y+ }: R
  10.     HAL_Delay(1000);    //延时一秒,方便可以在上位机上看见错误是否发生% b" K8 c  r. x5 C3 F9 h
  11.     MC_AcknowledgeFaultMotor1();    //清除错误
    6 }; e) ^: O' u& j
  12.     HAL_Delay(100);     //延时0.1秒
    7 e0 k' ]  b3 G/ u
  13.     MC_ProgramSpeedRampMotor1(MC_GetLastRampFinalSpeedMotor1(),1000);   //重新设置上一次速度值
    " h8 X' R; |, F+ |; J" l
  14.     MC_StartMotor1();   //启动电机+ X" v8 _- M4 F8 n/ n2 Q5 @& F
  15.     HAL_Delay(5000);    //运行5秒
    9 h1 O$ \$ h) W# F* ]5 q
  16.     MC_StopMotor1();    //停机
    0 a% B) K0 z  S4 S6 f4 N5 |7 L
  17.     HAL_GPIO_WritePin(LED11_GPIO_Port,LED11_Pin,GPIO_PIN_RESET); //拉低LED引脚,表示任务结束" p1 [" f# N7 o7 e
  18. }1 X# z2 U* h7 W$ T8 X( c
复制代码
主函数代码:
  1. /* Infinite loop */8 d1 Y& ^6 Q! I' z) ^
  2.   /* USER CODE BEGIN WHILE */
    " G1 R6 \' w$ `& p
  3.   while (1)" \* s; m& @5 a( ^' {# M2 k
  4.   {
    # y! J1 v; D! i+ h% Y0 D# I
  5.       ! K% Z5 X( R0 |% z
  6.       if(GPIO_PIN_SET == HAL_GPIO_ReadPin(LED11_GPIO_Port,LED11_Pin))
    ( |- ~2 M6 }4 b- Z
  7.       {& I% y, o' Y. a3 M
  8.           task_3();7 R' ]/ Y( Q+ U  F
  9.       }( y" L4 d( J3 y' X- @3 ^
  10.       else" W2 o  n0 Y7 @  }# \
  11.       {( Z' B( A/ @9 q5 H8 v! {
  12.         MC_StopMotor1();
    * S& A9 U, t  x
  13.       }      
    - F  g- a( }4 c, h* v
  14.   /* USER CODE END WHILE */1 j( Z- ~4 e) R" [0 C9 N
复制代码
实验现象:
任务三速度变化截图.png
9 U' d# t* o' L  }' R% n
通过速度变化趋势可以看到任务成功实现了,我对比了PPT的预期结果图,有一些差距。当速度设置为3000rpm时,speed reference并没有跟随代码变为3000。另外,我做了延迟清除错误信息,所以在图中可以看到一截零速状态。

' Z, g- E5 A4 X9 o  O
4 w/ D# V* `9 N2 E1 ~1 H
好了,任务3完成。
---------------------------------------------------------
现在分享一个开放性实验,旋钮控制转速,我把这个任务定为任务4吧,用旋钮来控制电机转速我觉得才是真正的一个电机控制系统。
由于SDK中并没有考虑旋钮ADC的初始化,所以如果要使用旋钮电位器首先要通过cubemx对ADC进行初始化,在我的第二篇帖子中已经讲过关于套件的硬件资源,也知道了旋钮电位器连接的是PB1引脚。
用户1.png
创建全局变量:
  1. int32_t Speed_Adc = 0;, r3 [( x) X( v/ D: S  Y
  2. int32_t Speed_ref = 0;8 X5 ?$ d- g/ M7 G9 v
  3. PWMC_Handle_t * MC_SPEED_REF;
    : ^7 q/ g% X$ U  L
复制代码
任务4代码:
  1. void task_4(void)  C  U- ?) u) O, v
  2. {
    % ]/ J$ b# Z% c* M3 A/ c  \; b6 r, N
  3.     Speed_Adc = R3_1_F30X_ExecRegularConv(MC_SPEED_REF,ADC_CHANNEL_12);/ Y& \: S" \& j" |( E/ U
  4.     Speed_ref = (15500*Speed_Adc)>>16;3 k! y$ i5 h& W9 E7 U+ \
  5.     if(Speed_ref > 0)' A& a5 {5 z7 ?
  6.     {, e4 u( [5 @, W9 x- N
  7.         MC_ProgramSpeedRampMotor1((Speed_ref+1500)/6,1000);- i7 C  o/ i8 Q- D- e" ^& u/ u( z- F
  8.         MC_StartMotor1();0 O* i# E6 y% S1 S' [) g2 f/ c
  9.     }/ r' @' K1 y  w2 b. ]3 z
  10.     else9 r& l2 {2 f1 `. i, G# X( E" F$ [
  11.     {
    ; ~3 q8 W5 Q7 G' ~7 F
  12.         MC_StopMotor1();
    ( M* L) Q- `4 ]5 y4 p
  13.     }8 c' V/ O7 h( U) H' |/ X1 w
  14.     HAL_Delay(100);
    0 U, J/ t0 `( M5 b5 [6 z+ y
  15. }
复制代码
主函数代码:
9 M" E$ K/ v+ ?# ?) \/ D0 k) T
  1. /* Initialize interrupts */- a" w6 [" \1 p, [0 o
  2.   MX_NVIC_Init();
    ) R; d# X5 E# r) {
  3.   /* USER CODE BEGIN 2 */# _. Z) \- e0 a; ~- a/ A8 |
  4.   MC_SPEED_REF = &PWM_Handle_M1._Super;
    ! S  e; M) W' r; J0 [8 J; E- I' U
  5.   /* USER CODE END 2 */
    0 X: N* q7 v0 y

  6. ' e5 r, ^+ O4 D+ q! I) s0 o4 b6 S
  7.   /* Infinite loop */& z& E3 _8 b; e* Y2 Y$ R" p6 r
  8.   /* USER CODE BEGIN WHILE */7 r3 O' Q5 x* g
  9.   while (1)
    7 D; b2 E& L7 K% b& s# i* q
  10.   {
    ' ^+ h/ t$ r" `$ M7 @+ o6 u" k! j
  11. 5 O2 _0 K9 P% \6 j5 X
  12.       if(GPIO_PIN_SET == HAL_GPIO_ReadPin(LED11_GPIO_Port,LED11_Pin))# B9 H  ~+ J5 c  l* ~6 `" \
  13.       {
    3 ]; b  J4 ?5 z! r! L4 F+ o3 J- ]
  14.           task_4();& v1 y6 k% m5 i' |% o, X  Y6 j) ?
  15.       }* t. \$ C$ r! [: A, J* K! E- l
  16.       else
    2 n5 b/ a; G3 m7 M8 s2 B
  17.       {
    ' z2 U( G3 c0 d- y4 u7 f
  18.           MC_ProgramSpeedRampMotor1(0,0);
    $ u7 Y. s4 E1 O2 C. P$ ?" n
  19.           MC_StopMotor1();8 D, R+ V# M, y! B& w6 I# T' {
  20.       }
    % B; C, k% ]5 v* }* w7 j: Y7 D
  21.   /* USER CODE END WHILE */8 c' G5 y; o" s, b

  22.   C# \' ?/ f( m2 B4 J
  23.   /* USER CODE BEGIN 3 */
    ! j. Z  Y( H2 H

  24. * S3 F, X9 _1 X; j; V
  25.   }* D; ^- y. J$ }% m5 h$ ?6 _0 c( Y
  26.   /* USER CODE END 3 */
    * t* x$ x2 o& P5 e) w1 C' U
复制代码
在这里稍微解释一下代码:
Speed_Adc是存储ADC采样值的变量,Speed_ref变量通过ADC采样值转化为速度设定值,MC_SPEED_REF是一个指针变量,用于获取ADC初始化设置,R3_1_F30X_ExecRegularConv这个函数在r3_1_f30x_pwm_curr_fdbk,c这个文件中,用于处理规则ADC采样。速度换算这里可以没什么说的。速度设定的时候加1500偏移是有原因的,当设定速度过低的时候电机系统根本不能正常启动,这是我尝试设置的时候所能达到的最低启动速度。
- z0 T9 x4 A5 z, `
实验现象:
旋钮调速转速跟踪波形.png
从实验结果看来,这份代码默认速度PID能很好的跟踪给定转速。
我发现一个问题,代码里面在电机运行结束之后有些变量好像没有清零,这个问题留到后面在研究吧。

& i. m; T! Q. e, W* C0 ^4 l
本帖两个任务分享就到这里,欢迎大家留言讨论。
; Z; `" @% r. e  d8 g$ q7 a, H

9 ^8 E4 Z" [) O& _
) M9 @8 T1 I) r/ X( ]; P' Z- X  n
5 R. p# [/ b% W/ C' U5 x
+ O0 w  K1 `6 X" B4 }6 }; W( N
1 收藏 2 评论118 发布时间:2018-9-2 19:17

举报

118个回答
子曰好人 回答时间:2020-4-15 09:28:07
ysx584085668 发表于 2020-4-14 23:23
' p1 A. [7 T4 w" J0 i( O9 _太感谢了,我发邮件给你看吧
+ n$ w# X1 d' \, H& i9 d+ K$ m
看了你发的邮件,新版本的MCSDK生成的代码没有留ADC规则转换的函数接口,可能需要你自己去写了,我把我这边生成的文件发你一份参考吧
5 H4 ^4 b& Y; A* s% q# [5 ` r3_1_f30x_pwm_curr_fdbk.zip (16.66 KB, 下载次数: 10)
passby328 回答时间:2018-11-6 11:04:29
子曰好人 发表于 2018-11-6 09:357 K1 M/ u; Y7 O  s; c( M+ Z/ ^
SDK5.1.3生成的代码里面没有regular_conversion_manager.c这个文件,5.2.0新增了。获取ADC值的代码是几乎 ...
3 s" H3 V+ ~" W
1.我之前参考您的函数,如果一直不断在执行转换,会影响电机库的控制时序导致无法开机,后来改为500ms一次,就没有问题。后来检查regular_conversion_manager.c中的内容,发现用户ADC的转换应该是电机库的状态机在调度的,如果连续不断转换或者没有走相应的接口估计会有问题。: y$ w- v* h  w" [; O: b
2.电机Workbench里面有设置OCP参数,看了原理图应该是通过体验板上面的L6230的内置比较器以及SMT32片内的ADC实现的,但是实际中的程序并没有提供类似的功能。后来查看了代码,OCP保护是通过L6230产生的FO信号进行处理的,不知道我说的是否有偏差,还请指教。
zhdzhd 回答时间:2018-9-2 22:27:32
代码规整,有功底,佩服!- k- q1 N: {$ S$ o4 V- ~
大佬也会有纰漏啊- {9 L* H# n/ m- ~) W% ?+ C
) }8 S8 U3 Z3 C: w2 N% X
/* Infinite loop */$ E& K8 k( u4 l4 n
  /* USER CODE BEGIN WHILE */
0 g! v0 b" i; d  while (1)
$ D, d; }# W: l: }+ U6 v  {/ ^2 h. W# |$ [
      
8 j9 S( F2 O( B! N$ G: H      if(GPIO_PIN_SET == HAL_GPIO_ReadPin(LED11_GPIO_Port,LED11_Pin))
9 P8 y5 q( o# E) r) k# U      {  z  M' p; _2 x, }: h
          task_5(); ------>task_3();: |- d4 ~( M' L" W( D& Z
      }
; F2 E* l- p! c5 [& Z      else, I: U) s) J( T* y, r8 y
      {& w7 j% z. x; j; m( ?2 L6 p( A$ v
        MC_StopMotor1();/ ?0 H& p7 d* a) F  b! I6 E
      }      
+ b3 y! C! [* S4 U8 b0 w1 J  /* USER CODE END WHILE */
子曰好人 回答时间:2018-9-2 22:36:27
zhdzhd-174422 发表于 2018-9-2 22:27+ u2 v! c9 n9 B; H$ m
代码规整,有功底,佩服!+ Y# N5 ]' ?" ^7 w0 q" F' k* J- |5 u
大佬也会有纰漏啊

( y" Z6 y; x% F1 }; `# W6 i不好意思,感谢指正
STM1024 回答时间:2018-9-3 10:24:43
哈哈,和你观点一样,很多故障报警,都是报的speed feedback,我在测试的时候,连堵转都试过,原本以为是电流过大报警,但没想到居然还是speed feedback故障
子曰好人 回答时间:2018-9-3 10:45:56
stm1024 发表于 2018-9-3 10:24
% j4 O" i. u4 J* [. d" Z哈哈,和你观点一样,很多故障报警,都是报的speed feedback,我在测试的时候,连堵转都试过,原本以为是电 ...

/ ]0 a6 [1 U: g) O去研究一下电机库生成的故障触发机制代码,也许就能明白了,搞清楚是怎么回事之后就能自定义故障报警了
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()?2 M$ v. e! r6 l9 }1 I
子曰好人 回答时间:2018-9-4 22:54:20
LT-386596 发表于 2018-9-4 18:382 Q* ?4 v5 g; V
Speed_Adc = R3_1_F30X_ExecRegularConv(MC_SPEED_REF,ADC_CHANNEL_12); 5.2.0 找不到  R3_1_F30X_ExecRegu ...
! S5 T" R6 B, t2 R. p# K
在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
5 P& z2 T" X! f; y( j  PVR连接的脚感觉像是PB1,从电路图上来看.

2 R+ Q/ i% a# |+ z& z' x; Y& R! s9 P手误写错了,已更正
花落莫相离 回答时间: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" y0 ]& C- Q+ T( j& a# b. y  c
楼主,我不太懂Speed_ref = (15500*Speed_Adc)>>16;这段程序中15500的作用时什么?
0 j$ S' P/ Z, Z, 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  r2 P2 |9 N6 J) B, H$ l' o
大神,不知道你有没有注意到有一个小细节,这个USB必须要插在主控板上整个程序好像才能运行,然后不插USB的 ...

, s/ R) _; m9 f) Z2 W没遇到过,我的一直是正常的呀,没有USB连接也能正常运行
晴空 回答时间:2018-10-29 15:53:32
学习了  哈哈
花落莫相离 回答时间:2018-10-31 13:51:43
子曰好人 发表于 2018-10-26 09:16* v$ H: _! Y0 M5 D5 v' i
15500是电机能达到的最大转速,Speed_Adc的最大值是4096,ADC采样值和速度参考值的换算方式为:(Spped_re ...
  L9 N4 k& z% ^8 @
多谢楼主解释了。

所属标签

相似分享

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