首页 > 其他分享 >龙邱512正交编码器

龙邱512正交编码器

时间:2023-08-06 18:55:45浏览次数:66  
标签:编码器 Pin 正交 TIM GPIO 512 my define

基本概念

龙邱的512线正交编码器,工作电压在3.3v-5v
我们只需要关注该款编码器的LSB及DIR引脚。

LSP:该引脚在编码器转动时,会输出步进脉冲,在不同的转速下,步进脉冲的数量是不同的。
所以我们可以设置一个定时器,把定时器的时钟输入通道改为外部引脚输入,这样我们就可以把单片机时钟的GPIO引脚接到编码器的LSP端口处。然后读取定时器的计数数量,就能获取到当前编码器当前的脉冲数量。
一次脉冲定时器就会计数一次。
另外一种方案是设置引脚上升沿或者下降沿中断来记录脉冲次数。
本文使用的是定时器计数

DIR:该引脚在编码器正转反转时输出的电平是不一样的,可以人为的界定。
可以设为Dir为高电平为正转,Dir为低电平为反转。该引脚连接的GPIO端口只需要设置为输入模式读取高低电平就可以了

注意部分

  • 要注意每次读取的时间间隔要是一定的。比如定时10ms读取一次。否则数值会与实际相差很大。
  • 由于会有误差,可以采用一阶线性滤波,这样就可以是数据更加的稳定,本文已经提供

程序实现部分 (基于STC32)

.H文件

/**
  ******************************************************************************
  * @file           : encoder.h
  * @author         : 宋明泽
  * @brief          : None
  * @attention      : None
  * @date           : 2023/5/2
  ******************************************************************************
  */

#ifndef INC_0_TEST_ENCODER_H
#define INC_0_TEST_ENCODER_H
#include "STC32G_Timer.h"

#define my_TIM3                 Timer3
#define my_TIM4                 Timer4

#define my_TIM_Mode             TIM_16BitAutoReload //16位自动重装载
#define my_TIM_CLOCK_Source     TIM_CLOCK_Ext //外部引脚输入
#define my_TIM_CLOCK_Out        DISABLE
#define my_TIM_Value            0
#define my_TIM_Run              ENABLE

// DIR方向引脚
#define Left1_Port              GPIO_P0
#define Left1_Pin               GPIO_Pin_4
#define Left2_Port              GPIO_P0
#define Left2_Pin               GPIO_Pin_5
#define Left_Direction          P05
#define Right1_Port             GPIO_P0
#define Right1_Pin              GPIO_Pin_6
#define Right2_Port             GPIO_P0
#define Right2_Pin              GPIO_Pin_7
#define Right_Direction         P07
//a的取值决定了算法的灵敏度,a越大,新采集的值占的权重越大,算法越灵敏,但平顺性差;相反,a越小,新采集的值占的权重越小,灵敏度差,但平顺性好。
#define A_R                     0.853f  //右电机A参数
#define A_L                     0.88f   //左电机A参数

void Encoder_Init(void);
/**
  * 函数说明: 读取编码器的值
  * 参数:    左右编码器 'L'跟'R'
  * 返回值:   float 一阶线性滤波值
*/
float Read_Encoder(u8 encno);
/**
  * 函数说明: 一阶滤波  本次滤波值 = a*本次采样值 + (1-a)*上次的滤波输出值
  * 参数:    编码器测得值
  * 返回值:   滤波后的值
*/
float First_Order_Filtering(int32 value, float A);
#endif //INC_0_TEST_ENCODER_H

.C文件

//a的取值决定了算法的灵敏度,a越大,新采集的值占的权重越大,算法越灵敏,但平顺性差;相反,a越小,新采集的值占的权重越小,灵敏度差,但平顺性好。
#define A_R                     0.853f  //右电机A参数
#define A_L                     0.88f   //左电机A参数

float last_Value;

void Encoder_Init(void)
{
    TIM_InitTypeDef my_tim_init;
    GPIO_InitTypeDef gpioInitTypeDef;


    my_tim_init.TIM_Mode = my_TIM_Mode;
    my_tim_init.TIM_ClkSource = my_TIM_CLOCK_Source; 
    my_tim_init.TIM_ClkOut = my_TIM_CLOCK_Out;
    my_tim_init.TIM_Value = 0;
    my_tim_init.TIM_Run = my_TIM_Run;

    Timer_Inilize(my_TIM3, &my_tim_init);
    Timer_Inilize(my_TIM4, &my_tim_init);

    gpioInitTypeDef.Mode = GPIO_PullUp;
    gpioInitTypeDef.Pin = Left1_Pin;
    GPIO_Inilize(Left1_Port,&gpioInitTypeDef);
    gpioInitTypeDef.Pin = Left2_Pin;
    GPIO_Inilize(Left2_Port,&gpioInitTypeDef);
    gpioInitTypeDef.Pin = Right1_Pin;
    GPIO_Inilize(Right1_Port,&gpioInitTypeDef);
    gpioInitTypeDef.Pin = Right2_Pin;
    GPIO_Inilize(Right2_Port,&gpioInitTypeDef);

    NVIC_Timer3_Init(DISABLE,Priority_2);// 中断优先级2
    NVIC_Timer4_Init(DISABLE,Priority_2);// 中断优先级2
}

/**
  * 函数说明: 读取编码器的值
  * 参数:    左右编码器 'L'跟'R'
  * 返回值:   float 一阶线性滤波值
*/
float Read_Encoder(u8 encno)
{
    int32 tm=0;
    float value;
    if(encno=='R')
    {
        T4T3M &= ~(1<<7); //暂停定时器4
        tm = T4H;
        if(Right_Direction)//编码器2计数A:P06  DIR:P07
            tm=0-((tm<<8)|T4L);
        else
            tm=(tm<<8)|T4L;
        T4H = 0;
        T4L = 0;
        T4T3M |= (1<<7); //启动定时器4

        value = First_Order_Filtering(tm,A_R);
    }
    else if(encno=='L')
    {
        T4T3M &= ~(1<<3); //暂停定时器3
        tm = T3H;
        if(Left_Direction)//编码器2计数A:P04  DIR:P05
            tm=0-((tm<<8)|T3L);
        else
            tm=(tm<<8)|T3L;
        T3H = 0;
        T3L = 0;
        T4T3M |= (1<<3);//启动定时器3

        value = First_Order_Filtering(tm,A_L);
    }
    return value;
}

/**
  * 函数说明: 一阶滤波 本次滤波值 = a*本次采样值 + (1-a)*上次的滤波输出值
  * 参数:    编码器测得值
  * 返回值:   滤波后的值
*/
float First_Order_Filtering(int32 value, float A)
{
    float out_value;
    out_value = A*(float)value - (1-A)*last_Value;
    last_Value = out_value;
    return out_value;
}

标签:编码器,Pin,正交,TIM,GPIO,512,my,define
From: https://www.cnblogs.com/songmingze/p/17609706.html

相关文章

  • 施密特正交化
    目录公式推导拓展公式\[\left\{\begin{aligned}&\beta_1=\alpha_1\\&\beta_2=\alpha_2-\frac{(\alpha_2,\beta_1)}{(\beta_1,\beta_1)}\beta_1\\&\beta_3=\alpha_3-\frac{(\alpha_3,\beta_1)}{(\beta_1,\beta_1)}\beta_1-......
  • matlab做施密特正交
    fori=1:tiqvduanifi==1shimi=[shimi,duan(:,i)]elsetou=duan(:,i)'*shimimo=shimi.*shimimo=sum(mo,1)%mo=sqrt(mo)k=tou./mok=repmat(k,[h1])alltou=k.*shimialltou=sum(alltou,2)shimi=[shimi,duan(:,i)-alltou]endendshimo=repmat(sqrt(sum(shimi.*shimi,1)),[......
  • EC11编码器消抖
    前言之前在网上看到一篇文章优雅的对旋转编码器消抖(EC11,正交)-知乎(zhihu.com)感觉大佬用的方法挺不错的,这里在STM32上使用一下看下效果。消抖原理消抖的核心思路:A脚设置为上升下降沿均会进中断,下降上升一个变换周期,判断这个周期的A脚,B脚的始末状态,来判断正反转一次。......
  • 基于32位Cortex®-M4内核MK26FN2M0VMI18、MK22FN256VMP12、MK22FN512VLL12 180MHz/120
    一、MK26FN2M0VMI18KinetisK2032位微控制器是一款低功耗MCU,通过智能片上集成节省了大量BOM。该MCU基于Arm®Cortex®-M4核心,提供完整和可选的高速USB2.0(OTG控制器),包括无晶器件功能选项。此器件具有2MB的闪存,256KB的SRAM和多达2个USB控制器。详细描述:ARM®Cortex®-M4Kine......
  • oracle数据库临时表空间损坏,报错ORA-01116,ORA-01110 ,ORA-27041,ORA-06512的解决方式
     打脚本的时候报错:ORA-01116:打开数据库文件203时出错ORA-01110:数据文件203:'/u01/app/oracle/oradata/temp02.dbf'ORA-27041:无法打开文件Linux-x86_64Error:2:NosuchfileordirectoryAdditionalinformation:3ORA-06512:在line9  是我们环境的临时表空间......
  • Auto Encoder(自编码器)
    AutoEncoder(自编码器)SelfSupervisedLearning(自监督学习):用没有标注的资料训练模型,发明不需要标注资料上的任务,例如:做填空题、预测下一个token(符号);在BERT和GPT之前,有一种方法就是AutoEncoderAutoEncoder(自编码器):也是一种用没有标注的资料训练的模型AutoEncoder运作方式:......
  • java rmi上传下载512字节OutputStream
    /*JADXINFO:Accessmodifierschangedfrom:protected*/publicfinalvoiddownloadFile(Parameterparameter,OutputStreamout)throwsXException{if(!this.session.isEffective()){thrownewXException(10000000,"连接会话无效&......
  • 【雕爷学编程】Arduino动手做(40)---KY-040旋转编码器模块2
    37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的。鉴于本人手头积累了一些传感器和执行器模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的,这里准备逐一动手试试多做实验,不管成功与否,都会记录下来——小小的进步或是搞不掂的问题......
  • 240-960MHz带编码器的单片OOK 发射器CMT2157B
    CMT2157B是一款真正意义上的单芯片、高灵活性、超低功耗、带编码器的OOK射频发射芯片,非常适合于240至960MHz的无线应用场合。该芯片可实现完全兼容市面上最常用的527、1527、2262和2240等编码格式。此外,还支持用户各种自定义编码。该芯片支持4个独立按键或多达10个扫描按......
  • CF512D Fox And Travelling 题解--zhengjun
    计数好题。首先对于每个连通块独立考虑,最后合并答案。发现点数超过1的强连通分量一定删不掉。若连通块中存在点数超过1的强连通分量tarjan缩点之后,称这些点数超过1的强连通分量为关键点;那么两关键点之间的点也不能删;于是对于剩下的点直接dp即可,由于可删的子树......