单片机-STM32部分:13-1、编码器
飞书文档https://x509p6c8to.feishu.cn/wiki/BpEywhaX9iqbiLkdqdAcmDnwnab
EC旋转编码器
在产品开发过程中,需要位置闭环的的产品,类似电机类产品来说,编码器至关重要,它不仅可以使我们对带年纪进行精确的速度闭环,位置闭环,还可以通过时间积分,根据运动学关系,获得速度、位置等信息。
本节课,我们使用拨轮滚轮旋转编码器EC11E153440D,带大家了解下编码器如何驱动。
编码器有四根线,A\B是编码输出,S是按钮状态,C是公共端。
那么我们该怎样去使用这个编码器呢,从给出的数据手册上面我们看到一个波形,我们就是通过这个波形去判断编码器是否转动以及编码器转动的方向?
可以从图中可以看出当从CW方向转动的时候,A的波形上升沿比B波形的上升沿快,具体快多少,这里数据手册给出24±3°,当从CCW方向转动的这个时候恰好相反,B的相位上升沿快于A的上升沿。这样可以通过捕获上升沿的顺序来判断编码器的方向。
因此:我们有两种方式来判断编码器转动和方向:
- 1、设置IOA为上升沿触发中断,在中断中检测B的电平状态,来判断旋转方向,这种方式比较简单。
- 2、可以同时捕获A项的上升、下降边沿,然后判断A项第一个边沿中断时候获取B和A项的电平,在第二个边沿触发中断的时候捕获B和A项的电平,根据两次捕获B和A项的值就可以知道旋转的方向。
bool is_ccw_end = false;
bool is_cw_end = false;while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */if(is_ccw_end == true){is_ccw_end = false;printf("正转\n");}if(is_cw_end == true){is_cw_end = false;printf("反转\n");}}void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){if(GPIO_Pin == A1_Pin) //判断中断来自哪一条中断线{//进入中断之后,判断B1 PIN的电平来决定哪个方向if(HAL_GPIO_ReadPin(B1_GPIO_Port, B1_Pin) == 0){//CW方向is_cw_end = true;}else{//CCW方向is_ccw_end = true;} }
}
以CW方向为例,第一次捕获A项的的边缘位上升沿,此时A = 1,B = 0;那么第二次就必须捕获下降沿,A = 0,B = 1。假如A第一次没有在边沿捕获到上升沿的时候,捕获的是下降沿,第二次就一定捕获到上升沿。CCW方向也是如此的,这样我们就判断这四种情况,其他的都不用管,这样可以过滤掉干扰,从而实现更准确的控制。
设置PB0和PB1为编码器的A1、B1端口
PB0设置为外部中断,触发模式为上升、下降沿触发
PB1设置为输入模式
同时开启PB0的中断EXTI0
打开USART1作为日志口,方便调试
//CW方向set_cw_status();is_ccw_start = false;}else{//CCW方向set_ccw_status();is_cw_start = false;}}}
}int fputc(int ch, FILE *f)
{HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1, 0xFFFF);return ch;
}
/* USER CODE END 4 */
参考工程:
参考飞书文档
STM32的定时器有编码器模式(Encoder Mode)
大大的方便我们的开发。使用STM32cubeMX配置工具,使得这个过程变得无比简单。
如果TI1和TI2分别接编码器的A相和B相的话,那么,当编码器正转的时候,如下图计数器会向上计数,反转的时候会向下计数,注意了这个向下计数并不会出现负的值。
例如:
正转(0,1,2,…,65535,0)
反转(0,65535,65534,…,2,1,0)
配置定时器TIM的编码器模式
设置定时器TIM的Combined Channels的选项为Encoder Mode,编码器模式;
设置定时器TIM相关参数:
PSC:0 ; Counter:65535 (设置计数器的值为65535,最大值);
配置编码器模式相关参数:
在参数配置中的Econder Mode中选择Econder Mode TI1 and TI2;
如果编码模式设置为 Encoder Mode TI1 and TI2 则会默认检测AB相的上升沿与下降沿; |
在TI1、TI2的选项中选择Rising Edge上升沿触发计数;
这个参数的意思是在检测到上升沿的时候就触发encoder捕获AB相的值,而并不是这里设置的是上升沿就只检测AB相的上升沿,下降沿还是同样会计数的。
Input Filter:滤波值,起到消抖作用
选择GPIO模式配置,配置定时器两个GPIO引脚模式,全部改成Pull-Up,即上拉模式,主要用于没有外部上拉的编码器读取时,可以确定引脚电平,防止出错;
编写代码
添加定时器3的通道1和通道2的Encoder Mode开启使能函数
/* USER CODE BEGIN 2 */
HAL_TIM_Encoder_Start(&htim3,TIM_CHANNEL_1 | TIM_CHANNEL_2);
/* USER CODE END 2 */
编码器数据的读取使用:
在循环中调用 __HAL_TIM_IS_TIM_COUNTING_DOWN 可以获得当前电机的转向 0为正、1为负;
在循环中调用 __HAL_TIM_GET_COUNTER 获取计数器的计数值,即编码器的脉冲数;
/* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */int Direction = __HAL_TIM_IS_TIM_COUNTING_DOWN(&htim3); //读取编码器转动方向//若需要检测编码器转了多少格,记得要/4,因为转一格是+4;int CaptureNumber = (short)__HAL_TIM_GET_COUNTER(&htim3)/4; //读取编码器数据printf("Direction is %d \r\n",Direction);printf("CaptureNumber is %d \r\n",CaptureNumber);HAL_Delay(500);}/* USER CODE END 3 *///short的表示范围(-32768-32767),也就是说当读出来的值为(32767, 32768, 32769,…,65535,65536,65537…)的时候会因为溢出而转换为(32767,-32768,-32767,…, -1, ,0, , 1)就这样不断地循环下去。所以我们的电机反转的时候读出的数就是反方向的速度值。
相关文章:

单片机-STM32部分:13-1、编码器
飞书文档https://x509p6c8to.feishu.cn/wiki/BpEywhaX9iqbiLkdqdAcmDnwnab EC旋转编码器 在产品开发过程中,需要位置闭环的的产品,类似电机类产品来说,编码器至关重要,它不仅可以使我们对带年纪进行精确的速度闭环,位…...
机器学习第十二讲:特征选择 → 选最重要的考试科目做录取判断
机器学习第十二讲:特征选择 → 选最重要的考试科目做录取判断 资料取自《零基础学机器学习》。 查看总目录:学习大纲 关于DeepSeek本地部署指南可以看下我之前写的文章:DeepSeek R1本地与线上满血版部署:超详细手把手指南 一、学…...

关于我在使用stream().toList()遇到的问题
关于我在使用stream().toList()遇到的问题 问题描述 在测试以上程序的时候抛出了空指针异常 于是我以为是我数据库中存在null字段,但查看后发现并不存在为null的数据 问题排查 起初我以为问题出现在sort排序方法这,事实也确实是,当我把s…...
javascript 编程基础(2)javascript与Node.js
文章目录 一、Node.js 与 JavaScript1、基本概念1.1、JavaScript:动态脚本语言1.2、Node.js:JavaScript 运行时环境 2、核心区别3、执行环境差异3.1、浏览器中的JavaScript3.2、Node.js中的JavaScript 4、共同点5、为什么需要Node.js? 一、No…...
Spring Boot 集成 druid,实现 SQL 监控
文章目录 背景Druid 简介监控统计 StateFilter其它 Filter详细步骤第 1 步:添加依赖第 2 步:添加数据源配置【通用部分】第 3 步:添加监控配置【关键部分】第 3 步:访问 druid 页面参考背景 😂 在 Code Review 过程中发现,经常有开发会忘记给表加索引。这就导致,生产运…...

多卡跑ollama run deepseek-r1
# 设置环境变量并启动模型 export CUDA_VISIBLE_DEVICES0,1,2,3 export OLLAMA_SCHED_SPREAD1 # 启用多卡负载均衡 ollama run deepseek-r1:32b 若 deepseek-r1:32b 的显存需求未超过单卡容量(如单卡 24GB),Ollama 不会自动启用多卡 在run…...
HTML向四周扩散背景
<!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>扩散背景效果</title><style>body {…...

基于Java在高德地图面查询检索中使用WGS84坐标的一种方法-以某商场的POI数据检索为例
前言 随着移动互联网的飞速发展,基于位置的服务(LBS)需求日益增长,越来越多的应用需要从地图中检索特定区域内的地理信息,例如商业场所、公共服务设施等。商场作为城市商业活动的重要载体,其周边的地理信息…...
使用 Terraform 创建 Azure Databricks
使用 Terraform 创建 Azure Databricks Terraform 是一种基础设施即代码(IaC)工具,允许用户通过声明式配置文件来管理和部署云资源。Azure Databricks 是一个基于 Apache Spark 的分析平台,专为数据工程和数据科学设计。通过 Terraform,可以自动化 Azure Databricks 的创…...

本地部署dify+ragflow+deepseek ,结合小模型实现故障预测,并结合本地知识库和大模型给出维修建议
1.准备工作 使用ollama 拉取deepseek-r1:7b 官网下载ollama ollama run deepseek-r1:7b ollama list Ragflow专注于构建基于检索增强生成(RAG)的工作流,强调模块化和轻量化,适合处理复杂文档格式和需要高精度检索的场景。Dify…...

SECERN AI提出3D生成方法SVAD!单张图像合成超逼真3D Avatar!
SECERN AI提出的3D生成方法SVAD通过视频扩散生成合成训练数据,利用身份保留和图像恢复模块对其进行增强,并利用这些经过优化的数据来训练3DGS虚拟形象。SVAD在新的姿态和视角下保持身份一致性和精细细节方面优于现有最先进(SOTA)的…...
深入探索:Core Web Vitals 进阶优化与新兴指标
一、INP(Interaction to Next Paint)深度解析 INP 与 FID 的核心差异 • 响应范围:FID仅测量首次输入延迟,而INP跟踪页面生命周期中所有关键交互 • 测量维度:INP综合考虑输入延迟、处理时间和下一帧渲染时间 • 评…...
c/c++的opencv开闭操作
OpenCV 中的形态学开运算与闭运算 (C) 在计算机视觉和图像处理领域,形态学操作是用于分析和处理图像形状的一系列非线性操作。OpenCV 作为一个强大的开源计算机视觉库,提供了丰富的形态学转换函数。其中,“开运算”(Opening&…...

【物联网】 ubantu20.04 搭建L2TP服务器
部署篇 序言 为了是两个客户端在同一个网络内,需要找一台服务器,搭建一个L2TP服务器,通过L2TP使两个客户端在同一个网络内,为什么要搭建,主要是解决例如员工出差后,还需要连接公司内网资源的问题,本文主要…...
winrar 工具测试 下载 与安装
https://zhuanlan.zhihu.com/p/680852417 https://www.angusj.com/resourcehacker/#download 点击String Table,在展开列表中找到80:2052展开,删除1277行。点击右上方编译按钮,并保存。...
PLC组网的方法、要点及实施全解析
一、PLC组网方法 1.1 基于以太网的组网 - 适用场景:适用于数据传输量大、通信距离长、对实时性要求相对不苛刻的场景,如大型工厂的车间级数据交互、跨区域设备协同控制 。 - 实现方式:利用工业以太网交换机,将支持以太网接口的…...
网络安全深度解析:21种常见网站漏洞及防御指南
一、高危漏洞TOP 10 1. SQL注入(SQLi) 原理:通过构造恶意SQL语句突破系统过滤机制 典型场景: - 联合查询注入: union select 1,version(),3--+ - 布尔盲注:and (select substr(user(),1,1)=r) - 时间盲注:;if(now()=sysdate(),sleep(5),0)/ 防御方案: - 严格参数化查…...
【FAQ】HarmonyOS SDK 闭源开放能力 —Vision Kit (3)
1.问题描述: 通过CardRecognition识别身份证拍照拿到的照片地址,使用该方法获取不到图片文件,请问如何解决? 解决方案: //卡证识别实现页,文件名为CardDemoPage,需被引入至入口页 import { …...
Java大厂面试实战:Spring Boot与微服务场景中的技术点解析
Java大厂面试实战:Spring Boot与微服务场景中的技术点解析 第一轮:基础技术了解 面试官:谢飞机,你好。从简历上看,你熟悉Spring Boot,那我们来聊聊它的核心功能吧。Spring Boot有哪些主要的特性ÿ…...

从零启动 Elasticsearch
elastic 有弹力的 ElaticSearch (ES)是一个基于 Lucene 的分布式全文检索引擎。可以做到近乎实时地存储、检索数据,并且本身具有良好的扩展性,可以扩展到上百台服务器,处理PB级别(1 Petabyte 1024TB&…...
比较两个用于手写体识别的卷积神经网络(CNN)模型
要比较两个用于手写体识别的卷积神经网络(CNN)模型,可以从以下 6个核心维度 进行系统性评估,并直接给出对比结论: 一、基础性能对比(核心指标) 准确率 直接比较两个模型在 相同测试集 上的分类准确率(如MNIST测试集的错误率是否低于0.5%)若准确率接近…...
Linux利用多线程和线程同步实现一个简单的聊天服务器
1. 概述 本文实现一个基于TCP/IP的简单多人聊天室程序。它包含一个服务器端和一个客户端:服务器能够接收多个客户端的连接,并将任何一个客户端发来的消息广播给所有其他连接的客户端;客户端则可以连接到服务器,发送消息并接收来自…...
【计网】作业5
待补充 212.56.132.0/24 212.56.1000 0100.0 212.56.133.0/24 212.56.1000 0101.0 212.56.134.0/24 212.56.1000 0110.0 212.56.135.0/24 212.56.1000 0111.0 最小的212.56.1000 0100.0 四个,2^2 212.56.132.0/22 1111 1111.1111 1111.1111 1100.0000 0000 255.255.…...
15、Python布尔逻辑全解析:运算符优先级、短路特性与实战避坑指南
适合人群:零基础自学者 | 编程小白快速入门 阅读时长:约6分钟 文章目录 一、问题:Python布尔值的底层原理?1、例子1:电路开关模型解析布尔本质2、例子2:特殊的布尔类型值为False3、答案:(1&…...

Nginx基础知识
Nginx是什么? Nginx 是一款高性能的 Web 服务器、反向代理服务器和负载均衡器,以其高并发处理能力和低内存消耗著称。以下是 Nginx 的基础知识和常见配置示例: 1. 核心概念 • 配置文件位置:通常为 /etc/nginx/nginx.conf 或 /us…...

Vue-监听属性
监听属性 简单监听 点击切换名字,来回变更Tom/Jerry,输出 你好,Tom/Jerry 代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><title>监听属性</title><!-- …...

python fastapi + react, 写一个图片 app
1. 起因, 目的: 上厕所的时候,想用手机查看电脑上的图片,但是又不想点击下载。此app 应运而生。 2. 先看效果 单击图片,能放大图片 3. 过程: 过程很枯燥。有时候, 有一堆新的想法。 但是做起来太麻烦,…...
nginx集成防火墙ngx_waf的docker版
由于公网的环境越来与严峻,所以想找一个nginx带防火墙的版本 调研过openresty,大部分集成redis了,感觉还是太重了,有一个不那么重的https://github.com/unixhot/waf 但是维护没有那么勤,最后维护是5年前,倒…...

vscode c++编译onnxruntime cuda 出现的问题
问题描述 将onnx的dll文件和lib文件copy到可执行文件所在文件夹下后,现象: 双击可执行文件能正常运行 在vscode中点击cmake插件的运行按钮出现报错为 c [ONNXRuntimeError] : 1 : FAIL : LoadLibrary failed with error 126 “” when trying to load尝试…...
sts下载安装
windows下STS(Spring Tools Suite,自带spring插件的eclipse)的下载与安装_sts下载-CSDN博客Spring Boot安装与配置教程_spring boot安装配置-CSDN博客...