STM32CubeMX学习——旋转编码器模块

2023-11-04

前言

雨打灯难灭,风吹色更明。
若飞天上去,定作月边星。——李白《咏萤火》


一、旋转编码器介绍

旋转编码器是一种可以左右旋转,同时也可以按下,也可以按下旋转的器件,通过左右旋转对应着内部不同开关的导通,同时按下也可以旋转,由此看来旋转编码器可以实现很复杂的功能,简单的通过左右旋转可以调节音量、亮暗等功能,按键可以发挥普通按键的作用,按下按键的同时左右旋转又可以区别普通旋转的按键,因此可以用一个旋转编码器同时调节音量和亮暗(举例),同时也可以通过不同的转速实现不同的功能,综上所述,它的功能很复杂,用处也很多。

旋转编码器是用来测量转速并配合 PWM 技术可以实现快速调速的装置,光电式旋转编码器通过光电转换,可将输出轴的角位移、角速度等机械量转换成相应的电脉冲以数字量输出(REP)

  • 按信号的输出类型分为: 电压输出、集电极开路输出、推拉互补输出和长线驱动输出。
  • 形式分类:
    有轴型:有轴型又可分为夹紧法兰型、同步法兰型和伺服安装型等。
    轴套型:轴套型又可分为半空型、全空型和大口径型等。
    以编码器工作原理可分为: 光电式、磁电式和触点电刷式。
    按码盘的刻孔方式不同分类编码器可分为增量式和绝对式两类。

旋转编码器的原理和特点

  • 原理:

    • 旋转编码器是集光机电技术于一体的速度位移传感器。当旋转编码器轴带动光栅盘旋转时,经发光元件发出的光被光栅盘狭缝切割成断续光线,并被接收元件接收产生初始信号。该信号经后继电路处理后,输出脉冲或代码信号。
    • 旋转编码器是由一个中心有轴的光电码盘组成,其上有环形通、暗的刻线,有光电发射和接收器件读取,获得四组正弦波信号组合成A、B、C、D,每个正弦波相差90度相位差,将C、D信号反向,叠加在A、B两相上,可以增强稳定信号;另每转输出一个Z相脉冲以代表零位参考位。因为A、B两相相差90度,可以通过比较A相在前还是B相在前,借此来判别编码器的正转与反转,通过零位脉冲,可获得编码器的零位参考位。
  • 特点:

    体积小、重量轻、品种多、功能全、频响高、分辨能力高,力矩小,耗能低,性能稳定,可靠使用寿命长等特点。

1、增量式编码器

增量式编码器是将位移转换成周期性的电信号,再把这个电信号转变成计数脉冲,用脉冲的个数表示位移的大小。增量式编码器也称为正交编码器,是通过两个信号线的脉冲输出来进行数据处理,一个输出脉冲就对应于一个增量位移,编码器每转动一定的位移,就会产生一个脉冲信号。通过读取单位时间脉冲信号的数量,达到测量速度的效果(v = s / t),通过对脉冲信号的累加,和编码器的码盘周长 (转一圈对应的距离) 便可以达到计算距离的效果(s = n * d)

  • 工作原理:

    增量式旋转编码器通过两个光敏接收管来转化角度码盘的时序和相位关系,得到角度码盘角度位移量的增加(正方向)或减少(负方向)。
    增量式编码器工作原理图解
  • 上图A、B两点间的距离为S2,A、B表示两个相同的光敏接收管,下面的角度码盘的光栅间距分别为S0(凹槽)和S1(凸起)。
  • 当角度码盘匀速转动时,可知输出波形图中的S0:S1:S2比值与实际图的S0:S1:S2比值相同,同理,当角度码盘变速转动时,输出波形图中的S0:S1:S2比值与实际图的S0:S1:S2比值仍相同。
  • 通过输出波形图可知每个运动周期:
顺时针运动 逆时针运动
A B A B
1 1 1 1
0 1 1 0
0 0 0 0
1 0 0 1
  • 我们把当前的A、B输出值保存起来,与下一个到来的A、B输出值做比较,就可以得出角度码盘转动的方向;

  • 如果光栅格S0等于S1时,也就是S0和S1弧度夹角相同,且S2等于S0的1/2,那么可得到此次角度码盘运动位移角度为S0弧度夹角的1/2,再除以所用的时间,就得到此次角度码盘运动位移的角速度。

  • S0等于S1时,且S2等于S0的1/2时,1/4个运动周期就可以得到运动方向位和位移角度,如果S0不等于S1,S2不等于S0的1/2,那么要1个运动周期才可以得到运动方向位和位移角度了。

    (我们用的鼠标的滚轮也是这个原理。)

  • 实际使用的增量式编码器输出三组方波脉冲A、B和Z(有的叫C相)相。A、B两组脉冲相位差90º,可以判断出旋转方向和旋转速度。而Z相脉冲又叫做零位脉冲(有时也叫索引脉冲),为每转一周输出一个脉冲,Z相脉冲代表零位参考位,通过零位脉冲,可获得编码器的零位参考位,专门用于基准点定位,如下图所示:
    在这里插入图片描述
    在这里插入图片描述

  • 增量是编码器转轴旋转时,有相应的脉冲输出,其计数起点可以任意设定,可实现多圈无限累加和测量。编码器轴转动一圈会输出固定的脉冲数,脉冲数由编码器码盘上面的光栅的线数所决定,编码器以每旋转360度提供多少通或暗的刻线称为分辨率,也称解析分度、或称作多少线,一般在每转5~10000线,当需要提高分辩率时,可利用90度相位差的A、B两路信号进行倍频或者更换高分辩率编码器。

  • 增量型编码器精度取决于机械和电气的因素,这些因素有:光栅分度误差、光盘偏心、轴承偏心、电子读数装置引入的误差以及光学部分的不精确性,误差存在于任何编码器中。

  • 编码器的信号输出有正弦波(电流或电压)、方波(TTL、HTL)等多种形式。并且都可以用差分驱动方式,含有对称的A+/A-、B+/B-、Z+/Z-三相信号,由于带有对称负信号的连接,电流对于电缆贡献的电磁场为0,信号稳定衰减最小,抗干扰最佳,可传输较远的距离,例如:对于TTL的带有对称负信号输出的编码器,信号传输距离可达150米。对于HTL的带有对称负信号输出的编码器,信号传输距离可达300米。

  • 增量式编码器轴旋转时,有相应的相位输出。其旋转方向的判别和脉冲数量的增减,需借助后部的判向电路和计数器来实现。其计数起点可任意设定,并可实现多圈的无限累加和测量。还可以把每转发出一个脉冲的Z信号,作为参考机械零位。当脉冲已固定,而需要提高分辨率时,可利用带90度相位差A,B的两路信号,对原脉冲数进行倍频。
    在这里插入图片描述

  • 编码器时序:

在这里插入图片描述

  • 实物图:

我使用的是下面这种比较简单的五脚旋转编码器:
在这里插入图片描述


二、引脚配置

我使用的旋转编码器有五个引脚,可能还会有其他不同类型的会有不同的引脚,
这五个引脚分别为GND, VCC(+), SW, DT, CLK,具体的引脚已经在简介的图中标明了。

  • VCC:接电源正极 3.3~5V
  • GND:接地;
  • SW(Switch:开关)PA7(TIM3_CH2)
  • DT(DT:数据)PA6(TIM3_CH1)
  • CLK(CLK:时钟)PA5(任选一个引脚:配置为上拉输入模式)

接线表:

旋转编码器的接口 STM32的IO口 设置的工作模式
VCC VCC(3.3V) -
GND GND -
SW(Switch:开关) PA7 定时器编码模式
DT(DT:数据) PA6 定时器编码模式
CLK(CLK:时钟) PA5 GPIO_Mode_IPU(上拉输入模式)
- PA9 TX(USART1 串口1通信)
- PA10 RX(USART1 串口1通信)

三、新建工程

1.打开STM32CubeMX软件,点击“新建工程”

在这里插入图片描述

2. 选择 MCU 和封装

在这里插入图片描述

3.配置时钟

在这里插入图片描述
在这里插入图片描述
具体学习可以参考:博客网站-RCC学习

4.配置调试模式

5.串口(USART1)配置

在这里插入图片描述

6.定时器(TIM)配置
  • 配置为编码器模式:
    在这里插入图片描述
7.生成代码

输入项目名称和路径。(注:路径中不允许出现中文。)
在这里插入图片描述
选择应用的IDE,开发环境MDK-ARM V5
在这里插入图片描述
每个外设生成独立的 ’.c/.h’ 文件

  • 不勾: 所有初始化代码都生成在 main.c
  • 勾选: 初始化代码生成在对应的外设文件。 如 GPIO 初始化代码生成在 gpio.c 中。

    点击 GENERATE CODE 生成代码
8.构建工程

DeBug的模式根据不同的芯片进行选择:
在这里插入图片描述


四、编写代码

main.c文件中,添加一下代码:

  • 重写fgetfput函数:勾选微库(这个很重要),添加头文件<stdio.h>
    在这里插入图片描述
/* USER CODE BEGIN Includes */
#include<stdio.h>
/* USER CODE END Includes */
/**
  * 函数功能: 重定向c库函数printf到DEBUG_USARTx
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明:无
  */
int fputc(int ch, FILE *f)
{
  HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
  return ch;
}
 
/**
  * 函数功能: 重定向c库函数getchar,scanf到DEBUG_USARTx
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明:无
  */
int fgetc(FILE *f)
{
  uint8_t ch = 0;
  HAL_UART_Receive(&huart1, &ch, 1, 0xffff);
  return ch;
}

  • 添加代码encoder文件对(.c/.h):
    • 首先要新建文件,然后在添加到工程中去;
      在这里插入图片描述
      在这里插入图片描述
  • 将新建的文件添加到工程中去;

在这里插入图片描述

  • 返回上一级,寻找自己新建的文件:
    在这里插入图片描述
    在这里插入图片描述
    - 此时,完成了添加encoder.c文件:encoder.c中添加如下代码,即可将encoder.h添加进工程
#include "encoder.h"
  • encoder.c中添加代码:
#include "encoder.h"

uint8_t lock;    //旋钮锁死标志(1表示锁死)
uint16_t count; //计数标志

uint8_t ENCODER_READ(void)
{
  uint8_t key = 0;       //存放按键的值
  uint8_t level;         //记录按钮另一端的电平值
  
  if(HAL_GPIO_ReadPin(encoder_port_A, encoder_right) && HAL_GPIO_ReadPin(encoder_port_A, encoder_left)) //读取此时
  {
    lock = 0;  //判断旋钮是否锁死
  }
  if(!HAL_GPIO_ReadPin(encoder_port_A, encoder_right) && lock == 0) //判断是否旋转按钮,同时判断是否有按钮锁死
  {
    HAL_Delay(100);
    
    level = HAL_GPIO_ReadPin(encoder_port_A,encoder_left);       //把旋钮另一端电平状态记录
    
    HAL_Delay(13);  //延时
    
    if(!HAL_GPIO_ReadPin(encoder_port_A, encoder_right))     //去抖
    {
      if(level == 0)
      {
        key = 1;  //右转
      }
      else
      {
        key = 2;  //左转
      }
      count = 0; //初始锁死判断计数器
      while(!HAL_GPIO_ReadPin(encoder_port_A, encoder_right) && count < 60000)  //等待放开旋钮,同时累加判断锁死
      {
        count++;
        lock = 1;
        HAL_Delay(200);
      }
    }
  }
  
  if(!HAL_GPIO_ReadPin(encoder_port_A,encoder_down) && lock == 0)
  {
    HAL_Delay(20);
    if(!HAL_GPIO_ReadPin(encoder_port_A,encoder_down))    //消抖
    {
      key=3;
    }
  }
  return key;
}
  • encoder.h中添加代码:
#ifndef _ENCODER_H_
#define _ENCODER_H_

#include "main.h"
#include "tim.h"


#define encoder_port_A    GPIOA

#define encoder_left      GPIO_PIN_6	//定义IO接口,DT, 旋钮左转
#define encoder_right     GPIO_PIN_5	//定义IO接口,CLK,旋钮右转
#define encoder_down      GPIO_PIN_7	//定义IO接口,SW, 旋钮按下

uint8_t ENCODER_READ(void);     //接口读取值

#endif

  • 在主函数main.c中添加代码:
/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */
  int b;
  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_TIM3_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */

  printf("encoder is ready:\r\n");
  
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
    b = ENCODER_READ(); //读出旋转器编码器值
    
    HAL_Delay(1000);  
    
    if(b==1)
    {
      printf("编码器右转\r\n");
    }
    if(b==2)
    {
      printf("编码器左转\r\n");
    }
    if(b==3)
    {
      printf("编码器按下\r\n");
    }

  }
  /* USER CODE END 3 */
}


五、实验结果

在这里插入图片描述

谢谢阅读!!!

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM32CubeMX学习——旋转编码器模块 的相关文章

  • 【STM32】【HAL库】遥控关灯2 分机

    相关连接 STM32 HAL库 遥控关灯0 概述 STM32 HAL库 遥控关灯1主机 STM32 HAL库 遥控关灯2 分机 STM32 HAL库 遥控关灯3 遥控器 需求 接收RF433和红外信号 根据信号内容控制舵机 硬件设计 主控采
  • 什么是DevOps的三步工作法?

    作者介绍 张乐 DevOps时代联合创始人 高效运维社区合伙人 DevOpsDays大会 GOPS全球运维大会金牌讲师 国内首批DevOps Master 前百度资深敏捷教练 架构师 超过十四年敏捷转型 工程效能提升和大型项目管理实践经验
  • 电源篇 -- 降压电路(DCDC,非隔离)

    感谢阅读本文 在接下来很长的一段时间里 我将陆续分享项目实战经验 从电源 单片机 晶体管 驱动电路 显示电路 有线通讯 无线通信 传感器 原理图设计 PCB设计 软件设计 上位机等 给新手综合学习的平台 给老司机交流的平台 所有文章来源于项

随机推荐

  • 通过python实现局域网内传输大文件

    通过微信 网盘等进行传输速度很慢而且浪费流量 身旁又没有U盘等便携存储设备 那有没有一个方便的而且不用编程的局域网内传输的方式 那肯定有 step1 打开cmd cd进入需要分享的文件夹下 或者打开文件夹下 在当前路径下 打开cmd ste
  • Linux系统安装mysql

    1 卸载残留 如果服务器之前安装过mysql请先卸载 我这里是用yum安装的 现在通过yum去卸载 yum remove y mysql find name mysql 找到所有残留的文件 再通过rm rf去删除 2 卸载完成后 使用以下命
  • 乘积尾零

    如下的10行数据 每行有10个整数 请你求出它们的乘积的末尾有多少个零 5650 4542 3554 473 946 4114 3871 9073 90 4329 2758 7949 6113 5659 5245 7432 3051 443
  • R语言第七讲 线性回归分析案例

    题目 MASS 库中包含 Boston 波士顿房价 数据集 它记录了波士顿周围 506 个街区的 medv 房价中位数 我们将设法用 13 个预测变量如 rm 每栋住宅的平均房间数 age 平均房 龄 lstat 社会经济地位低的家庭所占比
  • 017-爬虫-爬虫结果存入 sqlserver

    先上图 结果 一 利用这个模块连接sql server import pymssql 引入pymssql模块 安装方式 conda install pymssql 二 连接失败的可能原因 参考此博客 需要开启几个服务 https blog
  • win10中anaconda安装tensorflow时报错Traceback (most recent call last): File “E:\Anaconda3\lib\site-packag

    windows系统anaconda安装tensorflow时报错解决办法 报错 Traceback most recent call last File E Anaconda3 lib site packages pip vendor ur
  • 数组的复制(Java技巧篇,四种方法详解)

    使用java lang System类中的arraycopy方法 优点 该方法可复制全部内容 也可复制一部分成为子数组 且目标数组与源数组没有关系 目标数组可以比源数组大 比较灵活 缺点 返回值为void 所以需要手动创建目标数组 参数含义
  • OA项目之我的审批(查询&会议签字&审批)

    目录 会议查询 会议签字 会议审批 讲解思路 我的审批查询功能 手写签批插件及工具类介绍 手写签批插件集成 手写签批功能实现 会议查询 MeetingInfoDao java 我的审批 public List
  • 毕业设计-基于机器学习的二维码和条形码识别

    目录 前言 课题背景和意义 实现技术思路 实现效果图样例 前言 大四是整个大学期间最忙碌的时光 一边要忙着备考或实习为毕业后面临的就业升学做准备 一边要为毕业设计耗费大量精力 近几年各个学校要求的毕设项目越来越难 有不少课题是研究生级别难度
  • STM32F10xNVIC探究与学习_2021-04-24

    NVIC探究与学习 嵌套向量中断控制器 NVIC NVIC 驱动有多种用途 例如使能或者失能 IRQ 中断 使能或者失能单独的 IRQ 通道 改变 IRQ 通道的优 先级等等 NVIC Enable 中断设置使能寄存器 Disable 中断
  • SQL Server 数据加密功能解析

    数据加密是数据库被破解 物理介质被盗 备份被窃取的最后一道防线 数据加密 一方面解决数据被窃取安全问题 另一方面有关法律要求强制加密数据 SQL Server的数据加密相较于其他数据库 功能相对完善 加密方法较多 通常来讲 数据加密分为对称
  • Redis的面试题

    1 为什么使用Redis做缓存 redis具有高性能和高并发的特点 redis为什么具有高性能 或者说redis为什么快 1 首先redis的数据存在内存中 所以比存储磁盘上的数据库快 2 其次redis本身使用了高效的数据结构 redis
  • win11WiFi驱动如何下载 windows11WiFi驱动下载的步骤方法

    Win11wifi驱动如何下载 现在很多用户都安装了最新的Win11系统 但是在使用的时候发现电脑原有的无线网卡驱动不匹配 需要安装win11wifi驱动 不知道win11wifi驱动下载安装方式 下面小编就教下大家win11无线网卡驱动下
  • Java中Callable接口(多线程实现的第三种办法)

    实现多线程程序的步骤 1 自定义类实现Callable接口 重写接口中的run方法 V call throws Exception 其余两种方法run 没有返回值 2 创建线程池对象 Executors 里面的那个方法 返回的是Execut
  • m1 使用anaconda安装tensorflow

    anaconda已经支持m芯片了 所以直接在官网下载 创建conda环境 conda create n tensorflow learn python 3 8 conda activate tensorflow learn 按照tensor
  • 十大新兴前端框架大盘点

    十大新兴前端框架大盘点 2019年在整体上 前端的主流框架没有太大的变化 业务代码仍由三大框架 React Vue Angular 所主宰着 打包工具一般仍使用webpack Rollup js 状态管理器还是Redux MobX 但随着这
  • 腾讯云视频上传问题总结

    使用腾讯云提供java sdk4 4 MultipartUploadVodFile使用此接口 分片上传 分片大小设置1024 1024 20会被腾讯服务器拒绝 无法上传 目前设置为1024 1024 5 最小分片设置为1024 512 域名
  • adaboost原理(包含权重详细解释)

    1 1 Adaboost是什么 AdaBoost 是英文 Adaptive Boosting 自适应增强 的缩写 由Yoav Freund和Robert Schapire在1995年提出 它的自适应在于 前一个基本分类器分错的样本会得到加强
  • 为什么说区块链的性能严重不足?

    现如今 性能过低是当前区块链技术面临的主要挑战之一 区块链的性能指标主要包括交易吞吐量和延时 交易吞吐量表示在固定时间能处理的交易数 延时表示对交易的响应和处理时间 在实际应用中 需要综合两个要素进行考察 只使用交易吞吐量而不考虑延时是不正
  • STM32CubeMX学习——旋转编码器模块

    前言 雨打灯难灭 风吹色更明 若飞天上去 定作月边星 李白 咏萤火 一 旋转编码器介绍 旋转编码器是一种可以左右旋转 同时也可以按下 也可以按下旋转的器件 通过左右旋转对应着内部不同开关的导通 同时按下也可以旋转 由此看来旋转编码器可以实现