Board logo

标题: at91sam9260,定时器代码,驱动步进电机 [打印本页]

作者: yuyang911220    时间: 2017-5-24 16:27     标题: at91sam9260,定时器代码,驱动步进电机

写这个程序,想在网上找个现成的改改,没找到,这里做好了贴一贴,方便后来者。
用定时器的WAVE模式,产生RA、RC比较中断,RA比较中断将PA29引脚置高,RC比较中断将PA29置低,而且RA刚好是RC的一半,因此可以产生方波,改变RC就改变频率,驱动步进电机。

unsigned int TimerAttribute[][2] = {
{5 * 2,   BOARD_MCK / 8 / (300 * 2) },
{5 * 2,   BOARD_MCK / 8 / (350 * 2) },
{6 * 2,   BOARD_MCK / 8 / (400 * 2) },
{6 * 2,   BOARD_MCK / 8 / (450 * 2) },
{7 * 2,   BOARD_MCK / 8 / (500 * 2) },
{7 * 2,   BOARD_MCK / 8 / (550 * 2) },
{8 * 2,   BOARD_MCK / 8 / (600 * 2) },
{9 * 2,   BOARD_MCK / 8 / (650 * 2) },
{9 * 2,   BOARD_MCK / 8 / (700 * 2) },
{10 * 2,   BOARD_MCK / 8 / (750 * 2) },
{24 * 2 * 68,  BOARD_MCK / 8 / (800 * 2) }
};
volatile unsigned int CurMicroSteps;
volatile unsigned int CurLevel;
volatile unsigned int UpOrDown;
volatile unsigned int RunningFlag;
//------------------------------------------------------------------------------
/// Interrupt handler for TC0 interrupt. Toggles the state of LED\#2.
//------------------------------------------------------------------------------
void ISR_Tc0(void)
{
    unsigned int state;
// Clear status bit to acknowledge interrupt
    state = AT91C_BASE_TC0->TC_SR;
if(state & AT91C_TC_CPAS){
  //置高
  AT91C_BASE_PIOA->IO_SODR = AT91C_PIO_PA29;
  return;
}
if(state & AT91C_TC_CPCS){
  //置低
  AT91C_BASE_PIOA->IO_CODR = AT91C_PIO_PA29;
  CurMicroSteps--;
  //当前台阶走完
  if(0 == CurMicroSteps){
   if(1 == UpOrDown){//加速阶段
    if(CurLevel < 10){
     CurLevel++;//上升一个台阶
    }else{
     CurLevel--;//最高台阶走完,开始减速,下降一个台阶
     UpOrDown = 0;
    }
   }else{//减速阶段
    if(CurLevel > 0){
     CurLevel--;//下降一个台阶
    }else{
     RunningFlag = 0;//最低台阶走完,停止转动
     TC_Stop(AT91C_BASE_TC0);
    }
   }
   //未结束,继续发脉冲
   if(1 == RunningFlag){
    CurMicroSteps = TimerAttribute[CurLevel][0];
    AT91C_BASE_TC0->TC_RC = TimerAttribute[CurLevel][1];
    AT91C_BASE_TC0->TC_RA = TimerAttribute[CurLevel][1]/2;
    TC_Start(AT91C_BASE_TC0);
   }
  }//CurMicroSteps
}//AT91C_TC_CPCS   
}
//------------------------------------------------------------------------------
/// Configure Timer Counter 0 to generate an interrupt every 250ms.
//------------------------------------------------------------------------------
void ConfigureTc(void)
{
    //unsigned int div;
    //unsigned int tcclks;
    // Enable peripheral clock
    AT91C_BASE_PMC->MC_PCER = 1 << AT91C_ID_TC0;
    // Configure TC for a 4Hz frequency and trigger on RC compare
    //TC_FindMckDivisor(4, BOARD_MCK, &div, &tcclks);
    TC_Configure(AT91C_BASE_TC0, AT91C_TC_WAVE | AT91C_TC_WAVESEL_UP_AUTO | AT91C_TC_CLKS_TIMER_DIV2_CLOCK);
    //AT91C_BASE_TC0->TC_RC = (BOARD_MCK / div) / 4; // timerFreq / desiredFreq
    // Configure and enable interrupt on RC compare
    AIC_ConfigureIT(AT91C_ID_TC0, AT91C_AIC_PRIOR_LOWEST, ISR_Tc0);
    AT91C_BASE_TC0->TC_IER = AT91C_TC_CPAS | AT91C_TC_CPCS;
    AIC_EnableIT(AT91C_ID_TC0);
}




欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0