编码器介绍与应用

news2024/11/26 21:51:17

一.概述

1.编码器

编码器,是一种用来测量机械旋转或位移的传感器。这种传感器能够测量机械部件在旋转或直线运动时的位移位置或速度等信息,并将其转换成一系列电信号。其可和电机组装到一起用,反馈电机方向、转换角度的,然后电机根据反馈再动作纠偏,提升精度。

编码器是工业中常用的传感器之一,广泛应用于工业生产当中需要对机械系统进行监视或控制的场景,包括工业控制、机器人、照相机镜头、雷达平台以及部分计算机输入设备例如轨迹球和鼠标滚轮等等。

2.增量型编码器

增量型编码器是能够根据旋转运动产生信号的编码器,其刻度方式为每一个脉冲都进行增量计算,因此得名。

增量式旋转编码器是将设备运动时的位移信息变成连续的脉冲信号,脉冲个数表示位移量的大小。只有当设备运动的时候增量式编码器才会输出信号。编码器一般会把这些信号分为通道 A

和通道 B 两组输出,并且这两组信号间有 90° 的相位差。同时采集这两组信号就可以知道设备的运动和方向。除了通道 A、通道 B 以外,很多增量式编码器还会设置一个额外的通道 Z 输出信

号,用来表示编码器特定的参考位置,传感器转一圈 Z 轴信号才会输出一个脉冲。增量式编码器只输出设备的位置变化和运动方向,不会输出设备的绝对位置。

3.增量编码器结构

增量型编码器由一个中心有轴的光电码盘,其上有环形通、暗的刻线,有光电发射和接收器件读取,获得四组正弦波信号组合成A、B、C、D,每个正弦波相差90度相位差(相对于一个周波为360度),将C、D信号反向,叠加在A、B两相上,

可增强稳定信号;另每转输出一个Z相脉冲以代表零位参考位。由于A、B两相相差90度,可通过比较A相在前还是B相在前,以判别编码器的正转和反转,通过零位脉冲,可获得编码器的零位参考位。

分辨率―编码器以每旋转360度提供多少的通或暗刻线称为分辨率,也称解析分度、或直接称多少线,一般在每转分度5~10000线。

4.编码器基本参数

分辨率:

指编码器能够分辨的最小单位。对于增量式编码器,其分辨率表示为编码器转轴旋转一圈所产生的脉冲数,即脉冲数/转 (Pulse Per Revolution 或 PPR)。码盘上透光线槽的数

目其实就等于分辨率,也叫多少线,较为常见的有 5-6000 线。对于绝对式编码器,内部码盘所用的位数就是它的分辨率,单位是位 (bit),具体还分单圈分辨率和多圈分辨率。

精度:

首先明确一点,精度与分辨率是两个不同的概念。精度是指编码器每个读数与转轴实际位置间的最大误差,通常用角度、角分或角秒来表示。例如有些绝对式编码器参数表

里会写 ±20′′,这个就表示编码器输出的读数与转轴实际位置之间存在正负 20 角秒的误差,精度由码盘刻线加工精度、转轴同心度、材料的温度特性、电路的响应时间等各方面因素

共同决定。

最大响应频率:

指编码器每秒输出的脉冲数,单位是 Hz。计算公式:最大响应频率 = 分辨率 * 轴转速/60。

信号输出形式:

对于增量式编码器,每个通道的信号独立输出,输出电路形式通常有集电极开路输出、推挽输出、差分输出等。对于绝对式编码器,由于是直接输出几十位的二进

制数,为了确保传输速率和信号质量,一般采用串行输出或总线型输出,例如同步串行接口 (SSI)、RS485、CANopen 或 EtherCAT 等,也有一部分是并行输出,输出电路形式与增量

式编码器相同。

二.程序

1.硬件接口

STM32芯片内部有专门用来采集增量式编码器方波信号的接口,这些接口实际上是 STM32 定时器的其中一种功能。不过F407编码器接口功能只有高级定时器 TIM1、TIM8 和通用定时器 TIM2 到TIM5 才有。

2.增量式编码器程序设计,两个步骤:

①如何判断转动方向

②如何将脉冲数准确;  

第一个问题,如何根据编码器的脉冲判断电机的转动方向。

    目前比较常见的方法:使用DSP或者STM32,检测到A相信号的下降沿时触发中断,检测此时的B相信号的电平高低,如果电平为低,则为正转;如果为高,则为反转(正反转方向每个人的定义不同,不影响,只要根据自己的需要定义就行)。  

第二个问题的解决方案其实已经在上面说差不多了,如果为了提高精度,可以在A相信号的上升沿和下降沿都进行检测以及可以避免A相信号的下降沿和Z相信号上升沿重合

   (用A相信号的下降沿作为触发条件去检测Z相信号的高低,重合时检测不到,这也是我使用二倍频的原因),没有检测到从而不能及时清零的问题。

3.编码器定时器检测代码

/* 定时器溢出次数 */

__IO int16_t Encoder_Overflow_Count = 0;

TIM_HandleTypeDef TIM_EncoderHandle;

/**

  * @brief  编码器接口引脚初始化

  * @param  无

  * @retval 无

  */

static void Encoder_GPIO_Init(void)

{

  GPIO_InitTypeDef GPIO_InitStruct = {0};

  

  /* 定时器通道引脚端口时钟使能 */

  ENCODER_TIM_CH1_GPIO_CLK_ENABLE();

  ENCODER_TIM_CH2_GPIO_CLK_ENABLE();

  

  /* 设置输入类型 */

  GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;

  /* 设置上拉 */

  GPIO_InitStruct.Pull = GPIO_PULLUP;

  /* 设置引脚速率 */

  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;

  

  /* 选择要控制的GPIO引脚 */

  GPIO_InitStruct.Pin = ENCODER_TIM_CH1_PIN;

  /* 设置复用 */

  GPIO_InitStruct.Alternate = ENCODER_TIM_CH1_GPIO_AF;

  /* 调用库函数,使用上面配置的GPIO_InitStructure初始化GPIO */

  HAL_GPIO_Init(ENCODER_TIM_CH1_GPIO_PORT, &GPIO_InitStruct);

  

  /* 选择要控制的GPIO引脚 */

  GPIO_InitStruct.Pin = ENCODER_TIM_CH2_PIN;

  /* 设置复用 */

  GPIO_InitStruct.Alternate = ENCODER_TIM_CH2_GPIO_AF;

  /* 调用库函数,使用上面配置的GPIO_InitStructure初始化GPIO */

  HAL_GPIO_Init(ENCODER_TIM_CH2_GPIO_PORT, &GPIO_InitStruct);

}

/**

  * @brief  配置TIMx编码器模式

  * @param  无

  * @retval 无

  */

static void TIM_Encoder_Init(void)

{

  TIM_Encoder_InitTypeDef Encoder_ConfigStructure;

  

  /* 使能编码器接口时钟 */

  ENCODER_TIM_CLK_ENABLE();

  

  /* 定时器初始化设置 */

  TIM_EncoderHandle.Instance = ENCODER_TIM;

  TIM_EncoderHandle.Init.Prescaler = ENCODER_TIM_PRESCALER;

  TIM_EncoderHandle.Init.CounterMode = TIM_COUNTERMODE_UP;

  TIM_EncoderHandle.Init.Period = ENCODER_TIM_PERIOD;

  TIM_EncoderHandle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

  TIM_EncoderHandle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;

  

  /* 设置编码器倍频数 */

  Encoder_ConfigStructure.EncoderMode = ENCODER_MODE;

  /* 编码器接口通道1设置 */

  Encoder_ConfigStructure.IC1Polarity = ENCODER_IC1_POLARITY;

  Encoder_ConfigStructure.IC1Selection = TIM_ICSELECTION_DIRECTTI;

  Encoder_ConfigStructure.IC1Prescaler = TIM_ICPSC_DIV1;

  Encoder_ConfigStructure.IC1Filter = 0;

  /* 编码器接口通道2设置 */

  Encoder_ConfigStructure.IC2Polarity = ENCODER_IC2_POLARITY;

  Encoder_ConfigStructure.IC2Selection = TIM_ICSELECTION_DIRECTTI;

  Encoder_ConfigStructure.IC2Prescaler = TIM_ICPSC_DIV1;

  Encoder_ConfigStructure.IC2Filter = 0;

  /* 初始化编码器接口 */

  HAL_TIM_Encoder_Init(&TIM_EncoderHandle, &Encoder_ConfigStructure);

  

  /* 清零计数器 */

  __HAL_TIM_SET_COUNTER(&TIM_EncoderHandle, 0);

  

  /* 清零中断标志位 */

  __HAL_TIM_CLEAR_IT(&TIM_EncoderHandle,TIM_IT_UPDATE);

  /* 使能定时器的更新事件中断 */

  __HAL_TIM_ENABLE_IT(&TIM_EncoderHandle,TIM_IT_UPDATE);

  /* 设置更新事件请求源为:计数器溢出 */

  __HAL_TIM_URS_ENABLE(&TIM_EncoderHandle);

  

  /* 设置中断优先级 */

  HAL_NVIC_SetPriority(ENCODER_TIM_IRQn, 5, 1);

  /* 使能定时器中断 */

  HAL_NVIC_EnableIRQ(ENCODER_TIM_IRQn);

  

  /* 使能编码器接口 */

  HAL_TIM_Encoder_Start(&TIM_EncoderHandle, TIM_CHANNEL_ALL);

}

/**

  * @brief  编码器接口初始化

  * @param  无

  * @retval 无

  */

void Encoder_Init(void)

{

  Encoder_GPIO_Init();    /* 引脚初始化 */

  TIM_Encoder_Init();     /* 配置编码器接口 */

}

/**

  * @brief  定时器更新事件回调函数

  * @param  无

  * @retval 无

  */

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)

{

  /* 判断当前计数器计数方向 */

  if(__HAL_TIM_IS_TIM_COUNTING_DOWN(htim))

    /* 下溢 */

    Encoder_Overflow_Count--;

  else

    /* 上溢 */

    Encoder_Overflow_Count++;

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1671338.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MongoDB和AI 赋能行业应用:制造业和汽车行业

欢迎阅读“MongoDB和AI 赋能行业应用”系列的第一篇。 本系列重点介绍AI应用于不同行业的关键用例,涵盖制造业和汽车行业、金融服务、零售、电信和媒体、保险以及医疗保健行业。 随着人工智能(AI)在制造业和汽车行业的集成,传统…

求四个整数中的最大值(函数)(C语言)

一、N-S流程图&#xff1b; 二、运行结果&#xff1b; 三、源代码&#xff1b; # define _CRT_SECURE_NO_WARNINGS # include <stdio.h>int main() {//初始化变量值&#xff1b;int a, b, c, d, max;//获取用户输入的数据&#xff1b;printf("请输入4个整数&#x…

内部开发平台如何赋能开发人员与业务

一个厨师只有具备烹饪美食的技能与经验&#xff0c;并且在设备、工具齐全的餐厅里才能发挥他的才能。交响乐团需要正确的乐器、指挥家和舞台才能演奏初美妙的音乐。 而在软件开发的世界&#xff0c;开发人员需要最好的工具包和开发环境来设计开发他们的软件项目。这个环境就被…

Mysql数据类型设计思考

一、Mysql数据类型设计规范 1.1 选择更小的数据类型 一般情况下&#xff0c;在满足存储要求的基础上&#xff0c;尽量选择小的存储类型。例如&#xff1a;存储0~200&#xff0c;tinyint和bigint都可以存储&#xff0c;那么选择tinyint。原因&#xff1a;越小的数据类型运算速…

计算机组成原理(超详解!!) 第七节 中央处理器(下)

1.微程序控制器 微程序设计技术&#xff1a;利用软件方法来设计硬件的一门技术。 微程序控制器的基本思想&#xff1a; 仿照通常的解题程序的方法&#xff0c;把操作控制信号编成所谓的“微指令”&#xff0c;存放到一个只读存储器里。当机器运行时&#xff0c;一条又一条地…

高速电流反馈运放总结

目录 前言 基础架构 CFB运算放大器拓扑结构的进步 前言 最近项目发现有震荡&#xff0c;发现是电流反馈型运放导致&#xff0c;所以对电流运放的知识做了全面的复习。 基础架构 现在&#xff0c;我们将详细考察高速运算放大器中非常流行的电流反馈(CFB)运算放大器拓扑结 构…

Vue 局部布局 Layout 内部布局 [el-row]、[el-col]

之前的布局容器是一个整体的框架&#xff0c;layout里面的布局其实就是el-row和el-col的组合。 基础布局 使用单一分栏创建基础的栅格布局。 通过 ​row ​和 ​col ​组件&#xff0c;并通过 ​col ​组件的 ​span ​属性我们就可以自由地组合布局。 这种最简单&#xff0c;…

网络库-libevent介绍

1.简介 libevent是一个事件驱动的网络库&#xff0c;主要用于构建可扩展的网络服务器。它提供了跨平台的API&#xff0c;支持多种事件通知机制&#xff0c;如select、poll、epoll、kqueue等。 主要组件 event: 表示一个具体的事件&#xff0c;包括事件类型、事件回调等。eve…

Office之Word应用(二)

一、页眉添加文件名称和页码 1、双击页眉&#xff0c;点击“页眉-空白&#xff08;三栏&#xff09;” 2、删掉第一处&#xff08;鼠标放在上面就会选中&#xff0c;Enter即可&#xff09;&#xff0c;第二处输入文档名称&#xff0c;第三处插入页码。 注&#xff1a;插入页码时…

【CSP CCF记录】202203-2 出行计划

题目 过程 第一次提交 暴力求解&#xff0c;时间复杂度为n*n&#xff0c;超时 #include<bits/stdc.h> using namespace std; const int N100001; int n,m,k; int t[N],c[N],q[N]; int main() {cin>>n>>m>>k;for(int i0;i<n;i){cin>>t[i]&g…

计算机视觉的应用30-基于深度卷积神经网络CNN模型实现物体表面缺陷检测技术的项目

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下计算机视觉的应用30-基于深度卷积神经网络CNN模型实现物体表面缺陷检测技术的项目主要包括&#xff1a;物体表面缺陷检测技术项目介绍&#xff0c;数据构造&#xff0c;模型介绍。 物体表面缺陷检测技术是工业自动化…

深入探讨黑盒测试:等价类划分与边界值分析

文章目录 概要黑盒测试等价类划分边界值分析 设计测试用例小结 概要 在软件开发领域&#xff0c;测试是确保产品质量的关键步骤之一。而黑盒测试方法作为其中的一种&#xff0c;通过关注输入与输出之间的关系&#xff0c;而不考虑内部实现的细节&#xff0c;被广泛应用于各种软…

最短木板长度 - 贪心思维

系列文章目录 文章目录 系列文章目录前言一、题目描述二、输入描述三、输出描述四、java代码五、测试用例 前言 本人最近再练习算法&#xff0c;所以会发布自己的解题思路&#xff0c;希望大家多指教 一、题目描述 小明有 n 块木板&#xff0c;第 i ( 1 ≤ i ≤ n ) 块木板长…

3分钟,学会一个 Lambda 小知识之【流API】

之前给大家介绍的 Lambda 小知识还记得吗&#xff1f;今天再来给大家介绍&#xff0c; 流API 的相关知识要点。 流API Stream是Java8中处理集合的关键抽象概念&#xff0c;它可以指定你对集合的&#xff0c;可以执行查找、过滤和映射等数据操作。 Stream 使用一种类似用 SQ…

SSRF(服务器端请求伪造)的学习以及相关例题(上)

目录 一、SSRF的介绍 二、漏洞产生的原因 三、利用SSRF可以实现的效果&#xff08;攻击方式&#xff09; 四、SSRF的利用 五、SSRF中的函数 file_get_content() 、fsockopen() 、curl_exec() 1.file_get_content()&#xff1a; 2.fsockopen(): 3.curl_exec()&#xff1…

Golang面向对象编程(二)

文章目录 封装基本介绍封装的实现工厂函数 继承基本介绍继承的实现字段和方法访问细节多继承 封装 基本介绍 基本介绍 封装&#xff08;Encapsulation&#xff09;是面向对象编程&#xff08;OOP&#xff09;中的一种重要概念&#xff0c;封装通过将数据和相关的方法组合在一起…

进程间的IPC通信机制

一、介绍 进程与进程间的用户空间相互独立&#xff0c;内核空间共享。 1.传统的进程间通信机制 a.无名管道 pipe b.有名管道 fifo c.信号 signal 2.system V中的IPC对象 a.消息队列 message queue b.共享内存 shared memory c.信号灯集 semaphoare 3.可用于跨主机传输…

【C++ 】红黑树

1.1 红黑树的概念 红黑树&#xff0c;是一种二叉搜索树&#xff0c;但在每个结点上增加一个存储位表示结点的颜色&#xff0c;可以是Red或 Black。 通过对任何一条从根到叶子的路径上各个结点着色方式的限制&#xff0c;红黑树确保没有一条路 径会比其他路径长出俩倍&#xff…

Android的NDK开发中Cmake报缺少对应的x86的so文件

需要实现一个串口操作的命令。 供应商提供了2个so文件。 分别是 armeabi-v7a 和 arm64-v8a 添加到对应的cpp下。 在CMakeLists.txt里添加so文件 # 添加预编译的库 add_library(libxxx SHARED IMPORTED)# 设置库的路径 set_target_properties(libxxx PROPERTIES IMPORTED_…

OPT系列极速版远距离光数据传输器|光通讯传感器安装与调试方法

OPT系列极速版远距离光数据传输器|光通讯传感器使用红外激光通信&#xff0c;满足全双工 100M 带宽&#xff0c;通讯距离可达 300 米。能够快速&#xff0c;稳地传送数据&#xff0c;支持主流的工业控制总线&#xff08;Profinet&#xff0c;Ethercat 等&#xff09;&#xff1…