现在可以用编码器读取计数器的值了,但是怎么去测速呢?

2019-08-14 18:49发布

编码器怎么去测速呢?怎么通过PWM去控制直流电机呢?求教各位大神!最近在用直流电机,希望大家可以帮帮忙!谢谢啦!
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
28条回答
joe_knight
1楼-- · 2019-08-16 22:35
你在TIM2的5ms中断里做的是什么呀:打开TIM3和TIM5后就读计数器?读完然后就关闭?这样在一个测速周期内TIM3和TIM5都不工作,测出来不是0都怪了。
先禁用定时器,再读数,最后再使能定时器,这流程是不是你想要的?
但这样测速是不精确的,尤其对于慢速系统。
1,我们先来看Tc是不是满足需求,n = (60 × M1)/(P × Tc),为了在一个Tc内至少能收到一个编码脉冲,那么M1=1,P恒量4×400,n >= 60000 / (4 ×400 × 5),n>=7.5rpm,
也就是说,在低于7.5rmp的转速时,你的测速周期就不能满足需求,如果有示波器,可以通过编码脉冲的波形可以看一看不同转速下的最小Tc;
2,为什么说这样测速精度不够呢?copy一段,你好好理解一下:Tc开始时刻与码盘输出脉冲上升沿并非一定同步到达。同样,TC结束时刻也很难刚好与码盘的输出脉冲上升沿同步。这两个时间差都与转速的大小有关,而与高频计数时钟的频率无关。由此引起的计数和计时的时间偏差可能比高频时钟周期大得多,从而降低测速的精度;
张晓斌
2楼-- · 2019-08-17 00:57
回复【19楼】joe_knight:
---------------------------------
蒙圈了。。。应该是初始化时使能TIM3和TIM5,然后在TIM2中断里面禁用TIM3和TIM5,读取计数值放到M1和M2里面在进行计算。这样也不能实现。然后又仔细看了看那篇文章,换了种思路,  
主函数中   
 if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_6)==1)//TIM3的PC6 C7作为编码器接口
      {
        TIM3->CNT=0;
        TIM_Cmd(TIM5,ENABLE);
      }
然后在TIM2中断里
void TIM2_IRQHandler(void)
{
  u16 M1=0,M2=0;
   
    if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_6)==1)
    {    
  TIM_Cmd(TIM3,DISABLE);
  TIM_Cmd(TIM5,DISABLE);    
   
  M1=TIM3->CNT;
  M2=TIM5->CNT; 
    
  TIM3->CNT=0;
  TIM5->CNT=0;
  n=60*(1000000)*M1/(M2*4*400); 
  
  TIM_Cmd(TIM3,ENABLE);
  TIM_Cmd(TIM5,ENABLE);
    } 
  TIM_ClearITPendingBit(TIM2,TIM_IT_Update); 
    
}
但是这样也不可以啊!这样应该可以啊!奔溃了。。。
joe_knight
3楼-- · 2019-08-17 05:02
 精彩回答 2  元偷偷看……
张晓斌
4楼-- · 2019-08-17 05:26
回复【21楼】joe_knight:
---------------------------------
void TIM2_IRQHandler(void)
{    
  u8 count=0;
   if(TIM_GetITStatus(TIM2,TIM_IT_Update)!=RESET)
   {
      
    if(count==0)//第一次进入中断后
    {
        TIM3_Cap_Init();//输入捕获模式
        count++;  
    }        
    if(count==2)//第二次进入中断
    {
        count=0;
        TIM_Cmd(TIM3,DISABLE);
        M1=TIM3->CNT;
        TIM3->CNT=0;//计数器清零
        TIM3_Cap_Init();  
    }             
   TIM_ClearITPendingBit(TIM2,TIM_IT_Update); 
   }   
}
void TIM3_IRQHandler(void)
{
    u8 i=0;
    if(TIM_GetITStatus(TIM3,TIM_IT_Update)!=RESET)
        TIM_ClearFlag(TIM3,TIM_IT_Update);
    if(TIM_GetITStatus(TIM3,TIM_IT_CC1)!=RESET|TIM_GetITStatus(TIM3,TIM_IT_CC2)!=RESET)
    {   
        if(i==0)//第一次捕获
        {     
        TIM_Cmd(TIM3,DISABLE);
        TIM3->CNT=0;
        TIM_Encoder();
        TIM_Cmd(TIM5,ENABLE);
        i++;
        }
        if(i==2)//第二次捕获
        {
           i=0;
          TIM_Cmd(TIM5,DISABLE);
          M2=TIM5->CNT;  
        }
        TIM_ClearFlag(TIM3,TIM_IT_CC1);
        TIM_ClearFlag(TIM3,TIM_IT_CC2);
    }
}
我是按照你给的思路写的啊,但结果还是一样的。唉。。。对自己失望了。
张晓斌
5楼-- · 2019-08-17 06:41
回复【23楼】joe_knight:
---------------------------------
哦哦,可能是溢出没有处理好吧,我再弄弄吧!真心谢谢你!
13262695623
6楼-- · 2019-08-17 10:55
同问11111

一周热门 更多>