平衡小车—编码器使用教程与测速原理

简介: >来自**平衡小车之家**,与大家一起学习编码器使用与测速原理。
来自 平衡小车之家,与大家一起学习编码器使用与测速原理。

1.编码器概述

  编码器是一种将角位移或者角速度转换成一连串电数字脉冲的旋转式传感器,我们可以通过编码器测量到底位移或者速度信息。编码器从输出数据类型上分,可以分为增量式编码器和绝对式编码器。
  从编码器检测原理上来分,还可以分为光学式、磁式、感应式、电容式。常见的是光电编码器(光学式)和霍尔编码器(磁式)。

2.编码器原理

  光电编码器是一种通过光电转换将输出轴上的机械几何位移量转换成脉冲或数字量的传感器。光电编码器是由光码盘和光电检测装置组成。光码盘是在一定直径的圆板上等分地开通若干个长方形孔。由于光电码盘与电动机同轴,电动机旋转时,检测装置检测输出若干脉冲信号,为判断转向,一般输出两组存在一定相位差的方波信号。

  霍尔编码器是一种通过磁电转换将输出轴上的机械几何位移量转换成脉冲或数字量的传感器。霍尔编码器是由霍尔码盘和霍尔元件组成。霍尔码盘是在一定直径的圆板上等分地布置有不同的磁极。霍尔码盘与电动机同轴,电动机旋转时,霍尔元件检测输出若干脉冲信号,为判断转向,一般输出两组存在一定相位差的方波信号。

  可以看到两种原理的编码器目的都是获取AB相输出的方波信号,其使用方法也是一样,下面是一个简单的示意图。

3.编码器接线说明

  具体到我们的编码器电机,我们可以看看电机编码器的实物。

  这是一款增量式输出的霍尔编码器。编码器有AB相输出,所以不仅可以测速,还可以辨别转向。根据上图的接线说明可以看到,我们只需给编码器电源5V供电,在电机转动的时候即可通过AB相输出方波信号。编码器自带了上拉电阻,所以无需外部上拉,可以直接连接到单片机IO读取。

4.编码器软件四倍频技术

  下面我们说一下编码器倍频的原理。为了提高大家下面学习的兴趣,我们先明确,这是一项实用的技术,可以真正地把编码器的精度提升4倍。作用可类比于单反相机的光学变焦,而并非牺牲清晰度来放大图像的数码变焦。
  0K,先看看下面编码器输出的波形图。

  这里,我们是通过软件的方法实现四倍频。首先可以看到上图编码器输出的AB相波形,正常情况下我们使用M法测速的时候,会通过测量单位时间内A相输出的脉冲数来得到速度信息。常规的方法,我们只测量A相(或B相)的上升沿或者下降沿,也就是上图中对应的数字1234中的某一个,这样就只能计数3次。而四倍频的方法是测量A相和B相编码器的上升沿和下降沿。这样在同样的时间内,可以计数12次(3个1234的循环)。这就是软件四倍频的原理。

**************************************************************************/
/**************************************************************************
函数功能:把TIM2初始化为编码器接口模式
入口参数:无
返回  值:无
**************************************************************************/
void Encoder_Init_TIM2(void)
{
  TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;  
  TIM_ICInitTypeDef TIM_ICInitStructure;  
  GPIO_InitTypeDef GPIO_InitStructure;
 
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);//使能定时器2的时钟
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//使能PB端口时钟
    
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;    //端口配置
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
  GPIO_Init(GPIOA, &GPIO_InitStructure);                          //根据设定参数初始GPIOB
  
  TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
  TIM_TimeBaseStructure.TIM_Prescaler = 0x0; // 预分频器 
  TIM_TimeBaseStructure.TIM_Period = ENCODER_TIM_PERIOD; //设定计数器自动重装值
  TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;//选择时钟分频:不分频
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;////TIM向上计数  
  TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
  TIM_EncoderInterfaceConfig(TIM2, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, 
  TIM_ICPolarity_Rising);//使用编码器模式3,模式3就我们在这里所说的4倍频,详细信息查看stm32f1技术手册
 
  TIM_ICStructInit(&TIM_ICInitStructure);
  TIM_ICInitStructure.TIM_ICFilter = 10;
  TIM_ICInit(TIM2, &TIM_ICInitStructure);
 
  TIM_ClearFlag(TIM2, TIM_FLAG_Update);//清除TIM的更新标志位
  TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
  //Reset counter
 
  TIM_SetCounter(TIM2,0);
  TIM_Cmd(TIM2, ENABLE); 
}
/**************************************************************************
函数功能:把TIM4初始化为编码器接口模式  和TIM2同理
入口参数:无
返回  值:无
**************************************************************************/
void Encoder_Init_TIM4(void)
{
  TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;  
  TIM_ICInitTypeDef TIM_ICInitStructure;  
  GPIO_InitTypeDef GPIO_InitStructure;
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);//使能定时器4的时钟
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//使能PB端口时钟
    
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;    //端口配置
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
  GPIO_Init(GPIOB, &GPIO_InitStructure);                          //根据设定参数初始化GPIOB
  
  TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
  TIM_TimeBaseStructure.TIM_Prescaler = 0x0; // 预分频器 
  TIM_TimeBaseStructure.TIM_Period = ENCODER_TIM_PERIOD; //设定计数器自动重装值
  TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;//选择时钟分频:不分频
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;////TIM向上计数  
  TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
  TIM_EncoderInterfaceConfig(TIM4, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising,TIM_ICPolarity_Rising);//使用编码器模式3
  
  TIM_ICStructInit(&TIM_ICInitStructure);
  
  TIM_ICInitStructure.TIM_ICFilter = 10;
  TIM_ICInit(TIM4, &TIM_ICInitStructure);
  TIM_ClearFlag(TIM4, TIM_FLAG_Update);//清除TIM的更新标志位
  TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);
  //Reset counter
  TIM_SetCounter(TIM4,0);
  TIM_Cmd(TIM4, ENABLE); 
}

5.单片机如何采集编码器数据

  因为编码器输出的是标准的方波,所以我们可以使用单片机(STM32\STM851等)直接读取。在软件中的处理方法是分两种,自带编码器接口的单片机如STM32,可以直接使用硬件计数。而没有编码器接口的单片机如51单片机,可以通过外部中断读取,比如把编码器A相输出接到单片机的外部中断输入口,这样就可通过跳变沿触发中断,然后在对应的外部中断服务函数里面,通过B相的电平来确定正反转。如当A相来一个跳变沿的时候,如果B相是高电平就认为是正转,低电平就认为是反转。

/**************************************************************************
函数功能:单位时间读取编码器计数
入口参数:定时器
返回  值:速度值
**************************************************************************/
int Read_Encoder(u8 TIMX)
{
    int Encoder_TIM;    
   switch(TIMX)
     {
       case 2:  Encoder_TIM= (short)TIM2 -> CNT;  TIM2 -> CNT=0;break;
       case 3:  Encoder_TIM= (short)TIM3 -> CNT;  TIM3 -> CNT=0;break;    
       case 4:  Encoder_TIM= (short)TIM4 -> CNT;  TIM4 -> CNT=0;break;    
       default: Encoder_TIM=0;
     }
        return Encoder_TIM;
}
/**************************************************************************
函数功能:TIM4中断服务函数
入口参数:无
返回  值:无
**************************************************************************/
void TIM4_IRQHandler(void)
{                                       
    if(TIM4->SR&0X0001)//溢出中断
    {                                                        
    }                   
    TIM4->SR&=~(1<<0);//清除中断标志位         
}
/**************************************************************************
函数功能:TIM2中断服务函数
入口参数:无
返回  值:无
**************************************************************************/
void TIM2_IRQHandler(void)
{                                       
    if(TIM2->SR&0X0001)//溢出中断
    {                                                        
    }                   
    TIM2->SR&=~(1<<0);//清除中断标志位         
}

6.获取方式

  测试编码器代码获取方式,关注微信公众号:果果小师弟,后套回复:编码器。即可获取STM32测试编码器代码。

相关文章
|
编解码 监控 安全
红外成像仪开发版学习注意要点
三河凡科科技飞讯红外成像仪开发学习注意要点 红外成像仪主要用于检测和识别物体的热量,并将其转化为可见的图像。它可以用于许多应用,包括夜视、安全监控、军事、医疗和工业控制等领域。在开发红外成像仪时需要注意以下几个要点。
红外成像仪开发版学习注意要点
|
编解码 人工智能 移动开发
AIGC图像分辨率太低?快来试试像素感知扩散超分模型,你想要的细节都在这里
阿里巴巴最新自研的像素感知扩散超分模型已经开源,它把扩散模型强大的生成能力和像素级控制能力相结合,能够适应从老照片修复到AIGC图像超分的各种图像增强任务和各种图像风格,并且能够控制生成强度和增强风格。这项技术的直接应用之一是AIGC图像的后处理增强和二次生成,能够带来可观的效果提升。
923 4
|
安全 关系型数据库 网络安全
一步步实现SDDC-vRNI加速实现安全微分段
实验摘要: 1>利用vRealize Network Insight配置业务安全微分段策略 [难度★★复杂度★★★] 2>利用vRealize Network Insight优化业务安全微分段策略 [难度★★复杂度★★★]
|
固态存储 算法 计算机视觉
MobileDenseNet | 一步步打造全新的轻量化目标检测模型,让SSD继续发光发热
MobileDenseNet | 一步步打造全新的轻量化目标检测模型,让SSD继续发光发热
217 0
学不动系列 | YolactEdge:边缘设备上的实时实例分割(Xavier: 30 FPS,附源码与论文)(二)
学不动系列 | YolactEdge:边缘设备上的实时实例分割(Xavier: 30 FPS,附源码与论文)(二)
78 0
|
编解码 算法 计算机视觉
学不动系列 | YolactEdge:边缘设备上的实时实例分割(Xavier: 30 FPS,附源码与论文)(一)
学不动系列 | YolactEdge:边缘设备上的实时实例分割(Xavier: 30 FPS,附源码与论文)(一)
237 0
|
机器学习/深度学习 人工智能 算法
Jay Alammar再发新作:超高质量图解Stable Diffusion,看完彻底搞懂「图像生成」原理(1)
Jay Alammar再发新作:超高质量图解Stable Diffusion,看完彻底搞懂「图像生成」原理
275 0
Jay Alammar再发新作:超高质量图解Stable Diffusion,看完彻底搞懂「图像生成」原理(3)
Jay Alammar再发新作:超高质量图解Stable Diffusion,看完彻底搞懂「图像生成」原理
183 0
|
数据可视化 计算机视觉
Jay Alammar再发新作:超高质量图解Stable Diffusion,看完彻底搞懂「图像生成」原理(2)
Jay Alammar再发新作:超高质量图解Stable Diffusion,看完彻底搞懂「图像生成」原理
198 0
|
传感器 编解码 人工智能
史上最全 | 单目相机测距测速方法大盘点!(上)
在精确检测车速车距的方案中,视觉方案是非常具有挑战性的,但由于没有昂贵的距离传感器而大幅降低成本,所以潜力巨大。本文综述了基于视觉的车辆速度、距离估计。并建立了一个完整的分类法,对大量工作进行分类,对涉及的所有阶段进行分类。除此之外,还提供了详细的性能评估指标和可用数据集概述。最后,论文讨论了当前的局限性和未来的方向。
史上最全 | 单目相机测距测速方法大盘点!(上)