首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

at91sam9260,定时器代码,驱动步进电机

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);
}
继承事业,薪火相传
返回列表