打印
[STM32F1]

STM32编码器捕捉频率并同步到步进电机问题请教

[复制链接]
3743|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
目的,利用编码器,捕捉伺服电机频率,然后同步速度给步进电机,其中的速度比可以计算后调整。类似一个可调速度的同步环。



目前的笨办法,接入TIM3 CH1或其他I/O口捕捉,利用EXTI或TIM中断,计算后给步进电机输出脉冲,步进电机设置单脉冲模式,固定占空比,只是效率太低,

有什么其他合理的方式实现?比如主从模式? 外部时钟2模式?

新人,STM32参考手册翻了好几遍了。一直没有头绪。
沙发
airwill| | 2014-5-13 10:46 | 只看该作者
不需要 EXTI, 用定时器的 pwm 测量功能, 测出编码器信号的直接可以测量出周期, 你再去算加减速吧.

使用特权

评论回复
板凳
金色大元宝|  楼主 | 2014-5-13 10:56 | 只看该作者
a版主你好,因为伺服不是恒速的,pwm 测量出来,是不是也需要每个脉冲周期进行计算加减速?

使用特权

评论回复
地板
mmuuss586| | 2014-5-13 11:09 | 只看该作者
本帖最后由 mmuuss586 于 2014-5-13 11:10 编辑

STM32有编码器接口啊。
为啥不用定时器的捕获功能啊;
另外可以参考STM32的FOC算法;
有人用STM32做过多轴的伺服控制;

使用特权

评论回复
5
金色大元宝|  楼主 | 2014-5-13 12:39 | 只看该作者
m版主,我看到的例程,好像编码器接口都是计数的。没有看到捕获频率的。

刚刚吃饭的时候,我突然想到。是不是可以编码器的输入直接传递给TIM输出,然后控制TIM输出的分频来调速。因为只有减速,没有加速。

我去看下参考手册,TIM是外部触发后输出的话,还能不能分频。

使用特权

评论回复
6
icecut| | 2014-5-13 13:37 | 只看该作者
1.测量三五个脉冲的时间计算速度.用于控制步进电机输出.
2.测量长时间的编码器,计算速度.用于修正步进电机速度.
3.用5楼的办法产生更多的计数器溢出.使用溢出直接驱动gpio跳变产生信号...[理论上能,没试验过]

使用特权

评论回复
7
金色大元宝|  楼主 | 2014-5-14 11:58 | 只看该作者
捕捉实现了。同步也实现了。

TIM2负责输入捕捉,然后在TIM2中断里给TIM3的ARR和CCR赋值,但又碰到一个问题。我TIM2输入的脉冲不是持续运行的。时断时续

我该用什么办法控制TIM3比较好? 目前的想法是SYSTICK,每隔多少时间,读一次IC2Value = TIM_GetCapture2(TIM2);,大于0,使能TIM3,=0就禁止TIM3,还有更好的办法吗?

//输入捕获
static void TIM2_Mode_Config(void)
{
    TIM_TimeBaseInitTypeDef   TIM_TimeBaseStructure;
    TIM_ICInitTypeDef  TIM_ICInitStructure;
    TIM_DeInit(TIM2);
   
    /* Time base configuration */
   
    TIM_TimeBaseStructure.TIM_Period = 0xffff;         
    //TIM_TimeBaseStructure.TIM_Prescaler = 719;
    TIM_TimeBaseStructure.TIM_Prescaler = 71;
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;   
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
   
    TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
    TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
    //TIM输入2,3或4选择对应地与IC1或IC2或IC3或IC4相连
    TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
    //TIM捕获在捕获输入上每探测到一个边沿执行一次 TIM_ICPSC_DIV2\TIM_ICPSC_DIV4\TIM_ICPSC_DIV8
    TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
    //选择输入比较滤波器 0x0 - 0xF
    TIM_ICInitStructure.TIM_ICFilter = 0x0;  //
   
    TIM_PWMIConfig(TIM2, &TIM_ICInitStructure);
   
    /* Select the TIM3 Input Trigger: TI2FP2 */
    TIM_SelectInputTrigger(TIM2, TIM_TS_TI2FP2);
   
    /* Select the slave Mode: Reset Mode */
    TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Reset);
   
    /* Enable the Master/Slave Mode */
    TIM_SelectMasterSlaveMode(TIM2, TIM_MasterSlaveMode_Enable);   
   
    /* Enable the CC2 Interrupt Request */
    TIM_ITConfig(TIM2, TIM_IT_CC2, ENABLE);
   
    /* TIM enable counter */
    TIM_Cmd(TIM2, ENABLE);   
}
void TIM2_ISR(void)
{

    Uint16 TIM3_Period; //ARR
    Uint16 TIM3_CCR3_Val; //CCR3
    Uint16 IC2Value;

    TIM_ClearITPendingBit(TIM2, TIM_IT_CC2); //清除中断标志位
    IC2Value = TIM_GetCapture2(TIM2);
    if(IC2Value != 0)
    {
        //DutyCyle = (TIM_GetCapture1(TIM3) * 100) / IC2Value; //占空比计算
        //TIM3_Period = 72000000 / IC2Value; //0 -72M
        //TIM3_Period = 1000000 / IC2Value; //71 -1M
        //TIM3_Period = 100000 / IC2Value; //719 -100K
        
        /*
            同频捕获同频率输出
            TIM_Prescaler = 71, 即(71+1)=72分频,时钟频率降为1M
            TIM2和TIM3同频率,TIM2每个时钟周期捕获到的脉冲不用计算,可以直接输出给TIM3
        */
        
        TIM3_Period = IC2Value;
        TIM3_CCR3_Val = ((TIM3_Period + 1)/2);
    }
    else
    {
        TIM3_Period = 0;
        TIM3_CCR3_Val = 0;
    }
   
    /* 同步改变TIM3步进脉冲 */
   
    TIM3->ARR=TIM3_Period;//设定计数器自动重装值
    TIM3->CCR3=TIM3_CCR3_Val;
}

中断处理里还有一个现象,因为我TIM2和TIM3是同时钟频率的。TIM2捕捉到的就直接赋值给TIM3了,经初步检测,好像没问题。不知道这样做行不行?

使用特权

评论回复
8
金色大元宝|  楼主 | 2014-5-14 19:07 | 只看该作者
顶一下,呼叫香版

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

24

主题

82

帖子

3

粉丝