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

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

[复制链接]
STMCU小助手 发布时间:2021-8-5 12:39
在使用带霍尔编码器的电机时,需要捕获脉冲,来达到测电机的转速的目的,捕获脉冲的方式有很多,我刚开始选用的是定时器捕获,后因需要测度多个电机的速度,STM32F103的定时器感觉不够用,所以选择EXTI以达到捕获高电平的目的,再用TIM定时器中断计时。
! i: P, ~- F9 K3 G4 R1 A) g8 Y& [# j' B
7 ]0 Y' [9 T3 }8 Q+ {) s

. h8 U0 u" Q' ~5 Y1 i- k# h以下为EXTI配置2 {5 @* Q2 _2 B
  1. <font face="微软雅黑" size="3">/* Data defien ---------------------------------------------------------------------------------------*/7 l" H+ T# Z- \& n, E
  2. uint16_t motor_1_At = 0;        //电机A相的脉冲数3 ?7 w7 K* F6 l+ ^
  3. uint16_t motor_1_Bt = 0;   //电机B相的脉冲数0 J* T8 P* M3 s1 u: R- W
  4. uint16_t speed_motor_1;         //电机的转速
    3 ^  D& x" ?( R5 F4 M$ v9 U$ ?
  5. ( ^# h! k- r( i6 o! N! E1 C
  6. /***# d. N/ j5 ^8 \4 Y7 ?- [* U
  7.   * @name speed_measure()
    , R; s  S& C, \4 E" b0 v
  8.   * @brief
    , G1 {$ M/ N) {% ~+ _, o
  9.   * @param NONE5 x* H) t1 F! j/ l" V/ V; H
  10.   * @retval NONE; u& ^/ }( ?( S% y4 v4 l( l
  11.   */' j2 Q+ l8 W+ x( y- U
  12. void speed_measure_extix(void) 0 \0 P; R. v1 r2 B6 \7 K' o
  13. {
    + E+ z2 X! N  L! c. i% v) V/ s/ j' h! J
  14.     EXTI_InitTypeDef EXTI_InitStructure;  B* V+ {. {/ _3 y
  15.     NVIC_InitTypeDef NVIC_InitStructure;
      H$ g) m% T+ F" t2 w6 }! m9 Y; g
  16.     GPIO_InitTypeDef GPIO_InitStructure;2 g# [/ z  p4 D
  17.    
    ) K' d( J. b# d  B+ Q9 i
  18.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG|RCC_APB2Periph_GPIOD, ENABLE);     //使能PORTA,PORTE时钟
    / S8 W8 M: n3 ]1 m4 X
  19.     3 I+ T& Q+ K6 \! A3 ]) d
  20.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);3 Q8 q5 V: K$ Y$ G5 W! o1 Z
  21.     ) x; P0 X2 C1 N6 q/ |, ~4 f* V: T
  22.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;                  //motor_1_A-->PG9
    + A  b1 J) T# A3 i! v1 n: A
  23.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
    : ^; x7 T6 o( U" m/ K( U3 s/ b
  24.     GPIO_Init(GPIOG, &GPIO_InitStructure);" X1 t( _3 b' f9 l5 a! r
  25.    
    ! h$ ^! N; h, \" z8 Y* F, g
  26.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;                  //motor_1_B-->PD8. Z$ M4 ?7 }2 V; {. f$ T
  27.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
    1 n6 q! F3 |( ^$ f
  28.     GPIO_Init(GPIOD, &GPIO_InitStructure);- w( R' P8 k- h7 I8 q; s8 b' Y
  29.     . H0 L: a9 G# W  [7 A
  30.    
    $ x# ~- u) o) w9 |9 Y( t
  31.     # C* R. M. O8 u
  32.    
    9 M$ M: P( \' Z4 o3 x: [8 Z9 V6 J
  33.     GPIO_EXTILineConfig(GPIO_PortSourceGPIOG,GPIO_PinSource9);
    : Y5 t! d; c' T, ?
  34.     EXTI_InitStructure.EXTI_Line = EXTI_Line9;
    % o7 V' b2 H0 B0 h+ T% G3 }
  35.     EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;, T7 g5 L1 e. x8 ^8 [/ {# [0 Y) n
  36.     EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
    6 A" i  p  ]8 D2 u9 M9 Y3 J( ]
  37.     EXTI_InitStructure.EXTI_LineCmd = ENABLE;% ?& o0 `+ H% `" ~% Y, ^
  38.     EXTI_Init(&EXTI_InitStructure);7 r6 r; h0 |" L' \5 `6 F
  39.     . ^$ W9 v* k9 c4 t
  40.     GPIO_EXTILineConfig(GPIO_PortSourceGPIOD,GPIO_PinSource8);1 v+ _. w9 r; o, V+ b  m+ N  M
  41.     EXTI_InitStructure.EXTI_Line = EXTI_Line8;
    ! {) I. a3 J2 ~  Z
  42.     EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    ! [; l/ W" H9 Y, m
  43.     EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;$ }/ x( J3 g! O5 a
  44.     EXTI_InitStructure.EXTI_LineCmd = ENABLE;4 [9 F. ]  j" b7 y7 n: S
  45.     EXTI_Init(&EXTI_InitStructure);2 S1 V: j$ ^. M) `5 r2 j* g7 o
  46.     ( _) ~3 o8 z* G, ]2 Q7 }* b
  47.     NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;% |5 n$ C- N3 T, _
  48.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;
    " i" Z/ `, }  a1 R
  49.     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0X00;& I" _0 L0 O/ Z' E5 K- K8 F" C
  50.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;2 p5 U, `% R2 C7 x% R( `
  51.     NVIC_Init(&NVIC_InitStructure);    0 A  W! T8 \, [1 T$ `7 y
  52. }
    3 x, D, g3 Y! l
  53. 2 v- k& k" y( ~6 `) k; Q
  54. void EXTI9_5_IRQHandler(void)
    9 b1 @% W0 b3 I+ v
  55. {
    7 q: C6 W! m4 v; z/ G- r( k
  56.     if(EXTI_GetITStatus(EXTI_Line8)!=RESET)//判断某个线上的中断是否发生
    ; v3 s3 T1 H) ~; o
  57.     {   
    $ v0 p: [- k, g/ S
  58.     motor_1_Bt++;0 h. E+ P& \' U  j" v
  59.     EXTI_ClearITPendingBit(EXTI_Line8);
    , D, m: b5 O' `$ [
  60.     }: _5 m5 k  V6 w4 D8 n' w6 o
  61.     if(EXTI_GetITStatus(EXTI_Line9)!=RESET)//判断某个线上的中断是否发生
    ! {) i' I+ O; e! }9 U8 ]8 H# `
  62.     {   
    ( [6 o, F- U4 R( B
  63.     motor_1_At++;$ v2 J9 e7 l; t+ ^9 `/ O6 U2 `+ u
  64.     EXTI_ClearITPendingBit(EXTI_Line9);
    " C) \0 m8 ?9 G* |4 V- |3 m
  65.     }9 l4 ~; v0 B0 u' j" |" T
  66.    
    3 j6 T, W! l) |3 x
  67. }
    5 [6 j6 k# p1 Z! u
  68. </font>
复制代码
因为unsigned char类型整数表示的范围为: 0~2^8-1,所以需要用定时器进行置0,以下为代码:8 |" x3 k% `5 N* p- P1 w" k
  1. <font face="微软雅黑" size="3">/***
    " `. B! }4 m& p6 A$ f0 |
  2.   * @name speed_measure_time()
    6 O9 F+ t- F: P% {
  3.   * @brief  TIM2
    ; o2 u7 T9 ^: l2 C2 H
  4.   * @param NONE9 P" y7 A4 I' B. N# l+ P0 O6 r6 A
  5.   * @retval NONE: F) w& Y5 A2 N
  6.   */
    / g3 k& H- q3 x, M+ r
  7. void speed_measure_time(u16 arr, u16 psc)
    ) B7 t. J7 [" L# N; p- n
  8. {
    / j: R& b2 j! d0 g
  9.     TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;, z: ^/ r; K  _  B5 _( A
  10.     NVIC_InitTypeDef NVIC_InitStructure;. I$ W, K6 x, T2 Y. j8 ]
  11.     RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
    1 {; ?" ~* [/ P; L; a) w" }0 l
  12.     5 p5 q6 a+ A0 T. C! f
  13.     TIM_TimeBaseStructure.TIM_Period = arr;
    1 a, m( |% a& t: ~
  14.     TIM_TimeBaseStructure.TIM_Prescaler = psc;" U0 u1 e& s2 P  L2 v" I0 o' l
  15.     TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;9 O( k3 v& _9 x2 A, X, S
  16.     TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;! ]- A$ ~+ [% ~" ]0 C; x: D8 v
  17.     TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);3 k' l' B% J9 X0 Z# P' u! g
  18.     TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);! Z. m2 O+ b8 Q6 E2 o' T
  19.     1 i5 f1 _, ^4 x+ `1 _
  20.     NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;8 I9 ^; k! B( z; U1 m6 I8 H8 Y0 d
  21.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;% Y$ s* X, B) ?
  22.     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  o; m7 r! }3 A3 p- t7 G( X
  23.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;2 ?% B/ L; h1 L: M% {6 ]
  24.     NVIC_Init(&NVIC_InitStructure);
    0 w; L0 d0 Q. S: G8 p4 c
  25.    
    / J# [! d" W% }/ H1 m
  26.     TIM_Cmd(TIM2, ENABLE);
    ' V! V0 i# _3 P# }) }7 A4 ^! U; A
  27.    
    1 _4 `& Q9 M* s
  28. }
    8 S- J$ K% P$ E5 T  b, \

  29. % r+ V7 ^& \: A( X1 K
  30. void TIM2_IRQHandler(void)
    ! X" \' H9 k# D
  31. {
    2 i' N' _: X! J% w% Y) O
  32.     if(TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
    0 Z0 X6 ^  e5 M- L
  33.     {
    / |# N' x- S  R* Y' `
  34.         TIM_ClearITPendingBit(TIM2, TIM_IT_Update);5 B/ V2 ?/ |, Y; ~
  35.         speed_motor_1 = (motor_1_At + motor_1_Bt);: X7 N6 i/ L4 v4 W
  36.         motor_1_At = 0;
    2 h( J6 t& [; F( Z: f0 R
  37.         motor_1_Bt = 0;! M* I4 r6 F) `- k' S$ I4 t
  38.         
    2 `; i) }2 D  u5 e
  39.     }% N- V) G# \$ g1 v" b) k
  40. }
    % |6 Z' f' F) @2 c  `2 i
  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) ;
    5 z- m3 b& M% k' y4 r% \1 ?
  2. void speed_measure_time(u16 arr, u16 psc);</font>
复制代码
% T! F# [+ X) c# O' P3 f
( H& X1 K' D& H
收藏 评论0 发布时间:2021-8-5 12:39

举报

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