STM32F103 数字滤波的编码器测速

工作中经常遇到需要连续测速的应用,担心编码器“抖动”,导致速度测不准

一. 简单原理

      编码器计数  ---->  数值取样  ----> 差分  ----> FIR滤波  ---->  比例计算实际速度

二. 硬件接口

  STM32F103 数字滤波的编码器测速_第1张图片

 

三. 差分计算

  

#define MAXCOUNT1  		20000		//最大计数值 per 0.1s
#define ENCODER_TIM_PERIOD 	39999		//计数自动重装值 值在 0 到 39999之间
/*使用100ms 定时器,定时调用该函数*/
int16_t Enc_GetCount(void)
{
	static uint16_t last_count = 0;
	uint16_t cur_count;

	cur_count = __HAL_TIM_GetCounter(&htim2);      /*获取编码计数值*/
	
	int32_t Angle = cur_count - last_count;
	
	if(Angle > MAXCOUNT1)                          /*判定上溢出*/
	{
		Angle -= ENCODER_TIM_PERIOD;
	}
	if(Angle < -MAXCOUNT1)                         /*判定下溢出*/
	{
		Angle += ENCODER_TIM_PERIOD;
	}
	
	last_count = cur_count;
	
	return Angle;                                  /*返回差分值*/
}

四. FIR滤波器

  使用matlab 的 FDAtool工具,设计FIR滤波器

STM32F103 数字滤波的编码器测速_第2张图片

采样频率Fs = 10Hz  阶数order = 5(过长延迟增加)

导出滤波器参数

h(6) =

   -0.0691    0.0296    0.5204    0.5204    0.0296   -0.0691

STM32F103 数字滤波的编码器测速_第3张图片

C语言实现的FIR滤波器计算

/*简单的FIR滤波器*/
const float h[6] = {-0.0691  ,0.0296 ,0.5204 ,0.5204 ,0.0296 ,-0.0691}
float Fir_Filter(int16_t xn)
{
    static int16_t xx[6] = {0};        /*FIR 长度6*/
    float ret;
    int16_t i;

    xx[0] = xn;
    
    ret = xx[0] * h[0];

    for(i = 5;i > 0;i--)
    {
        ret += h(i) * xx[i];
        xx(i) = xx(i-1);
    }
    
    return ret;
}

5. 计算速度

    结合编码器一圈的脉冲数,可以换算成速度   如角频率,圈每分,圈每秒等

 

 

 

你可能感兴趣的:(嵌入式软件)