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

stm32f103测脉冲数用于带霍尔编码器的电机测速

[复制链接]
STMCU小助手 发布时间:2021-8-5 12:39
在使用带霍尔编码器的电机时,需要捕获脉冲,来达到测电机的转速的目的,捕获脉冲的方式有很多,我刚开始选用的是定时器捕获,后因需要测度多个电机的速度,STM32F103的定时器感觉不够用,所以选择EXTI以达到捕获高电平的目的,再用TIM定时器中断计时。" D% K8 X. J1 H( c5 g

9 Q- x( s( Q) G8 a& I. Q) n3 G

% _/ w) o4 O6 ~0 i+ }  f以下为EXTI配置
2 o3 Y( ]1 X0 t5 h# P
  1. <font face="微软雅黑" size="3">/* Data defien ---------------------------------------------------------------------------------------*/# X+ S* O' t3 E6 V5 C- A
  2. uint16_t motor_1_At = 0;        //电机A相的脉冲数0 W7 j3 z! P4 J. p+ }
  3. uint16_t motor_1_Bt = 0;   //电机B相的脉冲数
    ' h- G9 g5 y1 a7 ], Z
  4. uint16_t speed_motor_1;         //电机的转速$ m4 w3 n7 U' q9 W3 M( U6 f1 N
  5. 2 h2 n" i0 Y: B# }! t' Q. \! K. I
  6. /***
    0 F$ |: g  u# k& Z
  7.   * @name speed_measure()( K& t2 ?# ]3 ]3 E5 n
  8.   * @brief
    , b. N/ W8 g2 [3 C
  9.   * @param NONE9 L9 k, Y- l2 N  l- o& s
  10.   * @retval NONE
    ( z  H# x7 `9 L$ _  u* B
  11.   *// J% h( N; C% K1 O1 \# ]8 }$ _/ ~
  12. void speed_measure_extix(void) ' T) Y4 R- p  V! z+ s+ f/ }" W
  13. {
    * M% K) k' c- h5 G% {% e5 v
  14.     EXTI_InitTypeDef EXTI_InitStructure;
    6 j4 X) ^7 q7 w8 n- B+ G2 Z
  15.     NVIC_InitTypeDef NVIC_InitStructure;
    ) @( d3 b5 t, B& r0 C5 ]; b# Y$ `/ s
  16.     GPIO_InitTypeDef GPIO_InitStructure;
    8 R# |8 K+ t/ W, _: X- ~( m# b# d) X4 H
  17.     8 @& X& j0 }& n; Q( g- b4 s$ F, p
  18.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG|RCC_APB2Periph_GPIOD, ENABLE);     //使能PORTA,PORTE时钟 2 N9 B% H! h' v4 h
  19.     + r. s5 J  p8 ~& W- W
  20.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
    # R# j0 u% C8 D0 C/ U
  21.    
    9 Z4 B8 S- M  M. V  I- q- S
  22.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;                  //motor_1_A-->PG9$ j& `* ]+ J0 ?1 y: x5 d
  23.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;; C! q* c6 B1 L+ p0 B
  24.     GPIO_Init(GPIOG, &GPIO_InitStructure);
    ! L; ^, L6 O# e' }
  25.    
    7 i9 m+ R, z( [- r3 S9 W
  26.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;                  //motor_1_B-->PD8( V: w- X' Z: u7 `: V
  27.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;8 u% P6 V" p) Y2 t, M
  28.     GPIO_Init(GPIOD, &GPIO_InitStructure);2 Z4 [! [4 o: U
  29.    
    . i: f0 A# d1 g2 c
  30.    * \/ ]0 k9 [2 Z4 [# I6 B4 @, M
  31.    
    : Q/ W, F4 i: x) k0 g1 e5 l3 E" B% K
  32.     6 Z) Z, h% M9 t5 W% {* i! ^
  33.     GPIO_EXTILineConfig(GPIO_PortSourceGPIOG,GPIO_PinSource9);
    : F- D% ~  m% u% v! x$ t( D
  34.     EXTI_InitStructure.EXTI_Line = EXTI_Line9;
    / q2 |: V( L$ H- d
  35.     EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    7 k1 I+ W8 S, `5 z6 O
  36.     EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;+ r: o9 k1 @2 L/ A
  37.     EXTI_InitStructure.EXTI_LineCmd = ENABLE;9 @, h2 d) y% h7 e% T6 E
  38.     EXTI_Init(&EXTI_InitStructure);
    0 k2 C) e7 A" P8 J2 A
  39.    
    2 I1 T8 l) d& `$ H! S
  40.     GPIO_EXTILineConfig(GPIO_PortSourceGPIOD,GPIO_PinSource8);- e+ B3 C! j- K4 @( q0 J
  41.     EXTI_InitStructure.EXTI_Line = EXTI_Line8;
    9 k" n& [+ _6 ^4 j0 G+ F
  42.     EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    1 o, B& o2 W# G2 X- m
  43.     EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;; A: u9 B9 g  N2 D1 \7 ?" k6 L
  44.     EXTI_InitStructure.EXTI_LineCmd = ENABLE;
      `# Q2 ~( M* C/ F1 ~6 V
  45.     EXTI_Init(&EXTI_InitStructure);' ^; m$ e  [3 l
  46.     ! r/ d( J& A, Y) A, i
  47.     NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;' Y/ Z3 S( [" @# V! n9 K/ D1 o/ `) Y
  48.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;2 y2 y$ X" Y) A
  49.     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0X00;
      C! s' M! ]/ p! w
  50.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
      I/ v: ~& E3 x4 {& a) s" c
  51.     NVIC_Init(&NVIC_InitStructure);   
    $ x- A4 j. B, m- Y6 B( _' T
  52. }- N# h* R2 Q( u$ N
  53. ; M. x  }/ O. ~
  54. void EXTI9_5_IRQHandler(void)
    - G5 Z6 C: Q3 F& W
  55. {, X5 G# N, e7 `6 D4 p* M! p
  56.     if(EXTI_GetITStatus(EXTI_Line8)!=RESET)//判断某个线上的中断是否发生
    ! F- P+ [9 _3 @- U3 Q+ X* S
  57.     {   
    4 B' b1 a9 B/ B. C9 J0 G
  58.     motor_1_Bt++;0 `4 j' C4 W. `, w
  59.     EXTI_ClearITPendingBit(EXTI_Line8);- r4 s1 B* W5 E, P) L2 Q, @( Q
  60.     }) p7 X4 M/ q& C% j" I1 c; F
  61.     if(EXTI_GetITStatus(EXTI_Line9)!=RESET)//判断某个线上的中断是否发生
    3 }7 s0 F" ~8 B; U! }( c: _5 X
  62.     {   
    ' ?& W9 s. h% s# C$ }+ T, j5 j' _
  63.     motor_1_At++;
    * x; q( H4 q% M- f7 r& W1 ?
  64.     EXTI_ClearITPendingBit(EXTI_Line9);
    1 f1 X( j4 _5 E5 e
  65.     }6 F& K5 x' |5 c7 p
  66.    
    4 Q5 M  ~1 g6 j; R
  67. }0 Y9 [: n" G. ^0 g% x$ g
  68. </font>
复制代码
因为unsigned char类型整数表示的范围为: 0~2^8-1,所以需要用定时器进行置0,以下为代码:. j& X, q) o# }2 x+ i
  1. <font face="微软雅黑" size="3">/***1 z& }- j4 T, D! G8 J
  2.   * @name speed_measure_time()3 E* \& M6 E' X8 |9 t
  3.   * @brief  TIM2
    # S- k6 i  j0 \" Q- |
  4.   * @param NONE6 H. x! p- ^7 M& U
  5.   * @retval NONE. v8 g2 m6 e& S- z: |) v# }/ F
  6.   *// m3 X/ P( Z6 z5 g$ J9 {- k/ M
  7. void speed_measure_time(u16 arr, u16 psc)& w& \- |! e) M
  8. {0 Y+ g2 u0 k, c$ G1 F9 u3 |
  9.     TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;9 ^, Z9 X8 n# p7 |; x  j
  10.     NVIC_InitTypeDef NVIC_InitStructure;: P4 U: C" u9 d
  11.     RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);3 r- J" G1 F. b' r' r+ L* _* ^3 x
  12.     # U% [" ~/ {2 R& o$ t( r- M% l
  13.     TIM_TimeBaseStructure.TIM_Period = arr;
    9 O, [+ W, e7 A" e9 J( @
  14.     TIM_TimeBaseStructure.TIM_Prescaler = psc;3 |6 Z5 h0 P4 P$ k% }* B7 {; u
  15.     TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    7 t6 j3 T( C' ^! T: o& D& C6 H
  16.     TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    + f1 `% R2 h6 ~# g" _% n9 T+ y
  17.     TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);) a, Y/ Z: a( r% i% V1 I1 L  D6 Z
  18.     TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
    / a+ O8 M3 g0 i2 t6 y& K
  19.    
    2 V) ?$ F% B/ w1 ~, K2 {
  20.     NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
    / p; ]& e: w* v$ f% V3 K) U# U
  21.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;/ S# {6 _% m1 ]) V
  22.     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
    ' ^0 n& M$ ]1 h8 h2 b( V/ k
  23.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;! T: J1 D9 |' E2 l) ?+ }! n
  24.     NVIC_Init(&NVIC_InitStructure);$ p/ d) A( _, F. M  A6 p. t- f4 y
  25.    
    ; g) \# @; R8 m3 u0 S  L+ E
  26.     TIM_Cmd(TIM2, ENABLE);* R$ K" }( y0 R/ V
  27.     # O( F* M, ]' k' @9 z
  28. }& D7 S4 p! S* o% Q/ a& Q3 ~0 R  j

  29. , A" W0 M. y& J9 J+ O/ d
  30. void TIM2_IRQHandler(void)7 [8 m: x% y7 [' v) |# d" Q. k
  31. {
    & T+ _9 u  R7 i8 U+ ?" G9 Q& w* x
  32.     if(TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)! C# q7 ]9 [  d' ?
  33.     {
    ) `- C7 J' P: {4 I
  34.         TIM_ClearITPendingBit(TIM2, TIM_IT_Update);' ?2 S* A, @3 H- b1 @2 A
  35.         speed_motor_1 = (motor_1_At + motor_1_Bt);. |: j7 }' ^" u9 o$ V8 [
  36.         motor_1_At = 0;
    8 C( y8 z% g1 m6 ]
  37.         motor_1_Bt = 0;1 H! d; B$ C* ^  l3 C4 j# R
  38.         5 {) r  Q8 f" T& b  u
  39.     }
    2 B% h) |' e* v6 X# k6 p, V
  40. }2 @2 Z. n! w1 E. @% H2 o2 k0 N" Q
  41. </font>
复制代码

代码中的speed_motor_1为设置时间内的电机A相与B相的脉冲数之和。

定时器时间的设置可以通过(u16 arr, u16 psc)实现,附上计算公式

T =[ (arr+1) + (psc+1)]/72000000

使用时直接调用这两个函数:

  1. <font face="微软雅黑" size="3">void speed_measure_extix(void) ;8 i; [) ]0 B- |( }+ e+ }
  2. void speed_measure_time(u16 arr, u16 psc);</font>
复制代码

/ I1 W% Z+ s$ |: l/ K" j
6 Y" b( k7 e+ ?7 \; d7 c1 \/ k
收藏 评论0 发布时间:2021-8-5 12:39

举报

0个回答
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版