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

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

[复制链接]
子曰好人 发布时间:2018-9-2 19:17
本帖最后由 子曰好人 于 2018-9-5 08:55 编辑
- Z2 H, j' ^- Y* O+ M. K+ X  s9 j* h2 V& U( m
继续做实验,任务3和旋钮控制转速。
首先来看看任务3的要求:
任务3要求.png
这个可通过代码实现也可以通过上位机实现,已经有坛友做过这样的事情了。通过上位机做就是快速拨弄圆盘,这样系统不能在短时间内反转,造成观测器不能收敛,触发速度反馈错误报警,其实我个人觉得这里也是有过流报警存在的,这就看系统优先响应哪一个报警了。
我这里通过代码来实现task3。
任务3代码:
  1. void task_3(void)7 W" X( G  Y% D8 m" m
  2. {
    7 N0 }0 B5 V! ~; u/ o7 d, E; A
  3.     MC_ProgramSpeedRampMotor1(-3000/6,1000); //设置-3000rpm的转速,在一秒之内达到
    ' `" A3 E+ C- Q. f6 ?; M' x* i$ N
  4.     MC_StartMotor1();       //启动电机
    : r9 d) A/ r% N, K9 ^5 \
  5.     HAL_Delay(500);         //运行500ms
    & s. _' M3 d- }  {% o) }. j: h' X
  6.     while(RUN != MC_GetSTMStateMotor1()); //等待电机处于运行状态,可有可无1 h  ?" G2 w" L+ }3 j/ ^
  7.     MC_ProgramSpeedRampMotor1(3000/6,1000); //切换到3000rpm转速- [  s) R6 F! h
  8.     MC_StartMotor1();       //启动电机
    * c% p" x$ z" I# q  H8 y
  9.     while(MC_SPEED_FDBK != STM_GetFaultState(&STM[M1])); //等待错误触发
    0 o9 ^/ [9 w6 l% @- i2 X
  10.     HAL_Delay(1000);    //延时一秒,方便可以在上位机上看见错误是否发生
    9 y: Z' }) C  l# g, }3 q3 N3 b# }
  11.     MC_AcknowledgeFaultMotor1();    //清除错误
    4 I+ g' G5 U- |% j
  12.     HAL_Delay(100);     //延时0.1秒
    . }; u/ K$ L1 ^7 s, h
  13.     MC_ProgramSpeedRampMotor1(MC_GetLastRampFinalSpeedMotor1(),1000);   //重新设置上一次速度值3 z, w! _9 Z' a/ |' t- L) n& {
  14.     MC_StartMotor1();   //启动电机
    4 l0 Y  L8 d: E/ ?
  15.     HAL_Delay(5000);    //运行5秒" b9 E& z* m$ m: j+ u+ G% ]" [3 w
  16.     MC_StopMotor1();    //停机# A7 K, _) p4 m1 V- c
  17.     HAL_GPIO_WritePin(LED11_GPIO_Port,LED11_Pin,GPIO_PIN_RESET); //拉低LED引脚,表示任务结束
    % g. m$ N+ ~! Z( b
  18. }
    7 L$ y# q- |7 B; e( x2 o, Y
复制代码
主函数代码:
  1. /* Infinite loop */" c! q* J" I! T3 \* Z! M0 Z, \
  2.   /* USER CODE BEGIN WHILE */) v% }9 R$ A1 R0 F
  3.   while (1)) E- k- D+ d' u; G4 ?4 `- N
  4.   {& r+ i3 d8 G  p, n$ b+ L2 V: D
  5.       * q8 N+ e" m; }* i1 G0 v
  6.       if(GPIO_PIN_SET == HAL_GPIO_ReadPin(LED11_GPIO_Port,LED11_Pin))
    8 \4 J1 |# u, }4 k, f2 a
  7.       {+ q" t3 S# h- g% }0 ]% r  P
  8.           task_3();
    ! [4 A! O% |4 C4 E# ]! ?- w* C
  9.       }
    : T" S  J2 z" w3 a
  10.       else+ x  X$ @7 e% _4 v
  11.       {
    : j. ^& M" u" ]6 c9 B9 `
  12.         MC_StopMotor1();
    $ u+ [2 Y- ]1 t9 q# L8 O2 c2 f
  13.       }      - X# K( B; @0 ~/ `" t  ?, _
  14.   /* USER CODE END WHILE */% ^# [. ?2 P* M) O
复制代码
实验现象:
任务三速度变化截图.png 6 c) B' ]3 x/ b5 P- ]2 |5 g
通过速度变化趋势可以看到任务成功实现了,我对比了PPT的预期结果图,有一些差距。当速度设置为3000rpm时,speed reference并没有跟随代码变为3000。另外,我做了延迟清除错误信息,所以在图中可以看到一截零速状态。

% ]! r, N$ w1 R" r1 z; j
9 n+ A3 w( }: `( q. M# {
好了,任务3完成。
---------------------------------------------------------
现在分享一个开放性实验,旋钮控制转速,我把这个任务定为任务4吧,用旋钮来控制电机转速我觉得才是真正的一个电机控制系统。
由于SDK中并没有考虑旋钮ADC的初始化,所以如果要使用旋钮电位器首先要通过cubemx对ADC进行初始化,在我的第二篇帖子中已经讲过关于套件的硬件资源,也知道了旋钮电位器连接的是PB1引脚。
用户1.png
创建全局变量:
  1. int32_t Speed_Adc = 0;& O, Q( K* {6 C% }
  2. int32_t Speed_ref = 0;
    % T9 X! s' e7 h$ G. W3 v0 n5 D  P. u
  3. PWMC_Handle_t * MC_SPEED_REF;
    6 ?. a$ v) u5 F9 A
复制代码
任务4代码:
  1. void task_4(void)
    + \) G: u' d7 l( q- M3 I
  2. {/ L, W8 N& |0 p' V1 H% E, m$ f
  3.     Speed_Adc = R3_1_F30X_ExecRegularConv(MC_SPEED_REF,ADC_CHANNEL_12);
    $ y! M5 b: n) ^7 M9 c1 D
  4.     Speed_ref = (15500*Speed_Adc)>>16;4 c2 b2 J3 `+ A1 j) T& c+ S
  5.     if(Speed_ref > 0)
    8 y, A  ^: f# Q7 @
  6.     {
    2 w1 b3 z4 G( g8 P3 N* v, O' |
  7.         MC_ProgramSpeedRampMotor1((Speed_ref+1500)/6,1000);
      F% |# Z! U" f, ^8 k' V  Z
  8.         MC_StartMotor1();* \3 j8 b+ L; P9 t+ d
  9.     }
    2 d9 o: l; R' s* z; z1 A- p0 ?! e
  10.     else
    2 }1 V* ?- j# h& A: d3 }/ U) I
  11.     {
    , G, e/ q; X& g6 Q: X3 B
  12.         MC_StopMotor1();
    . P( t0 ^2 u  f: G0 `7 S
  13.     }  D( t$ }* J; M% y0 f( Y8 Z
  14.     HAL_Delay(100);* j' {) ]2 h, o4 j6 e% f  s8 `$ @
  15. }
复制代码
主函数代码:
; Z, l, S' |8 z7 y5 P9 q7 u
  1. /* Initialize interrupts */
    - m# b" H, G1 s! o  l& c
  2.   MX_NVIC_Init();6 s' ?& l, ]) W+ |" y
  3.   /* USER CODE BEGIN 2 */& z* h  D% N+ h. h' L
  4.   MC_SPEED_REF = &PWM_Handle_M1._Super;
    * _" P+ n- ]+ b
  5.   /* USER CODE END 2 */0 h+ Z/ L6 n& J6 I: \$ X
  6. 2 q( {1 T& a, _" _. L4 O, _* g
  7.   /* Infinite loop */& Y: P: ^8 Y" L
  8.   /* USER CODE BEGIN WHILE */* C; J7 W. r+ _" K+ H
  9.   while (1)
      B9 y  e( Z2 x9 j2 g  H. F( I& w
  10.   {
    3 m+ N& @& G5 ]$ A* d: C1 F
  11. # z! y# {* |6 ^( @4 t& z1 |+ K
  12.       if(GPIO_PIN_SET == HAL_GPIO_ReadPin(LED11_GPIO_Port,LED11_Pin))
    # M/ N( v1 ~# E6 Z. `8 O0 S+ l
  13.       {
    ; I; W. x# N* A; Y- R% K
  14.           task_4();0 U2 B6 c- r! ~. l
  15.       }; D+ g2 ^/ a3 o# \  F! X; O
  16.       else
    4 E2 r- }  n8 q& Y1 K" H
  17.       {
    3 e2 C7 b+ B6 l& F$ O
  18.           MC_ProgramSpeedRampMotor1(0,0);8 R* w/ i  N5 k. P
  19.           MC_StopMotor1();" K8 R, e- E# f2 ?
  20.       }
    2 i* O% H7 [3 M
  21.   /* USER CODE END WHILE */7 z- S/ C! q1 [. `
  22.   T7 ~/ c7 ~. I: q5 A% F. N
  23.   /* USER CODE BEGIN 3 */9 R5 o) R# h7 s% O5 |. r

  24. 3 z$ O" Y- M4 \4 w+ S) A2 R" Q  @
  25.   }# x7 ~' o' ^3 A0 M: M+ V' t+ Z4 ^
  26.   /* USER CODE END 3 */3 v1 u/ Z0 Z" m& j) g+ B$ A7 w8 J
复制代码
在这里稍微解释一下代码:
Speed_Adc是存储ADC采样值的变量,Speed_ref变量通过ADC采样值转化为速度设定值,MC_SPEED_REF是一个指针变量,用于获取ADC初始化设置,R3_1_F30X_ExecRegularConv这个函数在r3_1_f30x_pwm_curr_fdbk,c这个文件中,用于处理规则ADC采样。速度换算这里可以没什么说的。速度设定的时候加1500偏移是有原因的,当设定速度过低的时候电机系统根本不能正常启动,这是我尝试设置的时候所能达到的最低启动速度。

  q' L: a3 I0 K  m) n
实验现象:
旋钮调速转速跟踪波形.png
从实验结果看来,这份代码默认速度PID能很好的跟踪给定转速。
我发现一个问题,代码里面在电机运行结束之后有些变量好像没有清零,这个问题留到后面在研究吧。

) k9 p4 ~% t+ p2 `* J8 z
本帖两个任务分享就到这里,欢迎大家留言讨论。
* s/ g, V% Q& P2 m/ A
1 p: u: P1 R/ W' }

5 n" T5 S1 V. L; V* v) f- n8 S7 }( x' d

3 I0 W* x- e  G9 F7 i+ \- [) Q6 V
赞 1 收藏 2 评论118 发布时间:2018-9-2 19:17

举报

118个回答
子曰好人 回答时间:2020-4-15 09:28:07
ysx584085668 发表于 2020-4-14 23:23
8 S, C# U0 Z( l, c8 r太感谢了,我发邮件给你看吧

: c8 h' d9 c7 y4 G0 ~看了你发的邮件,新版本的MCSDK生成的代码没有留ADC规则转换的函数接口,可能需要你自己去写了,我把我这边生成的文件发你一份参考吧
; u' g' X+ N+ U& E r3_1_f30x_pwm_curr_fdbk.zip (16.66 KB, 下载次数: 10)
passby328 回答时间:2018-11-6 11:04:29
子曰好人 发表于 2018-11-6 09:359 b3 y3 A  @2 x& o
SDK5.1.3生成的代码里面没有regular_conversion_manager.c这个文件,5.2.0新增了。获取ADC值的代码是几乎 ...
  O0 m: s1 v# |2 m; r4 W
1.我之前参考您的函数,如果一直不断在执行转换,会影响电机库的控制时序导致无法开机,后来改为500ms一次,就没有问题。后来检查regular_conversion_manager.c中的内容,发现用户ADC的转换应该是电机库的状态机在调度的,如果连续不断转换或者没有走相应的接口估计会有问题。( e- z3 ^/ F" b8 @7 a" \
2.电机Workbench里面有设置OCP参数,看了原理图应该是通过体验板上面的L6230的内置比较器以及SMT32片内的ADC实现的,但是实际中的程序并没有提供类似的功能。后来查看了代码,OCP保护是通过L6230产生的FO信号进行处理的,不知道我说的是否有偏差,还请指教。
zhdzhd 回答时间:2018-9-2 22:27:32
代码规整,有功底,佩服!
' D# \. s) ]2 Q5 P1 l5 h$ j) D大佬也会有纰漏啊
( r. z! w, u5 T6 {
2 J+ x; L- l. b9 f/* Infinite loop */7 c& P2 q" f( I
  /* USER CODE BEGIN WHILE */' ^4 z# p$ J' f! k8 a, r( H* o  l8 p7 D
  while (1)! q; `: _* @' o0 w; B3 y+ k" W
  {
- }* a+ b% F1 j1 O/ E9 l      : v( C3 ^7 O% e; T* j4 O
      if(GPIO_PIN_SET == HAL_GPIO_ReadPin(LED11_GPIO_Port,LED11_Pin))
% v' B0 k' ]8 i( M/ W* g2 P! v      {
! |- G) Q5 s4 V; K  U- A          task_5(); ------>task_3();6 m5 U1 y4 j% h
      }0 B; |" `% l; r; e
      else0 }, M2 Z: O5 ?  a
      {
# s. N# ]5 _$ c' A# Y        MC_StopMotor1();
; S" }5 C; s: M+ Q* L& V      }      
0 G. N  ]2 k) ~7 g& w  /* USER CODE END WHILE */
子曰好人 回答时间:2018-9-2 22:36:27
zhdzhd-174422 发表于 2018-9-2 22:27
' D$ x3 ]0 I/ Y( b代码规整,有功底,佩服!
) k; A: t4 Z- H2 R' A& v4 [8 X大佬也会有纰漏啊

2 c1 b9 C9 S3 R1 F不好意思,感谢指正
STM1024 回答时间:2018-9-3 10:24:43
哈哈,和你观点一样,很多故障报警,都是报的speed feedback,我在测试的时候,连堵转都试过,原本以为是电流过大报警,但没想到居然还是speed feedback故障
子曰好人 回答时间:2018-9-3 10:45:56
stm1024 发表于 2018-9-3 10:24
8 r. }: _7 y- C2 `! O( @' P哈哈,和你观点一样,很多故障报警,都是报的speed feedback,我在测试的时候,连堵转都试过,原本以为是电 ...

  S4 `4 J/ R6 {7 @- H* b; ]去研究一下电机库生成的故障触发机制代码,也许就能明白了,搞清楚是怎么回事之后就能自定义故障报警了
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()?% m: Q" i  a+ \- r1 u* |" `, v* I9 j
子曰好人 回答时间:2018-9-4 22:54:20
LT-386596 发表于 2018-9-4 18:38- Y3 l7 f6 M/ p: k: E
Speed_Adc = R3_1_F30X_ExecRegularConv(MC_SPEED_REF,ADC_CHANNEL_12); 5.2.0 找不到  R3_1_F30X_ExecRegu ...

8 d: D( M/ G( i* C& u+ m4 ?在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+ H# N8 L5 ]. J* _1 u& n6 u  p
VR连接的脚感觉像是PB1,从电路图上来看.

8 l/ i8 b. u! b9 `3 w  d5 w1 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. z) z7 r9 X' Y( p
楼主,我不太懂Speed_ref = (15500*Speed_Adc)>>16;这段程序中15500的作用时什么?

0 G3 u! v! ?+ O6 u" B% B15500是电机能达到的最大转速,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
2 D) _6 X4 [4 t: U大神,不知道你有没有注意到有一个小细节,这个USB必须要插在主控板上整个程序好像才能运行,然后不插USB的 ...
* h" Y; S1 P8 W+ x1 Z6 e
没遇到过,我的一直是正常的呀,没有USB连接也能正常运行
晴空 回答时间:2018-10-29 15:53:32
学习了  哈哈
花落莫相离 回答时间:2018-10-31 13:51:43
子曰好人 发表于 2018-10-26 09:16  P/ a7 \" J/ Q( \+ I
15500是电机能达到的最大转速,Speed_Adc的最大值是4096,ADC采样值和速度参考值的换算方式为:(Spped_re ...
  A" E+ e4 L/ O5 D: d$ L( s
多谢楼主解释了。

所属标签

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