当前位置: 首页 > news >正文

【STM32】TIM定时器编码器

1 编码器接口简介

Encoder Interface 编码器接口

编码器接口可接收增量(正交)编码器的信号,根据编码器旋转产生的正交信号脉冲,自动控制CNT自增或自减,从而指示编码器的位置、旋转方向和旋转速度

接收正交信号,自动执行CNT自增或者自减,编码器接口相当于带有方向控制的外部时钟,同时控制着CNT的计数时钟和计数方向。每隔一段时间去取一次CNT的值,再把CNT清零,每次取出来的值就表示编码器的速度。(测频法)

每个高级定时器和通用定时器都拥有1个编码器接口

两个输入引脚借用了输入捕获的通道1和通道2(CH1和CH2)

1.1 正交编码器

正交编码器一般可以测量位置或者带有方向的速度值

旋转编码器:用来测量位置、速度或旋转方向的装置,当其旋转轴旋转时,其输出端可以输出与旋转速度和方向对应的方波信号,读取方波信号的频率和相位信息即可得知旋转轴的速度和方向

类型:机械触点式/霍尔传感器式/光栅式

 

方波频率代表速度。正转时A相提前B相90°;反转时A相滞后B相90°

首先把A\相和B相的所有边沿作为计数器的计数时钟,出现边沿信号时就计数器自增或者自减;计数的方向由另一相的状态来确定。当出现某个边沿时,判断另一相高低电平,如果另一相的状态出现在上面这个表中,那就是正转,计数自增;否则就是反转,计数自减。这样就可以实现编码器接口的功能了。

编码器接口有两个输入端,分别接到编码器的A相和B相,所以编码器的输入引脚就是定时器的CH1和CH2引脚。编码器的输出部分相当于从模式的控制器了,控制CNT的计数时钟和计数方向。计数器的自增和自减受编码器控制。

1.2 编码器接口基本结构

很清晰

1.3 工作模式

这里TI1FP1和TI2FP2接的就是AB相。计数和前面一样。

正转向上计数,反转向下计数。

1.4 实例图

均不反向,使用TI1和TI2都计数

很清晰。

TI1反向,TI2不反向。极性的变化对计数的影响。

这里的极性选择就是高低电平的极性选择了。如果选择上升沿的参数,就是信号直通过来,高低电平极性不反转;如果选择下降沿的参数,就是信号通过非门,高低电平反转。

很清晰。

手册

2  编码器接口测速

2.1 接线图

引脚定义

计划用TIM3的通道1和通道2

2.2 模块封装

按这个配置

库函数

// 定时器编码器接口配置
void TIM_EncoderInterfaceConfig(TIM_TypeDef* TIMx, uint16_t TIM_EncoderMode,uint16_t TIM_IC1Polarity, uint16_t TIM_IC2Polarity);

版本一:Encoder.c

#include "stm32f10x.h"                  // Device header// 编码器接口初始化函数
void EnCoder_Init(void)
{// 1开启时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);// 2配置GPIOGPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;         		// 上拉输入模式GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStruct);// 3配置时基单元TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;TIM_TimeBaseInitStruct.TIM_Prescaler = 1 - 1;                    	// PSC预分频器的值,不分频TIM_TimeBaseInitStruct.TIM_Period = 65536 - 1;                     	// ARR自动重装器的值 TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;      	// 向上计数,没有用TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;			// 不分频TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0;                	// 重复计数器的值TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStruct);// 4配置输入捕获单元(只有极性和滤波器两个参数有用)TIM_ICInitTypeDef TIM_ICInitStruct;TIM_ICStructInit(&TIM_ICInitStruct);                               // 结构体初始化TIM_ICInitStruct.TIM_Channel = TIM_Channel_1;					   // 通道1TIM_ICInitStruct.TIM_ICFilter = 0xF;							   // 滤波器
//	TIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_Rising;		   // 和后面重复
//	TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_DirectTI;       // 无作用
//	TIM_ICInitStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1;                 // 无作用TIM_ICInit(TIM3, &TIM_ICInitStruct);TIM_ICInitStruct.TIM_Channel = TIM_Channel_2;TIM_ICInitStruct.TIM_ICFilter = 0xF;//	TIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_Rising;	   // 和后面重复TIM_ICInit(TIM3, &TIM_ICInitStruct);// 5配置编码器接口模式// TIM_ICPolarity_Rising这个通道不反向,TIM_ICPolarity_Falling这个通道反向// 后两个参数相反就是方向相反TIM_EncoderInterfaceConfig(TIM3, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);// 6启动定时器TIM_Cmd(TIM3, ENABLE);
}// 获取CNT的值
int16_t Encoder_Get(void)
{return TIM_GetCounter(TIM3);
}

版本二:Encoder.c

#include "stm32f10x.h"                  // Device header// 编码器接口初始化函数
void EnCoder_Init(void)
{// 1开启时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);// 2配置GPIOGPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;         		// 上拉输入模式GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStruct);// 3配置时基单元TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;TIM_TimeBaseInitStruct.TIM_Prescaler = 1 - 1;                    	// PSC预分频器的值,不分频TIM_TimeBaseInitStruct.TIM_Period = 65536 - 1;                     	// ARR自动重装器的值 TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;      	// 向上计数,没有用TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;			// 不分频TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0;                	// 重复计数器的值TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStruct);// 4配置输入捕获单元(只有极性和滤波器两个参数有用)TIM_ICInitTypeDef TIM_ICInitStruct;TIM_ICStructInit(&TIM_ICInitStruct);                               // 结构体初始化TIM_ICInitStruct.TIM_Channel = TIM_Channel_1;					   // 通道1TIM_ICInitStruct.TIM_ICFilter = 0xF;							   // 滤波器
//	TIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_Rising;		   // 和后面重复
//	TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_DirectTI;       // 无作用
//	TIM_ICInitStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1;                 // 无作用TIM_ICInit(TIM3, &TIM_ICInitStruct);TIM_ICInitStruct.TIM_Channel = TIM_Channel_2;TIM_ICInitStruct.TIM_ICFilter = 0xF;//	TIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_Rising;	   // 和后面重复TIM_ICInit(TIM3, &TIM_ICInitStruct);// 5配置编码器接口模式// TIM_ICPolarity_Rising这个通道不反向,TIM_ICPolarity_Falling这个通道反向// 后两个参数相反就是方向相反TIM_EncoderInterfaceConfig(TIM3, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);// 6启动定时器TIM_Cmd(TIM3, ENABLE);
}// 获取CNT的值
int16_t Encoder_Get(void)
{
//    return TIM_GetCounter(TIM3);// 读取cnt,把cnt清零的逻辑int16_t temp = TIM_GetCounter(TIM3);TIM_SetCounter(TIM3, 0);return temp;
}

2.3 主函数

版本一:主函数

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "Timer.h"
#include "EnCoder.h"int main()
{OLED_Init();								// 初始化OLEDEnCoder_Init();
//	Timer_Init();								// 初始化定时器OLED_ShowString(1, 1, "CNT:");   			// 显示字符串while (1){OLED_ShowNum(1, 5, Encoder_Get(), 5);    // 显示CNT计数器}
}

版本二:主函数

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "Timer.h"
#include "EnCoder.h"int16_t speed;int main()
{OLED_Init();								// 初始化OLEDEnCoder_Init();Timer_Init();								// 初始化定时器OLED_ShowString(1, 1, "speed:");   			// 显示字符串while (1){OLED_ShowSignedNum(1, 7, speed, 5);    		 // 显示CNT计数器}
}// 中断函数
void TIM2_IRQHandler(void)
{// 检测中断标志位,确保是设置的中断源触发的这个函数if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET){// 中断处理speed = Encoder_Get();// 清除中断标志TIM_ClearITPendingBit(TIM2, TIM_IT_Update);}
}

相关文章:

【STM32】TIM定时器编码器

1 编码器接口简介 Encoder Interface 编码器接口 编码器接口可接收增量(正交)编码器的信号,根据编码器旋转产生的正交信号脉冲,自动控制CNT自增或自减,从而指示编码器的位置、旋转方向和旋转速度 接收正交信号&#…...

力扣44题通配符匹配题解

44. 通配符匹配 - 力扣(LeetCode) 给你一个输入字符串 (s) 和一个字符模式 (p) ,请你实现一个支持 ? 和 * 匹配规则的通配符匹配: ? 可以匹配任何单个字符。* 可以匹配任意字符序列(包括空字符序列)。 …...

windows系统安装RocketMQ_dashboard

1.下载源码 按照官网说明下载源码 官网 官网文档 2.源码安装 2.1.① 编译rocketmq-dashboard 注释掉报错的maven插件frontend-maven-plugin、maven-antrun-plugin mvn clean package -Dmaven.test.skiptrue2.2.② 运行rocketmq-dashboard java -jar target/rocketmq-…...

ATECLOUD电源自动测试系统打破传统 助力新能源汽车电源测试

随着新能源汽车市场的逐步扩大,技术不断完善提升,新能源汽车测试变得越来越复杂,测试要求也越来越严格。作为新能源汽车的关键部件之一,电源为各个器件和整个电路提供稳定的电源,满足需求,确保新能源汽车的…...

如何教会小白使用淘宝API接口获取商品数据

随着互联网的普及,越来越多的人开始接触网络购物,而淘宝作为中国最大的电商平台之一,成为了众多消费者首选的购物平台。然而,对于一些小白用户来说,如何通过淘宝API接口获取商品数据可能是一个难题。本文将详细介绍如何…...

Redis有序集合对象

一.编码 有序集合的编码可以是ziplist或者skiplist。 ziplist编码的有序集合对象使用压缩列表作为底层实现,每一个集合元素使用紧挨在一起的两个压缩列表节点来保存。第一个节点保存元素的成员(member),而第二个元素则保存元素的分值(score)。 127.0.0.…...

【C++数据结构 | 字符串速通】10分钟秒杀字符串相关操作 | 字符串的增删改查 | 字符串与数组相互转换

字符串 by.Qin3Yu 文中所有代码默认已使用std命名空间且已导入部分头文件&#xff1a; #include <iostream> #include <string> using namespace std;概念速览 字符串是一种非常好理解的数据类型&#xff0c;它用于存储和操作文本数据。字符串可以包含任意字符…...

运动重定向:C-3PO

C-3PO: Cyclic-Three-Phase Optimization for Human-Robot Motion Retargeting based on Reinforcement Learning解析 摘要1. 简介2. 相关工作2.1 运动重定向&#xff08;Motion Retargeting&#xff09;2.2 强化学习&#xff08;Reinforcement Learning&#xff09; 3. 预备知…...

天池SQL训练营(四)-集合运算-表的加减法和join等

-天池龙珠计划SQL训练营 4.1表的加减法 4.1.1 什么是集合运算 集合在数学领域表示“各种各样的事物的总和”, 在数据库领域表示记录的集合. 具体来说,表、视图和查询的执行结果都是记录的集合, 其中的元素为表或者查询结果中的每一行。 在标准 SQL 中, 分别对检索结果使用 U…...

thinkphp lists todo

来由&#xff1a; 数据库的这个字段我想返回成&#xff1a; 新奇的写法如下&#xff1a; 逻辑层的代码&#xff1a; public function goodsDetail($goodId){$detail $this->good->where(id, $goodId)->hidden([type_params,user_id])->find();if (!$detail) {ret…...

【Flutter】创建应用顶级组件,应用根组件 (学习记录)

前言 在 Flutter 中&#xff0c;应用的顶级组件或根组件通常是在 main() 函数中通过 runApp() 方法创建的。这个组件通常是一个 MaterialApp、CupertinoApp、GetMaterialApp 或其他类似的应用框架组件。 以下是一个创建 MaterialApp 作为根组件的示例&#xff1a; void main()…...

AI材料专题报告:AI革命催生新需求国产替代推动新方向

今天分享的AI系列深度研究报告&#xff1a;《AI材料专题报告&#xff1a;AI革命催生新需求国产替代推动新方向》。 &#xff08;报告出品方&#xff1a;光大证券&#xff09; 报告共计&#xff1a;25页 1、算力需求增长催生 800G 光模块需求 算力是数字经济时代新生产力&…...

JVM 分析GC日志

GC日志参数 -verbose:gc 输出gc日志信息&#xff0c;默认输出到标准输出 -XX:PrintGC 输出GC日志。类似&#xff1a;-verbose:gc -XX:PrintGCDetails 在发生垃圾回收时打印内存回收详细的日志&#xff0c;并在进程退出时输出当前内存各区域分配情况 -XX:PrintGCTimeStam…...

阿里云服务器环境配置,ssh免密登录和配置docker

此文章适合ubuntu20.04 64位和ubuntu22.04 64位版本 一.登陆服务器 租完服务器后&#xff0c;首选需要使用本地gitbash或者cmd进入服务器&#xff0c; 命令&#xff1a; ssh rootxxx xxx为服务器公网ip&#xff0c;然后yes&#xff0c;然后输入密码就会进入自己的服务器&am…...

【LeetCode】2621. 睡眠函数

睡眠函数 Promise异步 题目题解 题目 请你编写一个异步函数&#xff0c;它接收一个正整数参数 millis &#xff0c;并休眠 millis 毫秒。要求此函数可以解析任何值。 示例 1&#xff1a; 输入&#xff1a;millis 100 输出&#xff1a;100 解释&#xff1a; 在 100ms 后此异步…...

网络入门---TCP通信实现

目录标题 前言准备工作 tcpserver.hpp构造函数初始化函数(listen)运行函数(accept) tcpserver.cctcpclient.hpp构造函数初始化函数运行函数(connect) tcpclient.cc问题测试改进一&#xff1a;多进程改进二&#xff1a;多线程改进三&#xff1a;线程池完整代码 前言 在前面的文…...

neuq-acm预备队训练week 8 P2661 [NOIP2015 提高组] 信息传递

题目背景 NOIP2015 Day1T2 题目描述 有 n 个同学&#xff08;编号为 1 到n&#xff09;正在玩一个信息传递的游戏。在游戏里每人都有一个固定的信息传递对象&#xff0c;其中&#xff0c;编号为 i 的同学的信息传递对象是编号为 Ti​ 的同学。 游戏开始时&#xff0c;每人都…...

《C++新经典设计模式》之第18章 备忘录模式

《C新经典设计模式》之第18章 备忘录模式 备忘录模式.cpp 备忘录模式.cpp #include <iostream> #include <vector> #include <memory> using namespace std;// 保存对象内部状态&#xff0c;必要时恢复 // 在不破坏封装性的前提下&#xff0c;捕获对象的内部…...

OWASP安全练习靶场juice shop-更新中

Juice Shop是用Node.js&#xff0c;Express和Angular编写的。这是第一个 完全用 JavaScript 编写的应用程序&#xff0c;列在 OWASP VWA 目录中。 该应用程序包含大量不同的黑客挑战 用户应该利用底层的困难 漏洞。黑客攻击进度在记分板上跟踪。 找到这个记分牌实际上是&#…...

当使用RSA加密,从手机前端到服务器后端的请求数据存在+

将转成了空格&#xff0c;导致解密出错 将空格转成了...

React 第五十五节 Router 中 useAsyncError的使用详解

前言 useAsyncError 是 React Router v6.4 引入的一个钩子&#xff0c;用于处理异步操作&#xff08;如数据加载&#xff09;中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误&#xff1a;捕获在 loader 或 action 中发生的异步错误替…...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战

前言 现在我们有个如下的需求&#xff0c;设计一个邮件发奖的小系统&#xff0c; 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式&#xff08;Decorator Pattern&#xff09;允许向一个现有的对象添加新的功能&#xff0c;同时又不改变其…...

React Native 导航系统实战(React Navigation)

导航系统实战&#xff08;React Navigation&#xff09; React Navigation 是 React Native 应用中最常用的导航库之一&#xff0c;它提供了多种导航模式&#xff0c;如堆栈导航&#xff08;Stack Navigator&#xff09;、标签导航&#xff08;Tab Navigator&#xff09;和抽屉…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)

在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...

AI,如何重构理解、匹配与决策?

AI 时代&#xff0c;我们如何理解消费&#xff1f; 作者&#xff5c;王彬 封面&#xff5c;Unplash 人们通过信息理解世界。 曾几何时&#xff0c;PC 与移动互联网重塑了人们的购物路径&#xff1a;信息变得唾手可得&#xff0c;商品决策变得高度依赖内容。 但 AI 时代的来…...

Python 包管理器 uv 介绍

Python 包管理器 uv 全面介绍 uv 是由 Astral&#xff08;热门工具 Ruff 的开发者&#xff09;推出的下一代高性能 Python 包管理器和构建工具&#xff0c;用 Rust 编写。它旨在解决传统工具&#xff08;如 pip、virtualenv、pip-tools&#xff09;的性能瓶颈&#xff0c;同时…...

Golang——6、指针和结构体

指针和结构体 1、指针1.1、指针地址和指针类型1.2、指针取值1.3、new和make 2、结构体2.1、type关键字的使用2.2、结构体的定义和初始化2.3、结构体方法和接收者2.4、给任意类型添加方法2.5、结构体的匿名字段2.6、嵌套结构体2.7、嵌套匿名结构体2.8、结构体的继承 3、结构体与…...

人工智能--安全大模型训练计划:基于Fine-tuning + LLM Agent

安全大模型训练计划&#xff1a;基于Fine-tuning LLM Agent 1. 构建高质量安全数据集 目标&#xff1a;为安全大模型创建高质量、去偏、符合伦理的训练数据集&#xff0c;涵盖安全相关任务&#xff08;如有害内容检测、隐私保护、道德推理等&#xff09;。 1.1 数据收集 描…...

python爬虫——气象数据爬取

一、导入库与全局配置 python 运行 import json import datetime import time import requests from sqlalchemy import create_engine import csv import pandas as pd作用&#xff1a; 引入数据解析、网络请求、时间处理、数据库操作等所需库。requests&#xff1a;发送 …...

[论文阅读]TrustRAG: Enhancing Robustness and Trustworthiness in RAG

TrustRAG: Enhancing Robustness and Trustworthiness in RAG [2501.00879] TrustRAG: Enhancing Robustness and Trustworthiness in Retrieval-Augmented Generation 代码&#xff1a;HuichiZhou/TrustRAG: Code for "TrustRAG: Enhancing Robustness and Trustworthin…...