396221798 发表于 2013-9-8 22:48:38

无刷电调问题 有图有真相

本帖最后由 396221798 于 2013-9-8 22:52 编辑

关于这个问题我已经弄了三天了,电机加速到50%油门的时候就会失速,之前问了一些专家说是过零的消磁干扰求大神解释换相代码如下

      if(!TF2H)
      {      while(!COMP1_Out());
                        //Delay_1us();
            Disable_COMP1_Falling_IT();
            Enable_COMP1_Rising_IT();
            Clear_COMP1_IF();
            Enable_COMP1_IT();
                        //State = Running;
      }
上面这个语句是开启比较器中断用的,在开启之前我添加了这么一句话while(!COMP1_Out()); 也就是比较器最后一个下降沿才开启中断这样就不怕消磁事件和干扰了

电机 运行到50%油门就失速了


void COMP1_Interrupt(void) interrupt 13
{
    /* 如果不是比较器输出上升沿中断,则退出 */
    if(Flag_BemfEdge == RISING)
    {
      Clear_COMP1_IF();
      return;
    }
       //_nop_();_nop_();_nop_();_nop_();_nop_();

    Clear_COMP1_IF();
    Disable_COMP1_IT();
    //LED7 = ~LED7;

    /* 获取过零点时长 */
    do
    {
       ZeroCrossTime.bytes.high = TMR2H;
       ZeroCrossTime.bytes.low = TMR2L;
    }
    while (ZeroCrossTime.bytes.high != TMR2H);

    ZeroCrossTime.word -= TempTime.word;

    if(State == Running)
    {
      /* 30°角换向 */
                //while(!COMP1_Out());
                _nop_();
      Disable_TIM2();
      TMR2H = ZeroCommutateTime.bytes.high;
      TMR2L = ZeroCommutateTime.bytes.low;
      Enable_TIM2();
      Clear_TIM2_IF();
    }
}

void TIM2_Interrupt(void) interrupt 5
{
    Clear_TIM2_IF();
    Commutate();

    /* 如果是下降沿检测 */
    if(Flag_BemfEdge == FALLING)
    {
      TempTime.word = CommutateTime.word - BLANKING_COUNT;
      //TempTime.word = CommutateTime.word + BLANKING_COUNT;
      /* 避开换向后的消磁事件 */
       //Delay_1us();// while(TMR2L < BLANKING_COUNT);
               
      Disable_TIM2();
      TMR2H += TempTime.bytes.high;
      if((unsigned int)(TMR2L + TempTime.bytes.low) > 255)
            TMR2H ++;
      TMR2L += TempTime.bytes.low;
      Enable_TIM2();

      /* 如果消磁事件还未结束则继续等待 */
       /* while(COMP1_Out())
      {
            if(TF2H)
            {
                                TF2H = 0;
                LED7 = ~LED7;
                                //State = Start;
                break;
            }
      } */
                //Delay_1us();
                //Delay_1us();
                //Delay_1us();
                //Delay_1us();
                //Delay_1us();
                //Delay_1us();


      /* 如果换向时间还未到达,使能比较器中断。在比较器中断时准备下一次换向 */
      /* 如果换向时间已经溢出,则中断状态维持TIM1不变,在下一次进入中断函数后
         直接换向 */
      if(!TF2H)
      {        while(!COMP1_Out());
                        //Delay_1us();
            Disable_COMP1_Falling_IT();
            Enable_COMP1_Rising_IT();
            Clear_COMP1_IF();
            Enable_COMP1_IT();
                        //State = Running;
      }
    }
    else
    {
      /* 预期的换向时长(30°)等于60°换向时长/2 */
      ExpectCommutateTime.word = (0xFFFF - CommutateTime.word)/2 ;

      /* 计算预期的换向时长和过零点时间的误差 */
      /* 如果比较器检测到的过零时长大于预期时长,则增加换向时长,反之则减小换向时长 */
      if(ZeroCrossTime.word > ExpectCommutateTime.word)
      {
            ErrorTime = ZeroCrossTime.word - ExpectCommutateTime.word;
            /* 减速 */
            CommutateTime.word -= (ErrorTime/200);
            LED8 = 1;
            LED9 = 0;
      }
      else
      {
            ErrorTime = ExpectCommutateTime.word - ZeroCrossTime.word;
            /* 加速 */
            CommutateTime.word += (ErrorTime/200);
            LED9 = 1;
            LED8 = 0;               
      }

      /* 60°角换向 */
      Disable_TIM2();
      TMR2H += CommutateTime.bytes.high;
      if((unsigned int)(TMR2L + CommutateTime.bytes.low) > 255)
            TMR2H ++;
      TMR2L += CommutateTime.bytes.low;
      Enable_TIM2();

      ZeroCommutateTime.word = 0xFFFF - ((unsigned long)ExpectCommutateTime.word*(10-6))/10; //减数太小电机加速到很高的时候容易失速
      if(State == Accelerate)
      {
            /* 如果误差小于预期换向时长的1/2时进入同步状态 */
            if(ErrorTime < (ExpectCommutateTime.word/2))//这个调节进入同步的时间
            {
                State = Running;       
                                //Speed_Manager();                       
            }
      }
    }
}

页: [1]
查看完整版本: 无刷电调问题 有图有真相