编码器实现电机测速

1.为什么要电机测速

电机应用在很多的控制领域,控制领域多数是控制精度高的闭环控制,比如应用广泛的PID,在闭环系统内中电机是作为执行器,要实现闭环控制的话,需要我们的系统有反馈回路,反馈回路中需要有测量元件,来实现电机的闭环控制,所以编码器作为一种测量元件,广泛的应用于电机的速度测量,实现电机的闭环控制。

2.编码器是什么呢?

编码器encoder,将信号(比特流)或数据进行编制,转换为可以通讯、传输和存储的信号形式的设备,可以将角位移(码盘实现)或者直线位移(码尺)转化为电信号。编码器的类型有很多种,例如根据检测原理,可分为光学式、磁式、感应式和电容式。根据内部机械结构的运动方式,可分为线性编码器和旋转编码器。根据其刻度实现方法及信号输出形式,又可分为增量式、绝对式以及混合式三种。对于这些编码器的相关原理和区别网上有很多介绍,在这就不多说了,本文主要针对于霍尔编码器的原理及测速实现进行讲解(个人的总结吧,有不对的地方多多指教)。

3.霍尔编码器

在学习如何实现编码器测速之前,先了解以下概念:

减速比:一般直流电机会带减速箱,因为P=FV,我们希望输出大的扭矩的话,就需要减速,如果减速比是1:30,那么这就意味着我们电机外的转轴(连接负载那一端)转一圈,电机内的转子转了30圈。

编码器的线数:我们以上面那个示意图为例子我们电机内转子旋转一圈,那么霍尔元件就会输出多少个脉冲,这个脉冲的个数(一般来说是一个上升沿和下降沿),在上图自动编码器的减速电机是增量式的11线。

带霍尔编码器的直流电机,转到一周,在减速比为1:30,线数为11的情况下,A B两相分别输出数目相同的1*30*11的脉冲数,我们可以根据一定时间内脉冲数计算出电机的瞬时速度,在这我觉得可以这样逻辑,在一定时间内的脉冲数就是电机的位移。

4.测速原理

我们的编码器可以输出脉冲,那么如何来测速呢?

1.我们可以通过多少钱的输入捕获或者使用GPIO的外部中断来检测脉冲信号的边沿变化,实现对脉冲的计数,但是这样一方面会有毛刺的影响,另一方面我们会比较频繁的进入中断,但是进入中断后只是简单的计数是比较浪费软件资源的。

2.由于测速的需求,以STM32为例子,高级定时器的TIM1 TIM8和通用定时器的TIM2到TIM5有输入捕获的编码器接口功能。可以对脉冲计数,并且带滤波功能。如图是正反转的时候,A B两相的脉冲信号。这个时候的定时器就当做计数器的功能,输入的时钟就是这A B两相的脉冲,当然可以选择三种模式,模式的配置在STM32中是    TIM_EncoderInterfaceConfig(TIM3,TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);这个东西,当我们选择TIM_EncoderMode_TI1时候即A B两项都计数。

​​​​​

 脉冲信号的两项先后关系是表示旋转方向,脉冲的个数表示转过的角度,在这里简单的说一下为什么要用正交信号,这个就可以类比于我们人走路一样,前脚后脚前进,后脚前脚后退,表示方向,如上图,A B两相的电平是交替的跳变的,如果一相的电平在没有发送变化的情况下。另一相的电平发生了反复的电平变化就是出现了噪声,也就是一只腿不动,另一只推前后踢肯定是不正常的,另外A B相的信号我们都可以对其计次,使得分辨率更高。结合下图是讲到编码器的时候都会出现的一张图。

 我们选择在TI1、TI2都计数的情况,当TI1FP1出现上升沿,对应的TI2电平为高,即对应我们表格的反转A相上升沿,B相高电平,此事应该是向下计数。正转的时候计数器向上计数,反转的时候计数器向下计数。

5.编程设计

我们在定时器的程序设计中,经常会有ARR自动重装、PSC预分屏器,在编码器模式下,ARR的值就是脉冲计数的最大量程,由于编码器模式下的时钟是外部的脉冲,如果我们的预分频系数是二的情况下,电机一圈产生100脉冲,但是只可以记录到50个。

在程序设计中第一需要一个定时器进行时间的定时,第二就是需要另一个定时器的编码器模式实现脉冲的计数。

我们怎么来计算转速呢?是通过一段时间内产生的脉冲数,来除以一圈内的脉冲数,这样得到的就是在一段时间内的圈数,再把这个圈数除以这段时间,不就得到了转速了吗。

以下是结合一些大佬的程序和文章的总结:

通过一个定时器TIM5实现0.05秒的定时,该定时器的中断服务函数就是来读取另一个定时器TIM3在这一段时间内产生的脉冲个数。

在TIM3定时器中,我们配置它为编码器模式,定义count得到的脉冲数 current-count在每次0.05秒时CNT里面的值。


u32 Read_Encoder(void)
{
  u32 Count;                                                      //一段时间内的脉冲个数
  u16 Current_Count;                                              //在0.05秒时的CNT值
  u16 Enc_Timer_Overflow_one;	                                   //定时器溢出值

	Enc_Timer_Overflow_one=Encoder_Timer_Overflow;                  
  Current_Count = TIM_GetCounter(TIM3);                 
  Encoder_Timer_Overflow=0;      //清0方便下次计算                                 
  Count = (u32)(Current_Count - Previous_Count + (Enc_Timer_Overflow_one) * (4*ENCODER_PPR));   //我们选用四倍频ARR的值就是
  Previous_Count = Current_Count;  
  return(Count);
}

那么一段时间内产生的脉冲数我们放到TIM5的中断服务函数中。

在0.05秒内,产生的脉冲数目为:A=次数*ARR+(当前的CNT值-上一次的CNT值)

电机转动一圈的产生的脉冲数:B=(线数*4)/PSC.

那么在一段时间内转过的圈数为:A/B

转速为每秒内转过的圈数:A/B/time

void TIM5_IRQHandler(void)                          
{
	if(TIM_GetITStatus(TIM5,TIM_IT_Update)==SET)      
	{  
		encode=Read_Encoder();                          //脉冲个数
		printf("编码器脉冲个数%d\r\n",encode);
		speed=encode/390.0f/4.0f/0.05f;
		printf("转速%f\r\n",speed);		
	}
	TIM_ClearITPendingBit(TIM5,TIM_IT_Update);        
}

但是在实际的工程中,我们是需要对正转、反转都需要检测的,可以通过TIM的控制寄存器的第四位来判断

计算正反转中一共产生的脉冲数目,利用设置标志位来识别正反转。

u32 Read_Encoder(void)
{
  u32 Count;                                                     
  u16 Current_Count;                                              
	u16 Enc_Timer_Overflow_one;	                                   
  Enc_Timer_Overflow_one=Encoder_Timer_Overflow;                  
  Current_Count = TIM_GetCounter(TIM3);                           
  Encoder_Timer_Overflow=0;                                       
	if((TIM3->CR1&0x0010) == 0x0010)    
	{
				flag=1;          //Reversal flag
		
    Count = (u32)((Enc_Timer_Overflow_one)*(4*ENCODER_PPR) +(Previous_Count-Current_Count));  
	}
	else    
	{
		flag =0;            //Forward sign
Count = (u32)(Current_Count - Previous_Count + (Enc_Timer_Overflow_one) * (4*ENCODER_PPR));       
	}		
  Previous_Count = Current_Count;  
  return(Count);
}

  • 10
    点赞
  • 60
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值