EDA365电子工程师网

标题: STM32编码器模式计算减速电机AB相脉冲个数 [打印本页]

作者: zhoumi    时间: 2016-5-5 11:24
标题: STM32编码器模式计算减速电机AB相脉冲个数
小弟用STM32定时器编码器模式计算减速电机AB相脉冲个数,目的是想通过 AB相脉冲的上升沿和下降沿触发,然后计数器加一,那么如果检测到一个周期,有AB两相,两个上升沿两个下降沿的话,计数器就会四个 加一 。现在的问题是检测出来总是出现两次加一,只是检测到了上升沿,感觉没有检测到下降沿呀。希望论坛里的大哥们帮忙解答一下。' Q! C' P* M5 o# }" T

% ?$ {2 F  \7 U! B, zvoid TIM3_Int_Init(u16 arr,u16 psc)
, z) K, B0 b7 w+ M{  R4 I8 Y( ?0 [+ F" S' E& B/ p
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;; \0 U" I  k/ v% {8 o) O
        NVIC_InitTypeDef NVIC_InitStructure;; t' k& B& ], w

3 ?) r4 ]6 z& n+ ^; G        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能9 ]) b8 w: t/ r! a# w; l% H
        4 A) P/ x% b" y5 K5 i
        //定时器TIM3初始化
- k) A8 \0 a4 M" U( |6 p- \' F        TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值        & N; T& _& ]' v- M3 z4 a
        TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
/ \- a  _: o/ o$ \        TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim. {2 H1 }5 n1 y, p4 }# D
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式6 u2 t7 c* e% l0 Z* e7 \' c% p
        TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位        
% h! c3 i- m/ [- U. i1 j5 _' q// TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Trigger);//选择TIMx从模式
5 a0 h7 ^2 O/ P; ~        TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); //使能指定的TIM3中断,允许更新中断9 |% D$ h+ E& Q# P5 a6 v* Z
0 B  k, Q; t8 n
        //中断优先级NVIC设置
, O& G1 ?& N& P        NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  //TIM3中断" B) ?  b7 P" g# t/ W9 F" d7 r
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占优先级3级& ]3 ~  j- y/ j, u
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //从优先级3级
- |( }( P" j3 f! p. t% [+ ?, i        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
9 v0 D5 K- D1 Z3 T0 K  d        NVIC_Init(&NVIC_InitStructure);  //初始化NVIC寄存器
5 M! K9 C  j4 e! f0 @+ T
: Z/ z! U; l" w% y; P* x  //TIM3_Encoder_Write(65416) ;
8 W2 p8 G$ g/ U1 y  x5 m        
5 J4 s% j, f* N2 ?3 c$ I/ m        TIM_Cmd(TIM3, ENABLE);  //使能TIMx                                         3 u3 j7 ?3 M4 y+ ^. \. ?
}
0 \# D- h  [% S4 i$ U$ X
+ [  w/ \) Y2 @# K7 ^+ l
/ b5 c* p4 t9 L4 [2 W
# E/ N! T: I$ Y+ J% |; E6 K. W- Q+ W/**********TIM2_Encoder******/
% F% @8 w6 U9 p4 v5 C* I- _8 ~3 Q% Z+ v. M, Z: ?/ B
void TIM2_Encoder_Init(u16 arr,u16 psc)2 w3 T; |8 X& C9 {1 I
{
; ?! c9 l+ y/ `  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;/ p8 n! S9 U2 t% l
        NVIC_InitTypeDef NVIC_InitStructure;
. l; f" c9 I# p' k0 F' R        TIM_ICInitTypeDef TIM_ICInitStructure;* p, k4 l" i, e7 E. @; f6 j
6 R/ q4 d( C% M
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //时钟使能
) n0 u7 N- m* F/ `7 D0 U        & w9 n9 M5 O7 o+ Y
        //定时器TIM2初始化
. m, J; `' |& Y1 y        TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值          |1 z) U5 D+ Q0 u
        TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值$ n+ x6 Y* j. h3 J
        TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
( H( g" K+ L1 I        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式  O5 ]9 U, b) W0 e4 i
        TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位3 R  K, B# Y3 W/ v( L2 S: x9 [
        //TIM_SetCounter(TIM3, 0xFF88);//设置TIMx自动重装载寄存器值
0 G  {3 p( {0 z: l" b+ [2 ]6 Q+ |# `' i( D( c  \, c
        TIM_EncoderInterfaceConfig(TIM2, TIM_EncoderMode_TI12,* s- ]# a" A1 e! I3 C  L
                                TIM_ICPolarity_Falling, TIM_ICPolarity_Falling);& C6 E: V, a% ]3 B
        TIM_ICStructInit(&TIM_ICInitStructure);! I( {# g) Y7 Y- z$ M! ^' j
        TIM_ICInitStructure.TIM_ICFilter = 6;
" r7 W' r# ^. f# Z0 H        TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;        //上升沿捕获
8 `+ a  P( Z3 m5 p9 o        TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;         //配置输入分频,不分频
0 a( ?0 w( @6 w5 x        TIM_ICInit(TIM2, &TIM_ICInitStructure);0 F, ?# S# |+ C: J3 U5 A$ ~, ]
  //TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Trigger);//选择TIMx从模式
% W% Y+ M$ Y: o9 x3 Q7 ?* m  TIM_ClearFlag(TIM2, TIM_FLAG_Update);* e% u( g3 F0 [1 K7 A# k; p  M1 C
        TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE ); //使能指定的TIM3中断,允许更新中断! e4 P" E  f% I& v% v0 V: d
  //TIM2->CNT = 120;
/ U" U1 Q' f! V" c3 S" `        //中断优先级NVIC设置1 C' J4 z  V! d5 \
        NVIC_InitStructure.NVIC_IRQChannel = TIM_Channel_1|TIM_Channel_2;  //TIM3中断
2 Q" n1 F3 v  w0 E7 X        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占优先级3级
' F: d  R; k+ p0 ?! Y! H  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //从优先级3级9 o# K6 D% |; u; L: \! d3 `9 G
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
* V. i0 G. a2 z  NVIC_Init(&NVIC_InitStructure);  //初始化NVIC寄存器
2 o' A& P$ r+ F+ h0 E9 w/ T6 C' x! ^) }9 @: C
  //TIM3_Encoder_Write(65416) ;
% v* ]2 z  C/ j. I) r        
1 z1 L2 g; {* K8 h2 X        TIM_Cmd(TIM2, ENABLE);  //使能TIMx                                         
0 e6 {3 I9 j+ W: B) w- y}
* d4 B. E: w4 B) U" ^+ Z4 ^- v" e1 L! P8 E4 J, |
6 b- Z. G& [8 G* P5 B. F
//定时器3中断服务程序: P, I2 |9 J- h9 A$ ]7 A3 h
void TIM3_IRQHandler(void)   //TIM3中断) M- f9 V* j& |6 Z. d3 r
{! J- c- t- R* y3 }
        if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)  //检查TIM3更新中断发生与否( Y& K+ v* E, Z- U% ^" a0 f5 A
                {
6 P2 s1 p% c( p- g                TIM_ClearITPendingBit(TIM3, TIM_IT_Update  );  //清除TIMx更新中断标志
& Q( g4 O6 ^9 q& e3 b( q    TIM2->SMCR ^= 0x8000  ;0 K0 c/ V* r. q  k1 L' l
( R# q4 a) x1 u  c
                        EncVal = TIM_GetCounter(TIM2);, N8 k. p  G2 \

( X1 e  t" D$ O! H' |2 |3 _' I! m                        if(EncVal>=240)3 h( M9 v/ x$ w3 ?/ [" N/ D
                        {
) N1 G: O2 C( v. F& [0 h2 A: s         EncVal = 240; % Q* I2 H- v. q( y6 G/ R1 d
      }& y" _0 r: r7 ]# |4 V
                         LCD_DrawPoint(i, 5+EncVal);
2 I4 P+ q$ @  q                         if(i==320)  {  a" l# e; ~
                         {  
. b8 L% l/ p/ M& [, h2 a0 ~3 c                                     i =0;
1 P0 }( u' n% t9 j( Q2 \7 O" v                                LCD_Clear(WHITE);        
% ]1 o* S8 R! H% j& k. W0 E8 R                                     coordinate()  ; //横坐标        3 v3 L* m: K9 x$ ]2 m7 e; P) K# x
                                     ! V3 J! V, T% O  x/ B
             //delay_ms(50);                                ( r1 Q  \4 T  X: l. A$ K
                         }0 l& U4 P1 H+ a7 s
                        i++ ;
0 f, t* S/ E' C5 l" C. ~6 [                        TIM2->CNT = 240; 5 {6 _) V7 i! ]( G5 \" T- b1 z
                   Frequent() ;, R' \0 {- N% a2 ~
     //fre = 1000/(90 /(720*100/72)) ;                        
: P' V6 ~" _* L* Z                 //sprintf((char*)speed,"speed : %d ",EncVal );//将LCD ID打印到lcd_id数组。
; b- B3 g. h/ J% l  W                //sprintf((char*)lcd_id,"LCD ID:%04X",lcddev.id);3 r' W2 ~: ], n5 d& s4 ~6 P
                        //LCD_ShowString(200,200,200,16,16,"EncVal");
: u: h$ ?8 j1 w( `                        LCD_ShowxNum(250,200,EncVal,5,16,0);4 Y5 L+ U1 R6 O! c" V1 V2 ?+ |
                printf("%d\r\n",EncVal) ;
+ }; t5 {: R2 u; h    TIM_SetAutoreload(TIM1, 0xFF88);//设置TIMx自动重装载寄存器值
. [5 U$ x# P. i9 ^5 V                 }  }2 |* v: l' }+ S+ p. P5 [. ^. v  h
}2 b7 |8 _. n6 D1 V+ L; U
' X  K5 d1 O! z  o

TIMER.rar

2.59 KB, 下载次数: 0, 下载积分: 威望 -5


作者: Abricy    时间: 2016-5-18 10:59
楼主很用心啊!
作者: hasky    时间: 2016-6-6 15:17
好资料,果断收藏
7 b0 g4 Q, F1 A. R5 a




欢迎光临 EDA365电子工程师网 (https://bbs.elecnest.cn/) Powered by Discuz! X3.2