【STM32学习】——定时器的编码器接口&正交编码器&编码器接口测速代码实操

2023-10-30


声明:学习笔记根据b站江科大自化协stm32入门教程编辑,仅供学习交流使用!

前言

引入:本实操案例与之前学习外部中断时写的旋转编码器计次的代码实现的功能基本一样,只不过之前的是通过触发外部中断,在中断函数中手动(软件++)进行计次;本代码是通过定时器的旋转编码器接口来自动计次的,使用编码器接口的好处是节约软件资源,避免频繁进中断而只是执行简单的++操作(极大浪费软件资源)。
应用场景:编码器测速一般应用在电机控制的项目上,使用PWM波驱动电机,再使用编码器测量电机速度,然后再用PID算法进行闭环控制!
注意:一般电机旋转速度比较高,会使用无接触式的霍尔传感器或光栅进行测速,本案例为了方便就使用触点式旋扭编码器来演示,电机旋转用手拧来模拟,效果一样!

一、编码器接口

芯片手册14.3.12

1.简介

Encoder Interface 编码器接口
1、编码器接口可接收增量(正交)编码器的信号,根据编码器旋转产生的正交信号脉冲,自动控制CNT自增或自减,从而指示编码器的位置旋转方向旋转速度
2、每个高级定时器和通用定时器都拥有1个编码器接口。
3、编码器接口其实就相当于是一个带有方向控制的外部时钟,同时控制着CNT的计数时钟和计数方向。借用上一节输入捕获中测周法和测频法的知识点,编码器测速实际就是测频法测正交脉冲的频率,只不过编码器计次更高级:能根据旋转方向不仅能自增也可自减,是一个带方向的测速。
在这里插入图片描述
如上图绿框:
1、编码器有两个输入端,分别接到正交编码器的A、B两相引脚,两个输入引脚借用了输入捕获的通道1通道2,即TIFP1与TI2FP2与下面输入捕获通道的TIFP1与TI2FP2是连接在一起的。所以编码器最外面的输入引脚就是图左下的定TIMx_CH1和CH2两个引脚,信号从这两个引脚通过通道1或2到TIFP1与TI2FP2再到编码器接口。CH3与CH4与编码器接口无关。(红线)
2、编码器的输出部分,相当于从模式控制器,去控制CNT的计数时钟和计数方向。输出执行流程为:出现边沿信号时,并且根据下表判断为正转,则控制CNT自增,反之自减。注意之前一直使用的72MHz内部时钟CK_PSC和时基单元初始化时的计数方向+/-并不会使用,因为此时计数时钟和计数方向都处于编码器接口托管的状态,CNT的自增或自减由编码器控制。(绿线)
单一把编码器部分拿出来:
在这里插入图片描述
工作模式:(该表与下面正交编码器部分对应,正转向上计数,反转向下)
在这里插入图片描述
仅在TI1计数表示仅统计A相边沿时B相的状态,精度比在A、B边沿都都统计另一相状态要低。
实例(均不反相):(毛刺部分为抗噪声功能,上下摆动不计次)
所谓反相,即两个边沿检测与极性选择处选择下降沿参数,信号通过一个非门高低电平翻转。
在这里插入图片描述
实例(TI1反相):(极性变化对计数的影响)
TI1反相,即下面的TI1数字波需要高低反转下再对应查表,判断向下还是向上计数。反相功能的作用:比如实际需要的正反转(因为是相对的根据需要)与CNT自增自减不对应,就可反相一下。
在这里插入图片描述

2.正交编码器

正交:A、B两相位相差90°,用两相可以表示出方向(正反转是相对的):
在这里插入图片描述
出现边沿信号时就计数自增或自减,到底是自增还是自减由另一相的状态决定,这样就可以有方向计数。

二、实操案例(编码器接口测速)

在这里插入图片描述

//Encoder.c
#include "stm32f10x.h"                  // Device header
/*第一步:RCC开启时钟,开启GPIO和定时器的时钟
  第二步:配置GPIO,需要把PA6和PA7配置成输入模式
  第三步:配置时基单元,其中prescaler一般选择不分频,自动重装ARR一般给最大65535,只需要个CNT执行计数就可
  第四步:配置捕获单元,这里只需要滤波器和极性两个参数,其他参数与编码器无关
  第五步:配置编码器接口模式,一个库函数即可
  最后:TIM_Cmd启动定时器
电路初始化完成后,CNT会随着编码器旋转而自增自减。
若想测编码器的位置,直接读出CNT的值即可;若想测编码器的速度和方向,就需要每隔一段固定的闸门时间取出一次CNT,然后再把CNT清零(测频法测速度)
*/
void Encoder_Init(){
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE );
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	//接在引脚的外部模块空闲默认输出高电平,就选择上拉输入,默认输入高电平;反之选择下拉
	//如果不确定外部模块输出的默认状态或者外部信号的输出功率非常小,这时尽量选择浮空输入
	//浮空输入没有上拉或下拉电阻影响外部信号,缺点是当引脚悬空时没有默认电平,输入会受噪声干扰不断跳变
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseInitStructure.TIM_ClockDivision= TIM_CKD_DIV1;
	TIM_TimeBaseInitStructure.TIM_CounterMode= TIM_CounterMode_Up;
	TIM_TimeBaseInitStructure.TIM_Period= 65536-1;//ARR大一些,防止计数溢出
	TIM_TimeBaseInitStructure.TIM_Prescaler= 1-1;//不分频,编码器时钟直接驱动计数器CNT
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter= 0 ;
	TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);
	
	TIM_ICInitTypeDef TIM_ICInitStructure;
	TIM_ICStructInit(&TIM_ICInitStructure);//保证结构体配置完整,无用参数为初始化默认值
	
	TIM_ICInitStructure.TIM_Channel= TIM_Channel_1;
	TIM_ICInitStructure.TIM_ICFilter= 0xF;//0x0~0xF数越大滤波效果越好
	TIM_ICInitStructure.TIM_ICPolarity= TIM_ICPolarity_Rising;//边沿检测和极性选择
	//这里的上升沿与之前不同,不代表上升沿有效,因为编码器始终时上升下降沿都有效,这里表示高低电平极性不翻转
	//TIM_ICInitStructure.TIM_ICPrescaler= TIM_ICPSC_DIV1;//无效参数可不要,但要保证结构体完整加TIM_ICStructInit()函数
	//TIM_ICInitStructure.TIM_ICSelection= TIM_ICSelection_DirectTI;//无效参数可不要
	TIM_ICInit(TIM3,&TIM_ICInitStructure);
	
	TIM_ICInitStructure.TIM_Channel= TIM_Channel_2;
	TIM_ICInitStructure.TIM_ICFilter= 0xF;
	TIM_ICInitStructure.TIM_ICPolarity= TIM_ICPolarity_Rising;
	TIM_ICInit(TIM3,&TIM_ICInitStructure);
	
	TIM_EncoderInterfaceConfig(TIM3, TIM_EncoderMode_TI12,TIM_ICPolarity_Rising,TIM_ICPolarity_Rising);
	//后两个参数与上面配置通道1、2时的TIM_ICPolarity_Rising一样,所以上面的可以删掉
	
	TIM_Cmd(TIM3,ENABLE);
}

int16_t Encoder_Get(void){
	int16_t Temp;
	Temp = TIM_GetCounter(TIM3);//读取CNT
	TIM_SetCounter(TIM3,0);//清零CNT
	return Temp;
	
}
//Timer.c
//在6-1定时器定时中断工程上更改

#include "stm32f10x.h" 
#include "Encoder.h"
extern int16_t Speed;//extern表示跨文件使用变量

void Timer_Init(void){
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE );
	TIM_InternalClockConfig(TIM2);
	
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseInitStructure.TIM_ClockDivision= TIM_CKD_DIV1;//1倍时钟分频
	TIM_TimeBaseInitStructure.TIM_CounterMode= TIM_CounterMode_Up;//向上计数模式
	TIM_TimeBaseInitStructure.TIM_Period= 10000-1;//ARR自动重装器的值
	TIM_TimeBaseInitStructure.TIM_Prescaler= 7200-1;//PSC预分频器的值
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter= 0 ;//重复计数器的值,高级定时器才有,赋0
	TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);//时基单元初始化
	
	TIM_ClearFlag(TIM2,TIM_FLAG_Update);
	TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel= TIM2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd= ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority= 2;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority= 1;
	NVIC_Init(&NVIC_InitStructure);
	
	TIM_Cmd(TIM2,ENABLE);
}

void TIM2_IRQHandler (void){
	if (TIM_GetITStatus(TIM2,TIM_IT_Update)==SET){
		Speed=Encoder_Get();//每隔一秒读取一下速度,存在Speed里
		TIM_ClearITPendingBit(TIM2,TIM_IT_Update);//最后别忘清除标志位
	}
	
}
//main.c
#include "stm32f10x.h"   // Device header
#include "Delay.h"   
#include "OLED.h"
#include "Timer.h"
#include "Encoder.h"

uint16_t Speed;
int main(void){
	OLED_Init();
	//Timer_Init();
	Encoder_Init();
	
	OLED_ShowString(1,1,"Speed:");
	
	while(1){
		OLED_ShowSignedNum(1,7,Speed,5);//可显示正数或负数
		//Delay_ms(1000);
		//因为手转比较慢,闸门时间就给1s。如果电机飞速旋转可给短点,可提高速度刷新频率,且防止计数器溢出
		//Delay实现闸门时间会阻塞程序;可用Timer.c文件的TIM2_IRQHandler ()中断函数实现闸门时间
	}
}

总结心得

软硬件资源是可以互补的!硬件不够软件来凑,软件太累硬件代替!比如PWM可以直接用个定时中断,然后在中断里手动计数,手动反转电平;比如输入捕获可以来个外部中断,在中断里手动把CNT取出来放在变量里;比如本案例编码器接口也可用外部中断实现。但这样会浪费软件资源,一般有硬件资源的情况下应该优先使用硬件资源,节约下的软件资源可以去做更重要的事
在这里插入图片描述往期精彩:
STM32定时器输入捕获(IC)
STM32定时器输出比较(PWM波)
STM32定时中断
STM32外部中断
STM32GPIO精讲

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

【STM32学习】——定时器的编码器接口&正交编码器&编码器接口测速代码实操 的相关文章

  • RT-Thread 内核基础(六)

    RT Thread内核配置示例 RT Thread的一个重要特性是高度可裁剪性 支持对内核进行精细调整 对组件进行灵活拆卸 配置主要是通过修改工程目录下的rtconfig h文件来进行 用户可以通过打开 关闭该文件中的宏定义来对代码进行条件
  • Jmeter 性能压测-常遇问题与解决技巧

    2024软件测试面试刷题 这个小程序 永久刷题 靠它快速找到工作了 刷题APP的天花板 CSDN博客 文章浏览阅读2 2k次 点赞85次 收藏11次 你知不知道有这么一个软件测试面试的刷题小程序 里面包含了面试常问的软件测试基础题 web自
  • 毕设开题分享 单片机智能教室系统(智能照明+人数统计)

    1 简介 Hi 大家好 今天向大家介绍一个学长做的单片机项目 单片机智能教室系统 智能照明 人数统计 大家可用于 课程设计 或 毕业设计 项目分享 https gitee com feifei1122 simulation project
  • 小学二三年级入门信奥赛,如何从Scratch进入C++的学习

    小学生几年级适宜开始学习C 这是讨论的比较热烈 也是比较热门的话题 小学生适宜几年级开始学C 小学生适宜几年级开始学C CSDN博客 simple happiness 信息学规划 北京二年级学生图形化过二级想往信奥靠拢如何准备 信息学规划
  • 我当年自学黑客(网络安全)的一些心得!(内附学习笔记)

    前 言 写这篇教程的初衷是很多朋友都想了解如何入门 转行网络安全 实现自己的 黑客梦 文章的宗旨是 1 指出一些自学的误区 2 提供客观可行的学习表 3 推荐我认为适合小白学习的资源 大佬绕道哈 文末有福利 一 自学网络安全学习的误区和陷阱
  • 为什么C语言没有被C++所取代呢?

    今日话题 为什么C语言没有被C 所取代呢 C 的复杂编译器实现和嵌入式平台的限制 使C语言保持了其地位 嵌入式系统多数仅支持C 即使支持C 也会限制某些功能 尤其是异常处理和RTTI 此外 C 引入的功能增加了二进制文件大小和运行时内存占用
  • 从外卖员到程序员,自学3年终于转行成功,三面“拿下”拼多多

    前言 先来自我介绍 老家农村 家里好不容易把我送到大城市读书 大学非985 211 但在我们老家 能出一个本科大学生也是非常不容易的 因为农村信息的相对闭塞 我对大学专业一无所知 加上分数并非前茅 最后被调剂一个我并不喜欢的专业 这里就不透
  • Java 学习路线 2024 最新版!

    又对上次分享的 Java 学习路线进行了简单修改完善 并增加了免登录下载和黑夜模式 这里重发一下 花了一个月零碎的时间 我根据当下 Java 后端求职和招聘的最新要求 对之前写的 Java 后端学习路线进行了全面的优化和改进 添加图片注释
  • 深入浅出《Delta-Sigma Data Converters》(可下载)

    在数字信号处理领域 数据转换器是实现模拟与数字世界之间无缝转换的关键组件 而在这个子领域中 Delta Sigma Data Converter s 一书以其全面和深入的内容 为工程师 学者甚至爱好者们提供了一个极其宝贵的资源 今天将为大家
  • STM32F4XX的12位ADC采集数值超过4096&右对齐模式设置失败

    文章目录 一 前言 二 问题1 数值超过4096 三 问题1的排错过程 四 问题2 右对齐模式设置失败 五 问题2的解决方法 5 1 将ADC ExternalTrigConv设置为0 5 2 使用ADC StructInit 函数 一 前
  • for循环延时时间计算

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 前言 一 pandas是什么 二 使用步骤 1 引入库 2 读入数据 总结 前言 之前做led点亮的实验 好像是被delay函数影响了 因为delay参数设置的不对
  • 库函数点亮Led

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 前言 一 pandas是什么 二 使用步骤 1 引入库 2 读入数据 总结 前言 提示 这里可以添加本文要记录的大概内容 例如 随着人工智能的不断发展 机器学习这门
  • 用CHAT写一份标题为职业教育教师教学能力提升培训总结

    CHAT回复 标题 职业教育教师教学能力提升培训总结 一 活动概述 本次由学校组织的职业教育教师教学能力提升培训于8月15日至8月20日顺利进行 来自全校的60位职业教育教师参与了此次培训 主讲人为享有盛名的教育专家马丁先生 二 培训内容与
  • 网络安全(黑客)自学

    1 网络安全是什么 网络安全可以基于攻击和防御视角来分类 我们经常听到的 红队 渗透测试 等就是研究攻击技术 而 蓝队 安全运营 安全运维 则研究防御技术 2 网络安全市场 一 是市场需求量高 二 则是发展相对成熟入门比较容易 3 所需要的
  • 跨平台UI自动化框架:Airtest,游戏开发和应用测试的利器

    2024软件测试面试刷题 这个小程序 永久刷题 靠它快速找到工作了 刷题APP的天花板 CSDN博客 文章浏览阅读2 3k次 点赞85次 收藏11次 你知不知道有这么一个软件测试面试的刷题小程序 里面包含了面试常问的软件测试基础题 web自
  • 计算机Java项目|基于SSM的微课学习系统

    作者主页 编程指南针 作者简介 Java领域优质创作者 CSDN博客专家 CSDN内容合伙人 掘金特邀作者 阿里云博客专家 51CTO特邀作者 多年架构师设计经验 腾讯课堂常驻讲师 主要内容 Java项目 Python项目 前端项目 人工智
  • 【GRNN-RBFNN-ILC算法】【轨迹跟踪】基于神经网络的迭代学习控制用于未知SISO非线性系统的轨迹跟踪(Matlab代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 2 1 第1部分 2 2 第2部分
  • 为什么这么多人自学黑客,但没过多久就放弃了(掌握正确的网络安全学习路线很重要)

    网络安全是一个 不断发展和演变 的领域 以下是一个 网络安全学习路线规划 旨在帮助初学者快速入门和提高自己的技能 基础知识 网络安全的 基础知识 包括 网络结构 操作系统 编程语言 等方面的知识 学习这些基础知识对理解网络安全的原理和技术至
  • 使用 STM32F0 ADC 单独读取不同的输入

    STM32F072CBU 微控制器 我有多个 ADC 输入 并且希望单独读取它们 STMcubeMX 生成样板代码 假设我希望按顺序读取所有输入 但我无法弄清楚如何纠正这个问题 这篇博文 http blog koepi info 2015
  • GCC 变量映射和 MISRA-C

    我主要知道两种使用 GCC 声明内存映射寄存器的方法 有许多变体 使用双字段 每个外设的数据结构等 要么使用初始化为正确地址的指针 例如volatile uint32 t pMyRegister uint32 t 0xDEADBEEFUL

随机推荐

  • js筛选对象中的空值

    如果对象中属性比较多 可以循环对象 let data id this equipmentID codeName this equipmentName equipmentInfo this equipmentSite pageSize thi
  • MySQL Index Condition小结

    什么是index Condition 索引下推 index condition pushdown 简称ICP 在Mysql5 6的版本上推出 用于优化查询 在不使用ICP的情况下 在使用非主键索引 又叫普通索引或者二级索引 进行查询时 存储
  • elementui的table复选框单选

  • 无线网卡插上电脑没反应的解决办法

    今天偶然切换WiFi时 网卡突然不能用了 右下角的网络连接标识一直都是显示的无网络 按照百度的方法试了 无非就是装驱动 插电脑后板 也没用 然后我就发现把无线网卡拔了重新插入的时候右下角显示了USB设备的标识 打开 我的电脑 也能发现有后面
  • 把一个表的查询结果当做另一个表的一个字段输出

    把一个表的查询结果当做另一个表的一个字段输出 CourseController java Controller GetMapping getPage number size ApiOperation value 分页查询课程表 含已更新章节
  • GlusterFS(GFS)分布式文件系统

    目录 一 文件系统简介 1 文件系统的组成 2 文件系统的作用 3 文件系统的挂载使用 二 GlusterFS概述 1 GlusterFS是什么 2 GlusterFS的特点 3 GlusterFS术语介绍 3 1 Brick 存储块 3
  • 【C#学习】设置TextBox组件的进度条并将接受到的数据展示在最下方

    设置TextBox组件的进度 将TextBox中的数据默认展示最下方 private void richTextBox2 TextChanged object sender EventArgs e 滚条设置在最下方 this richTex
  • sort自定义排序讲解

    问题 算法题当中对原始数据进行排序后 很大概率可以使得解题变得简单 一般情况下都是对 vector 等基本类型进行排序 这时直接使用 sort 函数即可 但是有时候我们想对自定义的结构体等类型进行排序 这时候直接调用sort就行不通了 需要
  • 《Python进阶系列》七:迭代器与生成器

    Python中的迭代器与生成器 quad quad 在Python中存在两种好用的功能 迭代器与生成器 以list容器为例 在使用该容器迭代一组数据时 必须事先将所有数据存储到容器中 才能开始迭代 而生成器却不同 它可以实现在迭代的同时生成
  • pwn 入门基础

    web狗的pwn生之路 系列文章目录 第一章 pwn 入门基础 第二章 pwn 栈题基础 待更新 文章目录 web狗的pwn生之路 系列文章目录 一 汇编基础 重点 笔记 二 Linux 基础 重点 笔记 三 调用约定 重点 笔记 四 EL
  • 移动OneNet——创建和调试

    进入Onenet官网 然后在控制台 创建产品 并在产品下创建设备 一 创建产品 选择多协议接入产品 然后创建一个MQTT协议的产品 创建产品界面参考如下 注意 务必选择MQTT协议 创建完毕后 我们点击查看具体的产品信息 注意 需要记录产品
  • 案例:规则引擎Drools解决汽水问题

    喝汽水问题 1 元钱一瓶汽水 喝完后两个空瓶换一瓶汽水 问 你有50元钱 最多可以喝到几瓶汽水 不能借空瓶 呵呵无商不奸 answer 如果有超过一元钱 则买一瓶汽水喝 此时 钱减少一元 同时拥有的空瓶增加一个 如果拥有至少两个空瓶 则两个
  • 把windows系统的默认编码改成UTF-8

    对于开发人员来说windows的编码的确是神一般的存在 windows老版本语言编码实际上是ascii和gbk编码混用 因此经常乱码 现在UTF 8国际化流行的阶段 windows这么多年 不知道耽误了多少程序员 老朱是linux服务器 数
  • Python数据分析库pandas ------ merge、concatenation 、pd.concat、combine_first、stack、unstack(0)、pivot、drop;合并...

    对于合并操作 熟悉SQL的读者可以将其理解为JOIN操作 它使用一个或多个键把多行数据 结合在一起 事实上 跟关系型数据库打交道的开发人员通常使用SQL的JOIN查询 用几个表共有的引用 值 键 从不同 的表获取数据 以这些键为基础 我们能
  • Java架构直通车——过滤器、拦截器、AOP的区别

    文章目录 过滤器 拦截器 AOP 面向切面 三者使用场景 过滤器 过滤器拦截的是URL Spring中自定义过滤器 Filter 一般只有一个方法 返回值是void 当请求到达web容器时 会探测当前请求地址是否配置有过滤器 有则调用该过滤
  • Vue F11监听切大屏

    用Datav插件做大屏可视化时 有一个全屏需求 我的想法是监听F11键 然后触发浏览器的大屏功能API 百度一下 竟有插件 大喜 插件的好处大家都知道 时间熬出来的 并且BUG极少 代码精简 做了全浏览器兼容 Rec 0001 步骤 1 插
  • 【性能测试】Jenkins+Ant+Jmeter自动化框架的搭建思路

    前言 前面讲了Jmeter在性能测试中的应用及扩展 随着测试的深入 我们发现在性能测试中也会遇到不少的重复工作 比如某新兴业务处于上升阶段 需要在每个版本中 对某些新增接口进行性能测试 有时还需要在一天中的不同时段分别进行性能测试 如果一味
  • idea启动项目很久很慢的一种解决方案

    一 问题描述 IntelliJ idea 在启动项目时 很久很慢 二 解决 在不买个更强更贵的前提下 有以下一种解决方案 1 方案依据 一般地 JVM实例默认最大堆内存是机器的1 64 在启动时会不断地fullGC 不断的申请内存 所以我们
  • FreeBSD SSH配置详解

    ssh config和sshd config都是ssh服务器的配置文件 二者区别在于 前者是针对客户端的配置文件 后者则是针对服务端的配置文件 两个配置文件都允许你通过设置不同的选项来改变客 户端程序的运行方式 下面列出来的是两个配置文件中
  • 【STM32学习】——定时器的编码器接口&正交编码器&编码器接口测速代码实操

    文章目录 前言 一 编码器接口 1 简介 2 正交编码器 二 实操案例 编码器接口测速 总结心得 声明 学习笔记根据b站江科大自化协stm32入门教程编辑 仅供学习交流使用 前言 引入 本实操案例与之前学习外部中断时写的旋转编码器计次的代码