tag 标签: 正交编码器

相关博文
  • 热度 3
    2016-4-9 12:38
    3046 次阅读|
    1 个评论
    废话不说,先上代码 #include "main.h" /* PA7——TIM3_CH2 PA6——TIM3_CH1 PB7——TIM4_CH2 PB6——TIM4_CH1 */   int Timer3_Overflow; int Timer4_Overflow;   void wheel_encoder_configuration(void) {          GPIO_InitTypeDef                                        ENCODER;          TIM_TimeBaseInitTypeDef    TIMER3,  TIMER4;          TIM_ICInitTypeDef                                      IC_ENCODER;          NVIC_InitTypeDef                                        nvic;            RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA|RCC_AHB1Periph_GPIOB, ENABLE);          RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3|RCC_APB1Periph_TIM4, ENABLE);                   //PA6、PA7的复用功能一定要分开配置才行          GPIO_PinAFConfig(GPIOA,GPIO_PinSource6, GPIO_AF_TIM3);          GPIO_PinAFConfig(GPIOA,GPIO_PinSource7, GPIO_AF_TIM3);          ENCODER.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;          ENCODER.GPIO_Mode = GPIO_Mode_AF;          ENCODER.GPIO_Speed = GPIO_Speed_100MHz;          ENCODER.GPIO_PuPd = GPIO_PuPd_DOWN;          GPIO_Init(GPIOA, ENCODER);          GPIO_PinAFConfig(GPIOB,GPIO_PinSource6, GPIO_AF_TIM4);          GPIO_PinAFConfig(GPIOB,GPIO_PinSource7, GPIO_AF_TIM4);          ENCODER.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;          ENCODER.GPIO_Mode = GPIO_Mode_AF;          ENCODER.GPIO_Speed = GPIO_Speed_100MHz;          ENCODER.GPIO_PuPd = GPIO_PuPd_DOWN;          GPIO_Init(GPIOB, ENCODER);            /***********configure the TIM3**********/          TIMER3.TIM_Prescaler = 0;          TIMER3.TIM_Period = 0xffff;          TIMER3.TIM_ClockDivision = TIM_CKD_DIV1;          TIMER3.TIM_CounterMode = TIM_CounterMode_Up;            TIM_TimeBaseInit(TIM3, TIMER3);          /***********configure the TIM4***********/          TIMER4.TIM_Prescaler = 0;          TIMER4.TIM_Period = 0xffff;          TIMER4.TIM_ClockDivision = TIM_CKD_DIV1;          TIMER4.TIM_CounterMode = TIM_CounterMode_Up;            TIM_TimeBaseInit(TIM4, TIMER4);                   /**********Set TIM3 and TIM4 to the ecoder mode***************/          TIM_EncoderInterfaceConfig(TIM3, TIM_EncoderMode_TI12, TIM_ICPolarity_Falling, TIM_ICPolarity_Falling);          TIM_EncoderInterfaceConfig(TIM4, TIM_EncoderMode_TI12, TIM_ICPolarity_Falling, TIM_ICPolarity_Falling);                   /**********Set TIM3 and TIM4 to the input capture mode***************/          IC_ENCODER.TIM_Channel    =       TIM_Channel_1;          IC_ENCODER.TIM_ICSelection        =       TIM_ICSelection_DirectTI;          TIM_ICInit(TIM3, IC_ENCODER);          IC_ENCODER.TIM_Channel    =       TIM_Channel_2;          IC_ENCODER.TIM_ICSelection        =       TIM_ICSelection_DirectTI;          TIM_ICInit(TIM3, IC_ENCODER);          IC_ENCODER.TIM_Channel    =       TIM_Channel_1;          IC_ENCODER.TIM_ICSelection        =       TIM_ICSelection_DirectTI;          TIM_ICInit(TIM4, IC_ENCODER);          IC_ENCODER.TIM_Channel    =       TIM_Channel_2;          IC_ENCODER.TIM_ICSelection        =       TIM_ICSelection_DirectTI;          TIM_ICInit(TIM4, IC_ENCODER);                   /*************Configurate interrupts of TIM3 and TIM4*********/          nvic.NVIC_IRQChannel = TIM3_IRQn;          nvic.NVIC_IRQChannelPreemptionPriority = 2;          nvic.NVIC_IRQChannelSubPriority = 2;          nvic.NVIC_IRQChannelCmd = ENABLE;          NVIC_Init(nvic);          nvic.NVIC_IRQChannel = TIM4_IRQn;          nvic.NVIC_IRQChannelPreemptionPriority = 2;          nvic.NVIC_IRQChannelSubPriority = 2;          nvic.NVIC_IRQChannelCmd = ENABLE;          NVIC_Init(nvic);                   /*Clear the interruput flag and then enable the interrupt*/          TIM_ClearFlag(TIM3, TIM_FLAG_Update);          TIM_ClearFlag(TIM4, TIM_FLAG_Update);          TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);          TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);                   /*Set TIM3 and TIM4 CNT to 0x7fff*/          TIM_SetCounter(TIM3,0x7fff);          TIM_SetCounter(TIM4,0x7fff);          /*Enable TIM3 and TIM4 */          TIM_Cmd(TIM3, ENABLE);          TIM_Cmd(TIM4, ENABLE); }   int encoderR_get_cnt(void) {          /*get the speed of right wheel */          int cnt = 0;          cnt = (TIM3 - CNT) - 0x7fff;          TIM3 - CNT = 0x7fff;          return cnt; }   int encoderL_get_cnt(void) {          /*get the speed of left wheel*/          int cnt = 0;          cnt = (TIM4 - CNT) - 0x7fff;          TIM4 - CNT = 0x7fff;          return cnt; }   void TIM3_IRQHandler(void) {          TIM_ClearFlag(TIM3, TIM_FLAG_Update);          if(Timer3_Overflow != 0xffffffff)          {                    Timer3_Overflow++;          } }   void TIM4_IRQHandler(void) {          TIM_ClearFlag(TIM4, TIM_FLAG_Update);          if(Timer4_Overflow != 0xffffffff)          {                    Timer4_Overflow++;          } } 刚开始在调试的时候遇到了问题,读出来的cnt值只有0,1,-1,而且根本没有什么规律,后来发现是gpio的配置有问题,相应的GPIO口应该配制成GPIO_Mode_AF,而不是GPIO_Mode_IN,而且配置复用功能的时候,GPIO_PinAFConfig()函数的参数一定要注意,GPIO_PinSource参数只能写一个,不要讲多个GPIO_PinSource与在一起。比如,要配置PA6和PA7,应写成这样: GPIO_PinAFConfig(GPIOA,GPIO_PinSource6, GPIO_AF_TIM3);          GPIO_PinAFConfig(GPIOA,GPIO_PinSource7, GPIO_AF_TIM3); 而不要写出这样: GPIO_PinAFConfig(GPIOA,GPIO_PinSource6| GPIO_PinSource7,  GPIO_AF_TIM3);          程序中CNT寄存器的初值设置为0X7fff,这样的话无论一开始轮子是正转还是反转,都基本不会溢出,但是为了防止溢出的情况,又在两个定时器的中断函数中对溢出次数进行计数,在后续的应用中就可以结合溢出次数和CNT计数器的值,得到实际的计数值。
  • 热度 19
    2014-1-11 08:14
    1182 次阅读|
    0 个评论
      sbit Cor_A  = P2^0;  // 正交编码器入口 sbit Cor_B  = P2^1; sbit Cor_Z  = P2^2;   unsigned int xdata Coder_Value;   char bdata Bit1_Value _at_ 0x2F;    sbit Temp_Bit  = Bit1_Value^0;   void CP00_Serve(void); // A void CP01_Serve(void); void CP10_Serve(void); // B void CP11_Serve(void);       void Comparator_Init() {     int i = 0;     SFRPAGE   = CPT0_PAGE; CPT0MD    = 0x30;     CPT0CN    = 0x8F;     for (i = 0; i 600; i++);     CPT0CN    = ~0x30;       SFRPAGE   = CPT1_PAGE; CPT1MD    = 0x30;     CPT1CN    = 0x8F;     for (i = 0; i 600; i++);     CPT1CN    = ~0x30; }   void Interrupts_Init() { //    IE    |= 0x17; //    IP    |= 0x17;     EIE1  |= 0xF0;     EIP1  |= 0xF0; }     void main (void) { Comparator_Init(); Interrupts_Init(); while(1) { Temp_Value =  Coder_Value; } return; }         /************ 正交编码器入口 *** A ****/ void CP00_Serve(void) interrupt 10  {CPT0CN = ~0x10;// 下降沿中断  if(Cor_B == 1){Coder_Value ++; Temp_Bit = 1;}  if(Cor_B == 0){Coder_Value --; Temp_Bit = 0;}  pid_A.ActualSpeed = Coder_Value;  pid_B.ActualSpeed = Coder_Value; return; } /******************************* A ****/ void CP01_Serve(void) interrupt 11 {CPT0CN = ~0x20;// 上升沿中断  if(Cor_B == 0){Coder_Value ++; Temp_Bit = 1;}  if(Cor_B == 1){Coder_Value --; Temp_Bit = 0;}  pid_A.ActualSpeed = Coder_Value;  pid_B.ActualSpeed = Coder_Value; if(0x07 (P2 0x07)){Pow_ON = 0;  if(Coder_Value 4000)Coder_Value = 1;  if(Coder_Value 1)Coder_Value = 4000;  if(Cor_Z == 1){Pow_ON = 1 ; Coder_Value = 2000;}  } return; } /******************************* B ****/ void CP10_Serve(void) interrupt 12  {CPT1CN = ~0x10;// 下降沿中断  if(Cor_A == 0){Coder_Value ++; Temp_Bit = 1;}  if(Cor_A == 1){Coder_Value --; Temp_Bit = 0;}  pid_A.ActualSpeed = Coder_Value;  pid_B.ActualSpeed = Coder_Value; return; } /******************************* B ****/ void CP11_Serve(void) interrupt 13  {CPT1CN = ~0x20;// 上升沿中断  if(Cor_A == 1){Coder_Value ++; Temp_Bit = 1;}  if(Cor_A == 0){Coder_Value --; Temp_Bit = 0;}  pid_A.ActualSpeed = Coder_Value;  pid_B.ActualSpeed = Coder_Value;  if(0x07 (P2 0x07)){Pow_ON = 0;  if(Coder_Value 4000)Coder_Value = 1;  if(Coder_Value 1)Coder_Value = 4000;  if(Cor_Z == 1){Pow_ON = 1 ; Coder_Value = 2000;}  } return; } /*************** END ********************/