STM32旋转编码器驱动详解:方向判断、卡死处理与代码分析 | 零基础入门STM32第四十八步

主题内容教学目的/扩展视频
旋转编码器电路原理,跳线设置,结构分析。驱动程序与调用。熟悉电路和驱动程序。

师从洋桃电子,杜洋老师


📑文章目录

    • 一、旋转编码器原理与驱动结构
      • 1.1 旋转编码器工作原理
      • 1.2 驱动程序结构
    • 二、方向判断方法深度解析
      • 2.1 核心判断逻辑
      • 2.2 两种判断方法对比
    • 三、卡死问题解决方案
      • 3.1 卡死检测机制
      • 3.2 卡死恢复流程
    • 四、关键代码解析
      • 4.1 初始化函数
      • 4.2 核心读取函数
    • 五、项目开发注意事项
    • 六、扩展应用方向
    • 七、相关资源


▲ 回顾上期🔍旋转编码器原理与应用详解:从结构到实战 | 零基础入门STM32第四十七步


(图1:开发板与旋转编码器连接示意图)
(图2:旋转编码器结构示意图)

一、旋转编码器原理与驱动结构

1.1 旋转编码器工作原理

旋转编码器通过两个正交脉冲信号(K2/K3)判断方向。旋转时两个引脚依次产生低电平,相位差90度:

  • 右旋:K2先低电平 → K3后低电平
  • 左旋:K3先低电平 → K2后低电平

1.2 驱动程序结构

// 驱动核心函数
void ENCODER_Init(void);  // 初始化GPIO
u8 ENCODER_READ(void);    // 读取旋转值

二、方向判断方法深度解析

2.1 核心判断逻辑

通过检测K2下降沿时K3的电平状态:

if(!K2 && KUP==0) {delay_us(100);kt = K3_State; // 记录K3状态if(kt==0) a=1; // 右转else      a=2; // 左转
}

2.2 两种判断方法对比

方法优点缺点
边沿检测法(本文)实现简单依赖旋转速度
状态机法抗干扰强代码复杂度高
(图3:方向判断时序图---边沿检测法)
(图4:方向判断时序图---状态机法)


(时序图:左右旋转时的信号变化)

三、卡死问题解决方案

3.1 卡死检测机制

while(!K2 && cou<60000){cou++; KUP=1; // 设置卡死标志delay_us(20);
}
  • 循环计数器:cou统计等待时间
  • 标志位:KUP=1时禁止新操作

3.2 卡死恢复流程

检测K2低电平
是否卡死?
置位KUP标志
正常处理
等待物理复位
K2高电平清除KUP

四、关键代码解析

4.1 初始化函数

void ENCODER_Init(void){GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; // 上拉输入模式GPIO_Init(ENCODER_PORT_A, &GPIO_InitStructure);
}

配置引脚为上拉输入,增强抗干扰能力

4.2 核心读取函数

u8 ENCODER_READ(void){if(K2下降沿){delay_us(100); // 消抖kt = 读取K3状态;if(kt==0) 右转;else      左转;while(等待旋钮释放){cou++; // 卡死检测if(cou>阈值) KUP=1;}}return 方向值;
}

五、项目开发注意事项

  1. 消抖处理:实测机械抖动约5-10ms,代码中采用100us+3ms双重消抖
  2. 显示冲突:避免在旋转检测中调用耗时显示函数
  3. 中断优化:高精度场景建议改用外部中断检测

六、扩展应用方向

  1. 长按/短按识别
  2. 旋转加速检测
  3. 多级菜单控制
  4. 结合PID实现精密控制

附录:完整代码流程图

按下
Start
初始化GPIO
While
ENCODER_READ
检测K2?
消抖处理
读取K3状态
标记右转
标记左转
Right/Left
等待释放
超时?
标记卡死
返回方向值

七、相关资源

[1] 洋桃电子B站课程-STM32入门100步
[2] STM32F103xx官方数据手册
[3] STM32F103X8-B数据手册(中文)
[4] STM32F103固件函数库用户手册(中文)
[5] 旋转编码器数码管显示程序
[6] 旋转编码器介绍(中文)


💬 技术讨论(请在评论区留言~)

📌 下期预告:下一期将探讨I2C总线介绍,欢迎持续关注!

点击查阅🔍往期【STM32专栏】文章

版权声明:本文采用[CC BY-NC-SA 4.0]协议,转载请注明来源
实测开发版:洋桃1号开发版(基于STM32F103C8T6)
更新日志

  • v1.0 初始版本(2025-03-06)

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

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

相关文章

elementplus的cascader级联选择器在懒加载且多选时的一些问题分析

1. 背景 在之前做的一个项目中使用到了element的级联选择器&#xff0c;并且是需要懒加载、多选、父子不关联等等&#xff0c;在选的时候当然没问题&#xff0c;但是回显的时候就会回显不出来&#xff0c;相信大部分伙伴都遇到过这个问题。我在以前出过一篇文章写过关于级联选…

【Python运维】用Python自动化AWS资源管理:利用boto3实现高效管理S3桶和EC2实例

《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! 解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 随着云计算的普及,AWS(Amazon Web Services)已经成为许多企业和开发者首选的云平台。为了提高工作效率,自动化管理AWS资源成为了一个热…

淘宝关键字搜索接口爬虫测试实战指南

在电商数据分析和市场研究中&#xff0c;通过关键字搜索获取淘宝商品信息是一项重要任务。淘宝开放平台提供了 item_search 接口&#xff0c;允许开发者通过关键字搜索商品&#xff0c;并获取商品列表及相关信息。本文将详细介绍如何设计并测试一个基于该接口的爬虫程序&#x…

【Linux实践系列】:用c语言实现一个shell外壳程序

&#x1f525;本文专栏&#xff1a;Linux Linux实践项目 &#x1f338;博主主页&#xff1a;努力努力再努力wz 那么今天我们就要进入Linux的实践环节&#xff0c;那么我们之前学习了进程控制相关的几个知识点&#xff0c;比如进程的终止以及进程的等待和进程的替换&#xff0c;…

⭐算法OJ⭐N-皇后问题 II【回溯剪枝】(C++实现)N-Queens II

⭐算法OJ⭐N-皇后问题【回溯剪枝】&#xff08;C实现&#xff09;N-Queens 问题描述 The n-queens puzzle is the problem of placing n n n queens on an n n n \times n nn chessboard such that no two queens attack each other. Given an integer n, return the num…

03.06 QT

一、使用QSlider设计一个进度条&#xff0c;并让其通过线程自己动起来 程序代码&#xff1a; <1> Widget.h: #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QThread> #include "mythread.h"QT_BEGIN_NAMESPACE namespace Ui {…

Spring WebFlux 中 WebSocket 使用 DataBuffer 的注意事项

以下是修改后的完整文档&#xff0c;包含在多个多线程环境中使用 retain() 和 release() 方法的示例&#xff0c;且确保在 finally 块中调用 release()&#xff1a; 在 Spring WebFlux 中&#xff0c;WebSocketMessage 主要用于表示 WebSocket 的消息载体&#xff0c;其中 getP…

【CSS】Tailwind CSS 与传统 CSS:设计理念与使用场景对比

1. 开发方式 1.1 传统 CSS 手写 CSS&#xff1a;你需要手动编写 CSS 规则&#xff0c;定义类名、ID 或元素选择器&#xff0c;并为每个元素编写样式。 分离式开发&#xff1a;HTML 和 CSS 通常是分离的&#xff0c;HTML 中通过类名或 ID 引用 CSS 文件中的样式。 示例&#…

2025华为OD机试真题E卷 - 螺旋数字矩阵【Java】

题目描述 疫情期间,小明隔离在家,百无聊赖,在纸上写数字玩。他发明了一种写法:给出数字个数 n (0 < n ≤ 999)和行数 m(0 < m ≤ 999),从左上角的 1 开始,按照顺时针螺旋向内写方式,依次写出2,3,…,n,最终形成一个 m 行矩阵。小明对这个矩阵有些要求: 1、…

地下井室可燃气体监测装置:守护地下安全,防患于未“燃”!

在城市的地下&#xff0c;隐藏着无数的燃气管道和井室&#xff0c;它们是城市基础设施建设的重要部分&#xff0c;燃气的使用&#xff0c;给大家的生活提供了极大的便利。在便利生活的背后&#xff0c;也存在潜在的城市安全隐患。 近年来&#xff0c;地下井室可燃气体泄漏事故…

【使用hexo模板创建个人博客网站】

使用hexo模板创建个人博客网站 环境准备node安装hexo安装ssh配置 使用hexo命令搭建个人博客网站hexo命令 部署到github创建仓库修改_config.yml文件 编写博客主题扩展 环境准备 node安装 进入node官网安装node.js 使用node -v检查是否安装成功 安装成功后应该出现如上界面 …

C# OPC DA获取DCS数据(提前配置DCOM)

OPC DA配置操作手册 配置完成后&#xff0c;访问远程ip&#xff0c;就能获取到服务 C#使用Interop.OPCAutomation采集OPC DA数据&#xff0c;支持订阅&#xff08;数据变化&#xff09;、单个读取、单个写入、断线重连

发行思考:全球热销榜的频繁变动

几点杂感&#xff1a; 1、单机游戏销量与在线人数的衰退是剧烈的&#xff0c;有明显的周期性&#xff0c;而在线游戏则稳定很多。 如去年的某明星游戏&#xff0c;最高200多万在线&#xff0c;如今在线人数是48名&#xff0c;3万多。 而近期热门的是MH&#xff0c;在线人数8…

Unity自定义区域UI滑动事件

自定义区域UI滑动事件 介绍制作1.创建一个Image2.创建脚本 总结 介绍 一提到滑动事件联想到有太多的插件了比如EastTouchBundle&#xff0c;今天想单纯通过UI去做一个滑动事件而不是基于Box2d或者Box去做滑动事件。 制作 1.创建一个Image 2.创建脚本 using UnityEngine; us…

taosd 写入与查询场景下压缩解压及加密解密的 CPU 占用分析

在当今大数据时代&#xff0c;时序数据库的应用越来越广泛&#xff0c;尤其是在物联网、工业监控、金融分析等领域。TDengine 作为一款高性能的时序数据库&#xff0c;凭借独特的存储架构和高效的压缩算法&#xff0c;在存储和查询效率上表现出色。然而&#xff0c;随着数据规模…

《UE5_C++多人TPS完整教程》学习笔记34 ——《P35 网络角色(Network Role)》

本文为B站系列教学视频 《UE5_C多人TPS完整教程》 —— 《P35 网络角色&#xff08;Network Role&#xff09;》 的学习笔记&#xff0c;该系列教学视频为计算机工程师、程序员、游戏开发者、作家&#xff08;Engineer, Programmer, Game Developer, Author&#xff09; Stephe…

K8s 1.27.1 实战系列(七)Deployment

一、Deployment介绍 Deployment负责创建和更新应用程序的实例,使Pod拥有多副本,自愈,扩缩容等能力。创建Deployment后,Kubernetes Master 将应用程序实例调度到集群中的各个节点上。如果托管实例的节点关闭或被删除,Deployment控制器会将该实例替换为群集中另一个节点上的…

Linux(Centos 7.6)命令详解:vim

1.命令作用 vi/vim 是Linux 系统内置不可或缺的文本编辑命令&#xff0c;vim 是vi 的加强版本&#xff0c;兼容vi 的所有指令&#xff0c;不仅能编辑文本&#xff0c;而且还具有shell 程序编辑的功能&#xff0c;可以不同颜色的字体来辨别语法的正确性。 2.命令语法 usage: …

微信小程序引入vant-weapp组件教程

本章教程,介绍如何在微信小程序中引入vant-weapp。 vant-weapp文档:https://vant-ui.github.io/vant-weapp/#/button 一、新建一个小程序 二、npm初始化 npm init三、安装 Vant Weapp‘ npm i @vant/weapp -

C++ 作业 DAY5

作业 代码 Widtget.h class Widget : public QWidget {Q_OBJECTpublic:Widget(QWidget *parent nullptr);~Widget();private:Ui::Widget *ui;/************************ 起始终止坐标 ************************/QPoint end;QPoint start;QVector<QPoint> per_start_lis…