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

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

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

[复制链接]
子曰好人 发布时间:2018-9-2 19:17
本帖最后由 子曰好人 于 2018-9-5 08:55 编辑
: h7 t6 ]: |/ e, w0 [
. U/ i* G  n# n# S! B
继续做实验,任务3和旋钮控制转速。
首先来看看任务3的要求:
任务3要求.png
这个可通过代码实现也可以通过上位机实现,已经有坛友做过这样的事情了。通过上位机做就是快速拨弄圆盘,这样系统不能在短时间内反转,造成观测器不能收敛,触发速度反馈错误报警,其实我个人觉得这里也是有过流报警存在的,这就看系统优先响应哪一个报警了。
我这里通过代码来实现task3。
任务3代码:
  1. void task_3(void)
    . l4 A, R8 O+ t4 e# |4 ^5 e8 @6 T
  2. {
    4 W2 G! E  K+ O2 J# R! }7 A& l
  3.     MC_ProgramSpeedRampMotor1(-3000/6,1000); //设置-3000rpm的转速,在一秒之内达到
    : E; e( L/ ^. W- G" }$ v" g
  4.     MC_StartMotor1();       //启动电机
    / D! ~/ u( }( I6 H5 `" T
  5.     HAL_Delay(500);         //运行500ms
    , P) |( C/ m; Q. r; ~! X. R7 S
  6.     while(RUN != MC_GetSTMStateMotor1()); //等待电机处于运行状态,可有可无
    : j+ m# S1 X8 S1 @; u: d
  7.     MC_ProgramSpeedRampMotor1(3000/6,1000); //切换到3000rpm转速" I( Q. U1 ?. D! n1 k
  8.     MC_StartMotor1();       //启动电机) F+ G+ i) Z' e( _1 ]: f5 ]
  9.     while(MC_SPEED_FDBK != STM_GetFaultState(&STM[M1])); //等待错误触发% K" T3 q  D, S2 g9 O6 x8 p4 _$ _
  10.     HAL_Delay(1000);    //延时一秒,方便可以在上位机上看见错误是否发生2 N) ]  q" f- l7 L+ x0 U
  11.     MC_AcknowledgeFaultMotor1();    //清除错误
    6 I4 W+ L1 m" \8 M) t3 D
  12.     HAL_Delay(100);     //延时0.1秒
    : u* N% B  p5 }3 C
  13.     MC_ProgramSpeedRampMotor1(MC_GetLastRampFinalSpeedMotor1(),1000);   //重新设置上一次速度值2 L3 {% [; h1 C6 y" [/ _7 T
  14.     MC_StartMotor1();   //启动电机
    # c% q- [# e! ?$ v8 M% K0 u8 M  P
  15.     HAL_Delay(5000);    //运行5秒
    ) Z/ d+ [+ E) L3 c) K" q
  16.     MC_StopMotor1();    //停机( W& o% k+ Z* W  W! V! M/ a
  17.     HAL_GPIO_WritePin(LED11_GPIO_Port,LED11_Pin,GPIO_PIN_RESET); //拉低LED引脚,表示任务结束) B: N* A" L0 ~" Q* h4 D
  18. }1 _9 p$ x  h' J0 |; \
复制代码
主函数代码:
  1. /* Infinite loop */
    * K- O+ x& D/ K) T
  2.   /* USER CODE BEGIN WHILE */0 V5 I& q4 D! i* t- e5 p: V
  3.   while (1)
    8 g1 L- k5 \4 D9 ~. e# ^0 E0 ]+ z) t
  4.   {
    4 b$ r( P# w* Q2 Z
  5.       ! I" m7 ]2 ?* c0 _5 X- y' D
  6.       if(GPIO_PIN_SET == HAL_GPIO_ReadPin(LED11_GPIO_Port,LED11_Pin))
    1 i/ ^3 S$ e! m, [, V- D. G
  7.       {
    3 L$ a8 X7 Q; c8 Y" Q. d
  8.           task_3();# t+ H1 O& b- ~0 z5 N" Z/ b
  9.       }
    5 W' o7 N; D, M. K/ U) e/ |
  10.       else
    2 e  Y6 Z- s! N/ J" D; z
  11.       {
    6 w; Q' ^3 l+ `7 h
  12.         MC_StopMotor1();
    + F/ }1 S; I) @
  13.       }      
    & i% V5 D( ~6 o, z  D0 s# P, f
  14.   /* USER CODE END WHILE */, q* \+ X2 p* C, }# w- w% R7 ?
复制代码
实验现象:
任务三速度变化截图.png . f6 C& L! B- d) k9 M- A  u
通过速度变化趋势可以看到任务成功实现了,我对比了PPT的预期结果图,有一些差距。当速度设置为3000rpm时,speed reference并没有跟随代码变为3000。另外,我做了延迟清除错误信息,所以在图中可以看到一截零速状态。
; a' T8 @; e0 H3 T# v" w0 N

1 _9 Z. F  l( t- K7 I$ X# W' g9 S好了,任务3完成。
---------------------------------------------------------
现在分享一个开放性实验,旋钮控制转速,我把这个任务定为任务4吧,用旋钮来控制电机转速我觉得才是真正的一个电机控制系统。
由于SDK中并没有考虑旋钮ADC的初始化,所以如果要使用旋钮电位器首先要通过cubemx对ADC进行初始化,在我的第二篇帖子中已经讲过关于套件的硬件资源,也知道了旋钮电位器连接的是PB1引脚。
用户1.png
创建全局变量:
  1. int32_t Speed_Adc = 0;1 K5 w: H9 D! I# j1 _3 d
  2. int32_t Speed_ref = 0;0 z9 E% }7 D1 E0 \$ I/ p7 Z
  3. PWMC_Handle_t * MC_SPEED_REF;
    3 i3 P  c1 f8 Q( {0 n
复制代码
任务4代码:
  1. void task_4(void)
      k+ m3 O- v7 e* g9 {9 }. }
  2. {8 o; }" }/ j3 A3 W6 S, b
  3.     Speed_Adc = R3_1_F30X_ExecRegularConv(MC_SPEED_REF,ADC_CHANNEL_12);
    ; A7 x9 @# T/ ]/ `' E" T
  4.     Speed_ref = (15500*Speed_Adc)>>16;
    * r( B. G+ C: [
  5.     if(Speed_ref > 0)
    7 A6 d/ H5 \% c+ l8 U
  6.     {
    # O& ?8 s4 a. h. k' h! `2 t% Z4 h
  7.         MC_ProgramSpeedRampMotor1((Speed_ref+1500)/6,1000);. ^( N# n+ h3 K* v
  8.         MC_StartMotor1();
    . |3 M/ l( u2 z0 b
  9.     }# Z/ e3 E4 k8 V' x- g! k
  10.     else
    , \- ~- _: h* m5 c: A  f7 P
  11.     {
    ( A4 X/ R/ D: w7 L* R: S- _
  12.         MC_StopMotor1();
    + o5 P& v  q6 S. p7 r) \
  13.     }
    0 F& v2 f- C' m! e0 n& R
  14.     HAL_Delay(100);+ T0 {* Q6 [7 v; [, `
  15. }
复制代码
主函数代码:# p( d/ l8 }6 V) Q9 _8 J
  1. /* Initialize interrupts */3 t7 D# {3 V; x$ G! j
  2.   MX_NVIC_Init();
    # i# n0 y3 X) Y9 T1 C5 v+ E* j
  3.   /* USER CODE BEGIN 2 */
    " Q4 k0 v! k& `
  4.   MC_SPEED_REF = &PWM_Handle_M1._Super;
    ( y1 P4 ^% G0 Q2 J7 }" n7 ]
  5.   /* USER CODE END 2 */
    ! s; y; c; n" I# B
  6. 3 S; {0 w3 W2 F" h+ I% r
  7.   /* Infinite loop */
    * i! U! V1 |( T( ?
  8.   /* USER CODE BEGIN WHILE *// {5 l" P& _; D0 }9 P" y; T; ]( B8 ]
  9.   while (1)
    - V# I- r( ^  K7 ~+ k( B
  10.   {) m  u  Y, x% R( f7 g7 P% c
  11. + Z$ U  H' ~" {+ X' [0 Y3 t: ~, l
  12.       if(GPIO_PIN_SET == HAL_GPIO_ReadPin(LED11_GPIO_Port,LED11_Pin))1 c% d2 E* n' d( u$ p/ ~4 _8 Z) c( _
  13.       {
    & U" Y2 F& M/ r/ Z
  14.           task_4();
    6 F/ g4 Z8 f7 f, @
  15.       }
    " B# [/ V7 ~4 p1 i, @
  16.       else( H$ q+ k" Z! T0 e/ ~& Q2 X
  17.       {
    ( k$ A2 l  d2 h7 b
  18.           MC_ProgramSpeedRampMotor1(0,0);
    6 Z' U4 ]& _' S% N7 H: h7 P
  19.           MC_StopMotor1();4 p9 o( d  {3 l( y
  20.       }
    ( P! B7 a. `: j, G1 ^! ~
  21.   /* USER CODE END WHILE */
    # j. F5 f3 Q* F) d" {& {7 U: z

  22.   d: U# e2 Q2 w2 B  a1 v# _
  23.   /* USER CODE BEGIN 3 */
    * W7 m' m2 P; @$ ~7 h+ R

  24. 1 k  c& a. Q7 M0 H7 K) b8 N
  25.   }
    2 a+ {& p4 R) i3 E1 \" T/ `
  26.   /* USER CODE END 3 */
    * L0 U- N( Y5 ^2 v4 [6 l
复制代码
在这里稍微解释一下代码:
Speed_Adc是存储ADC采样值的变量,Speed_ref变量通过ADC采样值转化为速度设定值,MC_SPEED_REF是一个指针变量,用于获取ADC初始化设置,R3_1_F30X_ExecRegularConv这个函数在r3_1_f30x_pwm_curr_fdbk,c这个文件中,用于处理规则ADC采样。速度换算这里可以没什么说的。速度设定的时候加1500偏移是有原因的,当设定速度过低的时候电机系统根本不能正常启动,这是我尝试设置的时候所能达到的最低启动速度。
5 p8 e% V- ]  {2 o
实验现象:
旋钮调速转速跟踪波形.png
从实验结果看来,这份代码默认速度PID能很好的跟踪给定转速。
我发现一个问题,代码里面在电机运行结束之后有些变量好像没有清零,这个问题留到后面在研究吧。
' Q0 R; m4 `+ W' Q
本帖两个任务分享就到这里,欢迎大家留言讨论。
( Y- H. ]- w. q& j9 `
5 ?" T# }) m( C0 z
* f- X9 `& g& c& v9 i( T2 G

% s" h8 R: O/ w$ d9 R0 ]! u8 m' V6 Z, y/ t. j0 U- @
1 收藏 2 评论118 发布时间:2018-9-2 19:17

举报

118个回答
子曰好人 回答时间:2020-4-15 09:28:07
ysx584085668 发表于 2020-4-14 23:231 v; \* N, e# R7 g7 f, ~2 z
太感谢了,我发邮件给你看吧

$ K) n6 N& d* K/ H+ _8 m" i看了你发的邮件,新版本的MCSDK生成的代码没有留ADC规则转换的函数接口,可能需要你自己去写了,我把我这边生成的文件发你一份参考吧
: J( P# `, X" }7 z0 u! V r3_1_f30x_pwm_curr_fdbk.zip (16.66 KB, 下载次数: 10)
passby328 回答时间:2018-11-6 11:04:29
子曰好人 发表于 2018-11-6 09:35
! L, x7 V2 O- c, x* U: e) E1 I+ VSDK5.1.3生成的代码里面没有regular_conversion_manager.c这个文件,5.2.0新增了。获取ADC值的代码是几乎 ...
9 |7 Y% y& o& a! X' Y2 t/ J: G
1.我之前参考您的函数,如果一直不断在执行转换,会影响电机库的控制时序导致无法开机,后来改为500ms一次,就没有问题。后来检查regular_conversion_manager.c中的内容,发现用户ADC的转换应该是电机库的状态机在调度的,如果连续不断转换或者没有走相应的接口估计会有问题。$ p1 p: |* ?  R7 r( s# |
2.电机Workbench里面有设置OCP参数,看了原理图应该是通过体验板上面的L6230的内置比较器以及SMT32片内的ADC实现的,但是实际中的程序并没有提供类似的功能。后来查看了代码,OCP保护是通过L6230产生的FO信号进行处理的,不知道我说的是否有偏差,还请指教。
zhdzhd 回答时间:2018-9-2 22:27:32
代码规整,有功底,佩服!6 ]" G+ {, t7 W# {# s8 X
大佬也会有纰漏啊
  c' j9 [1 g4 x5 ~4 g
2 Q3 N0 D5 [9 ?5 P/* Infinite loop */
8 P, f4 L* a: J9 V9 }3 J! o; ]+ a6 ?* @  /* USER CODE BEGIN WHILE */- V+ y6 d  \. B6 F) V% N
  while (1)6 {' H/ i$ j3 h" U, A# q
  {1 m# f6 ~+ v& M4 K8 T5 d! k
      
4 M; ]" J1 o( X$ z. L% J      if(GPIO_PIN_SET == HAL_GPIO_ReadPin(LED11_GPIO_Port,LED11_Pin))( F2 E$ `. Z" `7 W" j3 W
      {$ x# U# F7 t) `0 [" w$ n* Z6 F
          task_5(); ------>task_3();
2 q0 s9 P- b4 F( F/ N      }5 ^! ~$ b! n* k; q3 v
      else. Z% X5 n- \: J$ d- B1 W
      {4 X% w1 [; \3 A: a+ s6 }6 K
        MC_StopMotor1();2 q' b. K( a/ M, A5 U
      }      
8 H* P4 B7 G8 |1 p+ k( W+ w  /* USER CODE END WHILE */
子曰好人 回答时间:2018-9-2 22:36:27
zhdzhd-174422 发表于 2018-9-2 22:27
' ]% O2 D4 U4 [5 E/ |7 m0 C代码规整,有功底,佩服!
: |8 M, N6 L9 H& J' S8 C大佬也会有纰漏啊
# `/ }; D# }8 |5 R
不好意思,感谢指正
STM1024 回答时间:2018-9-3 10:24:43
哈哈,和你观点一样,很多故障报警,都是报的speed feedback,我在测试的时候,连堵转都试过,原本以为是电流过大报警,但没想到居然还是speed feedback故障
子曰好人 回答时间:2018-9-3 10:45:56
stm1024 发表于 2018-9-3 10:24/ I, u, [$ W- D' m, ]3 G
哈哈,和你观点一样,很多故障报警,都是报的speed feedback,我在测试的时候,连堵转都试过,原本以为是电 ...

1 J! ~- |( K& L3 i4 w3 q* R  W去研究一下电机库生成的故障触发机制代码,也许就能明白了,搞清楚是怎么回事之后就能自定义故障报警了
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()?. V' r! D6 l# K$ H$ _7 C
子曰好人 回答时间:2018-9-4 22:54:20
LT-386596 发表于 2018-9-4 18:38
2 V8 a  A0 D5 P, lSpeed_Adc = R3_1_F30X_ExecRegularConv(MC_SPEED_REF,ADC_CHANNEL_12); 5.2.0 找不到  R3_1_F30X_ExecRegu ...
8 `8 q) D# a+ S  g1 ]. @
在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" j. t* o4 P4 M% L2 v
VR连接的脚感觉像是PB1,从电路图上来看.
' L% q# d. G$ v; k4 a
手误写错了,已更正
花落莫相离 回答时间: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* ]0 a# q5 X; {* k
楼主,我不太懂Speed_ref = (15500*Speed_Adc)>>16;这段程序中15500的作用时什么?
! h7 [& Y& C7 @* W1 `
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:598 P6 y, ^9 _2 |3 C8 P& K  ^
大神,不知道你有没有注意到有一个小细节,这个USB必须要插在主控板上整个程序好像才能运行,然后不插USB的 ...
  g  g- W5 L/ H0 c+ z" y0 g
没遇到过,我的一直是正常的呀,没有USB连接也能正常运行
晴空 回答时间:2018-10-29 15:53:32
学习了  哈哈
花落莫相离 回答时间:2018-10-31 13:51:43
子曰好人 发表于 2018-10-26 09:16
. b5 g* k. I5 Z2 T- S4 a( b15500是电机能达到的最大转速,Speed_Adc的最大值是4096,ADC采样值和速度参考值的换算方式为:(Spped_re ...
* h0 E- _, T% u# ~
多谢楼主解释了。

所属标签

相似分享

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