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

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

[复制链接]
子曰好人 发布时间:2018-9-2 19:17
本帖最后由 子曰好人 于 2018-9-5 08:55 编辑
; F1 F8 z# f; i; B8 c" [. ?& E
/ M2 M% r+ J. }/ o
继续做实验,任务3和旋钮控制转速。
首先来看看任务3的要求:
任务3要求.png
这个可通过代码实现也可以通过上位机实现,已经有坛友做过这样的事情了。通过上位机做就是快速拨弄圆盘,这样系统不能在短时间内反转,造成观测器不能收敛,触发速度反馈错误报警,其实我个人觉得这里也是有过流报警存在的,这就看系统优先响应哪一个报警了。
我这里通过代码来实现task3。
任务3代码:
  1. void task_3(void)
    ! d$ d, S7 r' t% x: d) h8 p9 s- M
  2. {" Q6 p3 g0 W! |( F0 V/ L( E( ]& U
  3.     MC_ProgramSpeedRampMotor1(-3000/6,1000); //设置-3000rpm的转速,在一秒之内达到/ t; Z, g; Q. h, b1 ?0 [- ^2 p
  4.     MC_StartMotor1();       //启动电机
    - R2 U$ H; ^, ~& v! W' U
  5.     HAL_Delay(500);         //运行500ms8 s" q" a; j" e. ~
  6.     while(RUN != MC_GetSTMStateMotor1()); //等待电机处于运行状态,可有可无
    9 _0 C' X  W8 f9 x$ ]
  7.     MC_ProgramSpeedRampMotor1(3000/6,1000); //切换到3000rpm转速8 B" @# s: C2 t$ }6 [
  8.     MC_StartMotor1();       //启动电机
    # C: T% p4 U: B6 u
  9.     while(MC_SPEED_FDBK != STM_GetFaultState(&STM[M1])); //等待错误触发' M) L8 E5 W) g) [9 F8 C* T
  10.     HAL_Delay(1000);    //延时一秒,方便可以在上位机上看见错误是否发生
    / `' K7 T: e( d
  11.     MC_AcknowledgeFaultMotor1();    //清除错误
    " y3 Q, r% K. L) \. }1 r. Y, o! Z
  12.     HAL_Delay(100);     //延时0.1秒  n: m, d; N) Q' k2 R; Z) A
  13.     MC_ProgramSpeedRampMotor1(MC_GetLastRampFinalSpeedMotor1(),1000);   //重新设置上一次速度值4 y9 z, r9 R4 u& z) v: c
  14.     MC_StartMotor1();   //启动电机1 [4 K: n; ?) M; J/ `
  15.     HAL_Delay(5000);    //运行5秒
    ' G0 u3 X* F1 ]2 N) d' G5 K3 c
  16.     MC_StopMotor1();    //停机+ ~4 H: n- q7 L, e' v& u5 k
  17.     HAL_GPIO_WritePin(LED11_GPIO_Port,LED11_Pin,GPIO_PIN_RESET); //拉低LED引脚,表示任务结束+ Y& K" Y+ |7 `
  18. }
    # Y% b7 m9 u/ N5 d
复制代码
主函数代码:
  1. /* Infinite loop */5 J' g2 I8 D5 A0 ^# e8 }1 y
  2.   /* USER CODE BEGIN WHILE */9 |+ v+ N/ `9 r! O! _! G" K& R
  3.   while (1)
    " J3 k% b4 }7 S' o% E* P, ?
  4.   {% j& F. ~3 i# f3 k$ Y
  5.       8 {% d4 u% ~9 u1 e
  6.       if(GPIO_PIN_SET == HAL_GPIO_ReadPin(LED11_GPIO_Port,LED11_Pin))& {! K3 j# h- z8 P
  7.       {
    # m) m4 `* B8 j0 y
  8.           task_3();5 d* N8 f4 L0 d- ~0 X' Y1 j$ i
  9.       }# p7 P! Z2 w7 y
  10.       else. e* x3 U4 B, J$ N! s
  11.       {
    8 U5 e- [. ^  @% ]9 R
  12.         MC_StopMotor1();
    0 T; H# C$ [4 H+ z6 W
  13.       }      
    % _9 D$ r. T( ~" A, m! [* {
  14.   /* USER CODE END WHILE */
    " H& T4 \, K; Y9 }5 a  g: b. C
复制代码
实验现象:
任务三速度变化截图.png 8 d9 f8 D: m' V
通过速度变化趋势可以看到任务成功实现了,我对比了PPT的预期结果图,有一些差距。当速度设置为3000rpm时,speed reference并没有跟随代码变为3000。另外,我做了延迟清除错误信息,所以在图中可以看到一截零速状态。

% N4 {# e+ J, s6 @. ~9 |7 ^

% j0 ]9 l! U& R- u% N好了,任务3完成。
---------------------------------------------------------
现在分享一个开放性实验,旋钮控制转速,我把这个任务定为任务4吧,用旋钮来控制电机转速我觉得才是真正的一个电机控制系统。
由于SDK中并没有考虑旋钮ADC的初始化,所以如果要使用旋钮电位器首先要通过cubemx对ADC进行初始化,在我的第二篇帖子中已经讲过关于套件的硬件资源,也知道了旋钮电位器连接的是PB1引脚。
用户1.png
创建全局变量:
  1. int32_t Speed_Adc = 0;
    " F8 \1 K) f6 q8 A1 m' f* G
  2. int32_t Speed_ref = 0;
    ' S& X& u, Q# V) w9 u) m) ~- a
  3. PWMC_Handle_t * MC_SPEED_REF;: ]4 l* J2 K0 D" c1 V1 T7 P5 o
复制代码
任务4代码:
  1. void task_4(void)" B5 J  x. z9 M/ |
  2. {
    ( f% V1 z/ t8 B4 ~, G- _" B
  3.     Speed_Adc = R3_1_F30X_ExecRegularConv(MC_SPEED_REF,ADC_CHANNEL_12);2 l  N3 d. ]! i& Y
  4.     Speed_ref = (15500*Speed_Adc)>>16;
    5 u6 W, l0 o9 R
  5.     if(Speed_ref > 0)' |. m4 _2 Y" E8 R+ v8 L, F
  6.     {; y" p9 ]( y$ Z' e& O$ h4 Z1 l
  7.         MC_ProgramSpeedRampMotor1((Speed_ref+1500)/6,1000);& z3 N9 s" t. y# g& a
  8.         MC_StartMotor1();4 J2 Q0 R, R0 P$ Z
  9.     }
    : ]) `, j3 B9 I: M
  10.     else5 {/ [7 V# t* G, C& z
  11.     {9 Y; m$ k, f9 Q
  12.         MC_StopMotor1();
    / R: y+ Q- L! ]4 f
  13.     }/ v' w$ a: l6 \( K8 c
  14.     HAL_Delay(100);6 o. H5 _3 k# s9 B7 X& K& G/ O  z9 _, h
  15. }
复制代码
主函数代码:. {" j1 L6 {# h1 N; f8 O
  1. /* Initialize interrupts */
    7 j5 Z# m3 j1 W' y& C
  2.   MX_NVIC_Init();) J5 o! J) `0 F, p, m8 J
  3.   /* USER CODE BEGIN 2 */
    # e) x+ ^8 F0 |% z) J
  4.   MC_SPEED_REF = &PWM_Handle_M1._Super;( r; q8 Y+ S0 m+ h5 f
  5.   /* USER CODE END 2 */2 k  v! }1 ~; A  S+ ]8 l

  6. ' M" l1 Z% k5 e9 n$ [0 x- R
  7.   /* Infinite loop */$ c5 S8 _  d$ T% S  E# f: R
  8.   /* USER CODE BEGIN WHILE */: W# u- S, x: w
  9.   while (1)) J4 x" t3 z* \, c6 O* m( V1 `
  10.   {5 B. j0 P5 O" v
  11. 0 S6 T0 L4 Q  k+ b  Y
  12.       if(GPIO_PIN_SET == HAL_GPIO_ReadPin(LED11_GPIO_Port,LED11_Pin))% c  o! q2 ~7 ~2 ~
  13.       {
      E8 Y& U# n/ d+ k
  14.           task_4();
    + H" ^$ B, A( f7 R# k
  15.       }
    ; N) C+ Q' |" @, |" ^
  16.       else
      z5 X2 G2 o9 @0 F  F, d! ^) k
  17.       {
    + e. p$ l, H* o! f4 H3 p
  18.           MC_ProgramSpeedRampMotor1(0,0);
    9 e3 y' Y* @+ f% c# F
  19.           MC_StopMotor1();/ l& u0 {8 ?* m) M
  20.       }
    - t$ D0 Z. N& @2 r
  21.   /* USER CODE END WHILE */
    8 d& x2 F0 {) E3 _8 f8 K) n# Q
  22. 0 d& D4 h# Z) x
  23.   /* USER CODE BEGIN 3 */
    ( T0 i; ^0 j7 |. c& ]% e" S' v
  24. ; i7 _. I" U8 q0 s5 T# K
  25.   }
    7 o4 N) _; ~1 L* _9 D1 N! H. Q( _
  26.   /* USER CODE END 3 */
    $ y1 J# [& {! m# G4 S
复制代码
在这里稍微解释一下代码:
Speed_Adc是存储ADC采样值的变量,Speed_ref变量通过ADC采样值转化为速度设定值,MC_SPEED_REF是一个指针变量,用于获取ADC初始化设置,R3_1_F30X_ExecRegularConv这个函数在r3_1_f30x_pwm_curr_fdbk,c这个文件中,用于处理规则ADC采样。速度换算这里可以没什么说的。速度设定的时候加1500偏移是有原因的,当设定速度过低的时候电机系统根本不能正常启动,这是我尝试设置的时候所能达到的最低启动速度。
" q3 @$ d- l8 u! a
实验现象:
旋钮调速转速跟踪波形.png
从实验结果看来,这份代码默认速度PID能很好的跟踪给定转速。
我发现一个问题,代码里面在电机运行结束之后有些变量好像没有清零,这个问题留到后面在研究吧。
$ @4 @3 f: C: h( z! ^% ^
本帖两个任务分享就到这里,欢迎大家留言讨论。" Q5 y8 S- ]6 E5 I
0 Z4 H  O1 Q; X$ h/ O. R8 r/ X
; L) d. i) g, s+ {8 I+ |: _

: ~* h8 r5 n- ]4 X; v5 n+ V
  G4 G& L( G- D+ L5 e! n
赞 1 收藏 2 评论118 发布时间:2018-9-2 19:17

举报

118个回答
子曰好人 回答时间:2020-4-15 09:28:07
ysx584085668 发表于 2020-4-14 23:235 S) _3 i5 L2 q$ W% m
太感谢了,我发邮件给你看吧
- r$ I# A" m2 {! Y7 ~: @
看了你发的邮件,新版本的MCSDK生成的代码没有留ADC规则转换的函数接口,可能需要你自己去写了,我把我这边生成的文件发你一份参考吧8 N: t( K- w# u
r3_1_f30x_pwm_curr_fdbk.zip (16.66 KB, 下载次数: 10)
passby328 回答时间:2018-11-6 11:04:29
子曰好人 发表于 2018-11-6 09:357 _! Y) J, l3 l0 X9 U; }
SDK5.1.3生成的代码里面没有regular_conversion_manager.c这个文件,5.2.0新增了。获取ADC值的代码是几乎 ...
6 _0 F- C9 c5 H3 C8 _. N' q9 i0 c9 j
1.我之前参考您的函数,如果一直不断在执行转换,会影响电机库的控制时序导致无法开机,后来改为500ms一次,就没有问题。后来检查regular_conversion_manager.c中的内容,发现用户ADC的转换应该是电机库的状态机在调度的,如果连续不断转换或者没有走相应的接口估计会有问题。, S+ O+ ^* P% X9 X( S" t
2.电机Workbench里面有设置OCP参数,看了原理图应该是通过体验板上面的L6230的内置比较器以及SMT32片内的ADC实现的,但是实际中的程序并没有提供类似的功能。后来查看了代码,OCP保护是通过L6230产生的FO信号进行处理的,不知道我说的是否有偏差,还请指教。
zhdzhd 回答时间:2018-9-2 22:27:32
代码规整,有功底,佩服!
& }, d- G$ `! i/ ], H! c大佬也会有纰漏啊0 T0 U; m% [# ^  Z" U  @1 d
5 d& G9 [$ p) N- _, Q2 d% E: f# r$ d( t
/* Infinite loop */
0 u$ {) q8 E. T0 K  /* USER CODE BEGIN WHILE */
6 W8 F& ^$ Z, \& ~6 J  while (1)7 h! n) l: R8 T* L4 i
  {
! \- H% O% I1 V: s& U" m, e& ^      & ]) g+ E- [$ t) n; m- m6 m9 q
      if(GPIO_PIN_SET == HAL_GPIO_ReadPin(LED11_GPIO_Port,LED11_Pin))
' y+ U* n' @) J. W      {' f: ]4 x: \4 ]) R
          task_5(); ------>task_3();  B- D% ~  M- ?" S" J1 P% M
      }: o8 C1 V+ ]3 ^* D  R* U. C% n: D
      else2 N  Q, v& u$ |8 w
      {' Y, F/ X( c+ I; y5 d
        MC_StopMotor1();; B: h* C/ {! N) U: q
      }      
3 V. @/ F4 l3 F! G9 `: K  /* USER CODE END WHILE */
子曰好人 回答时间:2018-9-2 22:36:27
zhdzhd-174422 发表于 2018-9-2 22:27+ g( E- \8 B9 F6 j- H
代码规整,有功底,佩服!
! l- {* i  ~% W. x6 |! T大佬也会有纰漏啊
; g( p, K7 p6 ?$ {0 D. C. Q$ V# x0 d
不好意思,感谢指正
STM1024 回答时间:2018-9-3 10:24:43
哈哈,和你观点一样,很多故障报警,都是报的speed feedback,我在测试的时候,连堵转都试过,原本以为是电流过大报警,但没想到居然还是speed feedback故障
子曰好人 回答时间:2018-9-3 10:45:56
stm1024 发表于 2018-9-3 10:24" @9 C+ L/ Y; l
哈哈,和你观点一样,很多故障报警,都是报的speed feedback,我在测试的时候,连堵转都试过,原本以为是电 ...

! c) V$ g* G; ~5 X0 Y去研究一下电机库生成的故障触发机制代码,也许就能明白了,搞清楚是怎么回事之后就能自定义故障报警了
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()?
4 M3 R. i) T. r- c8 w2 K
子曰好人 回答时间:2018-9-4 22:54:20
LT-386596 发表于 2018-9-4 18:38
* d/ M3 T9 q3 z' t% H: S; iSpeed_Adc = R3_1_F30X_ExecRegularConv(MC_SPEED_REF,ADC_CHANNEL_12); 5.2.0 找不到  R3_1_F30X_ExecRegu ...

! {. z" \' w9 M' s# o8 w在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$ C  [: P6 S  v& G* t1 g
VR连接的脚感觉像是PB1,从电路图上来看.
: J) o) q& @( X. w( o$ O
手误写错了,已更正
花落莫相离 回答时间: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
  r$ t  Y9 @" l) a- V楼主,我不太懂Speed_ref = (15500*Speed_Adc)>>16;这段程序中15500的作用时什么?
; l- s7 U" j# @& Z6 I" ?
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" L8 I# i: B4 k1 s& `# C7 B) _
大神,不知道你有没有注意到有一个小细节,这个USB必须要插在主控板上整个程序好像才能运行,然后不插USB的 ...
* |" Z9 [" E9 I% q7 |
没遇到过,我的一直是正常的呀,没有USB连接也能正常运行
晴空 回答时间:2018-10-29 15:53:32
学习了  哈哈
花落莫相离 回答时间:2018-10-31 13:51:43
子曰好人 发表于 2018-10-26 09:16
7 ?( O; S' T9 H( c5 Y/ F15500是电机能达到的最大转速,Speed_Adc的最大值是4096,ADC采样值和速度参考值的换算方式为:(Spped_re ...
' U* p5 Q* X1 k5 z
多谢楼主解释了。

所属标签

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