运动控制器19:步进控制文件的初始化(选用定时器2)

控制步进输出的定时器TIM2初始化函数

    NVIC_InitTypeDef   NVIC_InitStructure;
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 , ENABLE);
    
    TIM_TimeBaseStructure.TIM_Period=1000;  
    TIM_TimeBaseStructure.TIM_Prescaler=0; //72M      
    TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;   
    TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
    
    TIM_ClearFlag(TIM2, TIM_FLAG_Update);                                   
    TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
    TIM_Cmd(TIM2, ENABLE);  


    NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;                     //选择定时器2中断线
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;        //抢占优先级为1
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;                  //响应优先级为0
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                         //使能中断通道
    NVIC_Init(&NVIC_InitStructure); 

我们再设置一个开启定时器和关闭定时器的函数:
开启定时器的函数名称:st_wake_up,
关闭函数则为:st_go_idle

void st_wake_up() 
{
  //使能控制系统控制的3个或者多个步进电机
  MotorsEnable(0x07);
  if (sys.state == STATE_CYCLE) {
   //设置上电时候输出为低电平,否则会发送一个脉冲信号
    out_bits = (0) ^ (settings.invert_mask); 
    //然后开启定时器的中断功能,设置中断的时候马上写入一遍优先级是一个好习惯
    //定时器刚启动,标记逻辑位置为0
    NVIC_EnableIRQ (TIM2_IRQn);  
    NVIC_SetPriority(TIM2_IRQn, 0);
    ShowPos = 1;
  }
}

关闭定时器的函数如下,关闭定时器时,如果要用到延时脱机,则处理一下延时命令,也可以打印出此时运行的XYZ坐标值:

void st_go_idle() 
{
  printpos_grbl(0,480);//输出位置信息
  ShowPos = 0;
  NVIC_DisableIRQ (TIM2_IRQn); 
  //如果需要延时脱机,则进行延时处理
  if ((settings.stepper_idle_lock_time != 0xff) || bit_istrue(sys.execute,EXEC_ALARM)) {
    _delay_ms(settings.stepper_idle_lock_time);
    if (bit_istrue(settings.flags,BITFLAG_INVERT_ST_ENABLE)) 
    {  STEPPERS_DISABLE_PORT &= ~(1<

定时器的ARR重载和预分频器的重新设置

  1. 首先,确定好最低运行的步进脉冲速度,这里设置为13HZ,在调用时,如果小于13HZ,则直接按照13HZ来处理,如下:
//最小的步进速度,步进脉冲停下来时,不要低于此值,也就是说,速度不要低于13HZ
#define MINIMUM_STEPS_PER_MINUTE 800 

 if (steps_per_minute < MINIMUM_STEPS_PER_MINUTE) 
 { steps_per_minute = MINIMUM_STEPS_PER_MINUTE; }

如果我们要产生13HZ的输出频率,如果时钟频率为4M,则需要分钟产生4M*60/800=300K个TICKS我们将此参数交给下面的函数:config_step_timer

TIM_ClockDivision设置的不是时钟分频,而是采样时间设置,比如TIM_CKD_DIV1则表示采样的时钟就是定时器时钟。

我们需要输出的步进脉冲信号是随时需要进行调整的,也就是说,ARR需要动态的进行调节,同时,输出的频率跨度比较大,我们同时要设置预分频,可以利用下面的两个函数进行调整,函数的使用示例如下:

  TIM_PrescalerConfig(TIM2,i,TIM_PSCReloadMode_Update);
  TIM_SetAutoreload(TIM2,1000+i*500);

编写的测试程序如下:

  1. 定时器的结构体初始化设置如下:
void st_init()
{
    NVIC_InitTypeDef   NVIC_InitStructure;
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 , ENABLE);
    
    TIM_TimeBaseStructure.TIM_Period=1000;  
    TIM_TimeBaseStructure.TIM_Prescaler=0; //72M      
    TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;   
    TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
    
    TIM_ClearFlag(TIM2, TIM_FLAG_Update);                                   
    TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
    TIM_Cmd(TIM2, ENABLE);  

    NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;                 
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;        
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;                  
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                         
    NVIC_Init(&NVIC_InitStructure);

    NVIC_EnableIRQ (TIM2_IRQn);  
}
  1. 中断服务程序
    在中断函数中,对time进行循环++,如下:
void TIM2_IRQHandler(void)
{
    if ( TIM_GetITStatus(TIM2 , TIM_IT_Update) != RESET ) 
    {   
        TIM_ClearITPendingBit(TIM2 , TIM_FLAG_Update);    
         time++;
    }           
}
  1. 我们实现的功能如下,在每次中断事件时,1/72秒以后,将LED引脚翻转,翻转4次以后,进行一次跟新,我们可以同时更新ARR和PSC,测试程序如下:
if(time==1000)
        {
            time=0;
            if((GPIO_ReadOutputDataBit(GPIOF, GPIO_Pin_7 )))
            {GPIO_ResetBits(GPIOF, GPIO_Pin_7 );
                    a++;
                    if(a%4==0)
                  {i++;
                TIM_PrescalerConfig(TIM2,i,TIM_PSCReloadMode_Update);
                    TIM_SetAutoreload(TIM2,1000+i*500);
                    if(i==10)i=0;}
            }
            else
            GPIO_SetBits(GPIOF, GPIO_Pin_7);
        }

你可能感兴趣的:(运动控制器19:步进控制文件的初始化(选用定时器2))