请选择 进入手机版 | 继续访问电脑版

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

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

[复制链接]
子曰好人 发布时间:2018-9-2 19:17
本帖最后由 子曰好人 于 2018-9-5 08:55 编辑
* O9 y2 N1 V- _+ Z  Y. G, n* z5 {3 g- T$ f
继续做实验,任务3和旋钮控制转速。
首先来看看任务3的要求:
任务3要求.png
这个可通过代码实现也可以通过上位机实现,已经有坛友做过这样的事情了。通过上位机做就是快速拨弄圆盘,这样系统不能在短时间内反转,造成观测器不能收敛,触发速度反馈错误报警,其实我个人觉得这里也是有过流报警存在的,这就看系统优先响应哪一个报警了。
我这里通过代码来实现task3。
任务3代码:
  1. void task_3(void)& r3 B' h  c- J
  2. {
    9 b+ D  o+ E, O# O. x
  3.     MC_ProgramSpeedRampMotor1(-3000/6,1000); //设置-3000rpm的转速,在一秒之内达到6 ^; S; i) Z4 F3 t: I# l
  4.     MC_StartMotor1();       //启动电机# L4 W# ]. I$ |  E0 w. I
  5.     HAL_Delay(500);         //运行500ms. Q" I8 R# S7 \0 M+ P
  6.     while(RUN != MC_GetSTMStateMotor1()); //等待电机处于运行状态,可有可无) [5 M  Z; C. {$ |6 {4 v
  7.     MC_ProgramSpeedRampMotor1(3000/6,1000); //切换到3000rpm转速
    - Y3 B* E; R* c- f
  8.     MC_StartMotor1();       //启动电机
    & V. @4 Y) i& a& p5 b: |6 Q
  9.     while(MC_SPEED_FDBK != STM_GetFaultState(&STM[M1])); //等待错误触发1 v- }4 V/ O0 N4 R) i
  10.     HAL_Delay(1000);    //延时一秒,方便可以在上位机上看见错误是否发生
    * N0 q# G' V8 \" M
  11.     MC_AcknowledgeFaultMotor1();    //清除错误- z. e1 I6 M# `5 r% n
  12.     HAL_Delay(100);     //延时0.1秒
    4 W1 ~: R5 ?. {; M& h) A/ `+ T
  13.     MC_ProgramSpeedRampMotor1(MC_GetLastRampFinalSpeedMotor1(),1000);   //重新设置上一次速度值' S" I  Z+ u9 ^* T% x
  14.     MC_StartMotor1();   //启动电机$ e2 E! C. y, A$ E% @; m2 v4 d
  15.     HAL_Delay(5000);    //运行5秒
    2 t) X# d) w- v2 L+ N- ]# Z7 b" ?
  16.     MC_StopMotor1();    //停机
    ! c9 N: B+ k! |9 p) F
  17.     HAL_GPIO_WritePin(LED11_GPIO_Port,LED11_Pin,GPIO_PIN_RESET); //拉低LED引脚,表示任务结束
    . ^# P# \" J! Q0 [' B8 i% I
  18. }
    ) @; K8 e( [6 G0 i$ o, x
复制代码
主函数代码:
  1. /* Infinite loop */
    ; _! M$ U, D8 P2 _) P0 u
  2.   /* USER CODE BEGIN WHILE */8 A9 ~& W# n/ _% [" ?
  3.   while (1)
    7 F6 s- Z# K8 I+ }& o
  4.   {
    ( N9 \( W. P' O2 ^; A& |
  5.       4 [  w: W4 k0 E* B
  6.       if(GPIO_PIN_SET == HAL_GPIO_ReadPin(LED11_GPIO_Port,LED11_Pin))
    ' T% V( G0 b. V, V- J
  7.       {5 F) f  I2 g9 \8 Y: g
  8.           task_3();1 L' p- b2 g" T5 f
  9.       }
    ) ^  ^0 C+ c3 M9 {* l
  10.       else
    8 a9 K3 c  N# R
  11.       {1 Y5 N' D- _0 m) L$ \  d$ [5 X2 L) u
  12.         MC_StopMotor1();
    . V3 r2 ]1 h8 q0 b
  13.       }      
    * R! g: u9 B; U. X4 ?# e0 t4 j
  14.   /* USER CODE END WHILE */
    5 B! l$ W+ T( V
复制代码
实验现象:
任务三速度变化截图.png ; ?8 W8 M% s3 |, a
通过速度变化趋势可以看到任务成功实现了,我对比了PPT的预期结果图,有一些差距。当速度设置为3000rpm时,speed reference并没有跟随代码变为3000。另外,我做了延迟清除错误信息,所以在图中可以看到一截零速状态。
0 q2 i  P( v  A& K* J1 ~
5 n2 B. ]) z8 P% v3 S
好了,任务3完成。
---------------------------------------------------------
现在分享一个开放性实验,旋钮控制转速,我把这个任务定为任务4吧,用旋钮来控制电机转速我觉得才是真正的一个电机控制系统。
由于SDK中并没有考虑旋钮ADC的初始化,所以如果要使用旋钮电位器首先要通过cubemx对ADC进行初始化,在我的第二篇帖子中已经讲过关于套件的硬件资源,也知道了旋钮电位器连接的是PB1引脚。
用户1.png
创建全局变量:
  1. int32_t Speed_Adc = 0;
    ' ]( O, Q: O' c$ M% l* x5 Z
  2. int32_t Speed_ref = 0;
    ; ?& J7 j" n/ g1 S$ B4 g- ]
  3. PWMC_Handle_t * MC_SPEED_REF;( b, U9 ]- H, G/ {! I' H
复制代码
任务4代码:
  1. void task_4(void)
    5 M. E) t3 M3 B  ~  A, d! E
  2. {1 w" i1 S7 r% K1 i! g
  3.     Speed_Adc = R3_1_F30X_ExecRegularConv(MC_SPEED_REF,ADC_CHANNEL_12);
    - ~# b6 W1 E0 K) i7 V9 |
  4.     Speed_ref = (15500*Speed_Adc)>>16;
    & `! d, H9 R  I- A- X
  5.     if(Speed_ref > 0)
    5 u7 X7 e& g/ b, U9 V  ^
  6.     {
    2 n4 p8 T6 k& P( H
  7.         MC_ProgramSpeedRampMotor1((Speed_ref+1500)/6,1000);
    / t/ y# i. O: H: m8 w. S. M, }
  8.         MC_StartMotor1();
    1 n+ t* b, r1 O5 P& n" D
  9.     }
    9 N8 d5 v2 W3 {  d$ y$ T2 x' G+ l" b
  10.     else# k) ?8 E4 o1 y( o0 [; x
  11.     {0 E! b( S( [- H5 [
  12.         MC_StopMotor1();
    7 H; N; O% _5 b6 _
  13.     }( e- G8 y9 R8 G. Q" y: k* t
  14.     HAL_Delay(100);
    2 Y2 t5 b5 z6 f$ V& R2 S1 t
  15. }
复制代码
主函数代码:
' s2 W& P0 E$ w. J! A' D
  1. /* Initialize interrupts */% a4 @) D# g- \$ P
  2.   MX_NVIC_Init();" l3 s9 j7 M1 w4 ]7 N
  3.   /* USER CODE BEGIN 2 */
    " B2 Q: u  i& y5 _5 z) Q$ \5 p, c
  4.   MC_SPEED_REF = &PWM_Handle_M1._Super;
    ! C2 q- t4 X% Y+ Y6 J
  5.   /* USER CODE END 2 */
    4 X% B5 V- t6 ?( c& F  l0 ^. w
  6. ' U, Z4 u9 F$ P' s
  7.   /* Infinite loop */
    9 M; w- N. c2 L) y5 Z
  8.   /* USER CODE BEGIN WHILE */
    - \+ v: o+ ^9 ?
  9.   while (1)
    # ]5 b; s" h8 @- `, n$ U
  10.   {
    ) s3 m3 Y; E) R9 x9 t/ F9 h$ P" Y5 j1 M

  11. / {7 z/ `3 g  c& J6 R" e/ c3 \
  12.       if(GPIO_PIN_SET == HAL_GPIO_ReadPin(LED11_GPIO_Port,LED11_Pin))
    / q& K& F7 z( F5 L0 X5 u
  13.       {$ T: V6 k! |$ C! g0 a" G7 t' J
  14.           task_4();6 Z" T6 N: Y# Q! M7 K% O
  15.       }
    . y+ q* l1 V$ d+ Z9 ^
  16.       else
    . _( O, H/ L( O- w, s; v
  17.       {
    4 f, [4 G( m2 @; o2 X) w
  18.           MC_ProgramSpeedRampMotor1(0,0);+ x) p9 E$ c7 ~2 s- I, {9 d
  19.           MC_StopMotor1();
    4 y" u7 y& [" k7 d' O- u' @
  20.       }
    / B9 T' s7 |0 w" s7 a, k, ?% e
  21.   /* USER CODE END WHILE */
    3 M, ~* x' [+ R+ B" E: T
  22. " y0 M- N& H+ E
  23.   /* USER CODE BEGIN 3 */
    0 R/ s7 @; R- ]/ Q% l! b
  24. 2 ^* [! i6 Q* q7 }* y; v9 e% X6 G
  25.   }
    4 f( U+ Q* R) u# m/ Y
  26.   /* USER CODE END 3 */
    , u; G9 A2 t" S- W) ^
复制代码
在这里稍微解释一下代码:
Speed_Adc是存储ADC采样值的变量,Speed_ref变量通过ADC采样值转化为速度设定值,MC_SPEED_REF是一个指针变量,用于获取ADC初始化设置,R3_1_F30X_ExecRegularConv这个函数在r3_1_f30x_pwm_curr_fdbk,c这个文件中,用于处理规则ADC采样。速度换算这里可以没什么说的。速度设定的时候加1500偏移是有原因的,当设定速度过低的时候电机系统根本不能正常启动,这是我尝试设置的时候所能达到的最低启动速度。
' D! w: `! \! n1 e
实验现象:
旋钮调速转速跟踪波形.png
从实验结果看来,这份代码默认速度PID能很好的跟踪给定转速。
我发现一个问题,代码里面在电机运行结束之后有些变量好像没有清零,这个问题留到后面在研究吧。
3 q# [7 A& S4 J" z2 ~- F
本帖两个任务分享就到这里,欢迎大家留言讨论。& z; b$ G4 r" b# u4 u. |

9 @7 U* h; x* ?! J5 s" o3 n  ]( p

4 e& S  a% c3 X6 z# w9 w7 [7 ?7 ?: d; D6 B5 c; I
1 收藏 2 评论118 发布时间:2018-9-2 19:17

举报

118个回答
子曰好人 回答时间:2020-4-15 09:28:07
ysx584085668 发表于 2020-4-14 23:23
4 k" ^% E/ U6 y太感谢了,我发邮件给你看吧

' T: D0 _- S* Q, T0 l& t# f7 f- Q看了你发的邮件,新版本的MCSDK生成的代码没有留ADC规则转换的函数接口,可能需要你自己去写了,我把我这边生成的文件发你一份参考吧: E  o5 a! E1 [6 O$ X4 ]
r3_1_f30x_pwm_curr_fdbk.zip (16.66 KB, 下载次数: 10)
passby328 回答时间:2018-11-6 11:04:29
子曰好人 发表于 2018-11-6 09:35
% V. w% k. k/ z; vSDK5.1.3生成的代码里面没有regular_conversion_manager.c这个文件,5.2.0新增了。获取ADC值的代码是几乎 ...
- L, p/ F! v' f! S1 k7 D5 C/ p
1.我之前参考您的函数,如果一直不断在执行转换,会影响电机库的控制时序导致无法开机,后来改为500ms一次,就没有问题。后来检查regular_conversion_manager.c中的内容,发现用户ADC的转换应该是电机库的状态机在调度的,如果连续不断转换或者没有走相应的接口估计会有问题。
1 P: {1 P% D/ T0 ~6 N- q  s2.电机Workbench里面有设置OCP参数,看了原理图应该是通过体验板上面的L6230的内置比较器以及SMT32片内的ADC实现的,但是实际中的程序并没有提供类似的功能。后来查看了代码,OCP保护是通过L6230产生的FO信号进行处理的,不知道我说的是否有偏差,还请指教。
zhdzhd 回答时间:2018-9-2 22:27:32
代码规整,有功底,佩服!0 c$ T1 t# }" I; C( V6 [4 S
大佬也会有纰漏啊5 W( [0 G1 ~. W4 m+ J7 I: @& _

5 h0 y! V; V8 U& T6 ]+ o6 X/* Infinite loop */5 m+ q2 ]  {; Z$ t
  /* USER CODE BEGIN WHILE */# j% k2 h5 t" _+ ~5 S" @  m! Q& f
  while (1)
& d+ I8 i/ ?4 d# S4 W) h. ]2 f  {
1 [" v8 W0 T; }+ K& E* q      
% t! d. p' ~+ D/ I      if(GPIO_PIN_SET == HAL_GPIO_ReadPin(LED11_GPIO_Port,LED11_Pin))
1 _) s5 _* K. B" A* U      {. u1 D6 S$ z, E) p  z2 E
          task_5(); ------>task_3();. [/ o" \& W* @6 i
      }
4 G2 P* a1 h( g! _      else% X) {# A- F* i4 h8 b, n
      {
! g& B: d6 G! Y) m$ E/ P        MC_StopMotor1();
  J2 a  v! H& @      }      % m8 `! P, |$ G: _
  /* USER CODE END WHILE */
子曰好人 回答时间:2018-9-2 22:36:27
zhdzhd-174422 发表于 2018-9-2 22:27
/ O+ ~$ s$ Y0 V0 G. q" h! n3 U5 w! R代码规整,有功底,佩服!
- F! ]8 A8 ^: b0 e: O0 M0 d& Z大佬也会有纰漏啊

7 Y1 z3 Z+ ~* z$ t不好意思,感谢指正
STM1024 回答时间:2018-9-3 10:24:43
哈哈,和你观点一样,很多故障报警,都是报的speed feedback,我在测试的时候,连堵转都试过,原本以为是电流过大报警,但没想到居然还是speed feedback故障
子曰好人 回答时间:2018-9-3 10:45:56
stm1024 发表于 2018-9-3 10:24
8 |1 }  f& z  B# M! U哈哈,和你观点一样,很多故障报警,都是报的speed feedback,我在测试的时候,连堵转都试过,原本以为是电 ...

, k# E; j" a( [  l! ]3 Z5 T去研究一下电机库生成的故障触发机制代码,也许就能明白了,搞清楚是怎么回事之后就能自定义故障报警了
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()?! K4 V- m) {0 c# C  }7 Z: F" E
子曰好人 回答时间:2018-9-4 22:54:20
LT-386596 发表于 2018-9-4 18:386 p* ~4 {* T$ V7 z6 {4 r
Speed_Adc = R3_1_F30X_ExecRegularConv(MC_SPEED_REF,ADC_CHANNEL_12); 5.2.0 找不到  R3_1_F30X_ExecRegu ...
) }) r3 e6 X6 F0 U% H
在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:274 n  Z, F6 M$ u; e' w) q
VR连接的脚感觉像是PB1,从电路图上来看.
6 \. e. M5 Q9 F
手误写错了,已更正
花落莫相离 回答时间: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 ^$ w0 \8 w' C" L: v) a楼主,我不太懂Speed_ref = (15500*Speed_Adc)>>16;这段程序中15500的作用时什么?
5 A) e6 T7 a+ G8 u6 M- [
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$ i+ @! @& z$ r  Y+ ~  ]
大神,不知道你有没有注意到有一个小细节,这个USB必须要插在主控板上整个程序好像才能运行,然后不插USB的 ...
8 G3 l. X: x1 Y6 L9 c. z, u
没遇到过,我的一直是正常的呀,没有USB连接也能正常运行
晴空 回答时间:2018-10-29 15:53:32
学习了  哈哈
花落莫相离 回答时间:2018-10-31 13:51:43
子曰好人 发表于 2018-10-26 09:16
- c$ F/ ~" _" _; G15500是电机能达到的最大转速,Speed_Adc的最大值是4096,ADC采样值和速度参考值的换算方式为:(Spped_re ...
; u) p# g3 D- V* ]
多谢楼主解释了。

所属标签

相似分享

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