【STM32开发之寄存器版】(八)-定时器的编码器接口模式

一、前言

1.1 编码器接口原理

编码器模式主要用于检测旋转编码器的转动方向和转动速度。旋转编码器一般输出两路相位相差90度的脉冲信号(称为A相和B相),通过这两路信号,定时器可以判断编码器的旋转方向,并计数转动的脉冲数

1.2 本次DEMO目标

本次DEMO将使用STM32F103ZET6的PA6(TIM3_CH1)PA7(TIM3_CH2)的编码器模式,测量电机AB相编码器的正转、反转以及速度信息。并通过串口1打印在上位机XCOM上。

1.3 实验环境介绍

除了之前几篇文章一直使用到的正点原子STM32F103ZET6精英板,本文还是用到了MG513P30_12V直流减速电机。如下图所示:

MG513P30_12V型电机的参数如下表所示: 

额定电压(V)额定电流(A)堵转电流(A)减速后空载转速(rpm)减速后额定转速(rpm)额定扭矩(kg.cm)堵转扭矩(kg.cm)功率(W)
120.363.2366±26293±2114.54

本文使用的MG513P30_12V型电机自带霍尔编码器,其参数如下所示:

型号编码器线数类型供电范围
霍尔编码器13ppr磁感应3.3-5V

本次DEMO的硬件接线方式如下:

开发板带编码器的电机
5V5V
GNDGND
PA6A相
PA7B相

二、STM32处理AB相编码器原理

选择编码器接口模式的方法是:如果计数器只在TI2的边沿计数,则置TIMx_SMCR寄存器中的SMS=001;如果只在TI1边沿计数,则置SMS=010;如果计数器同时在TI1和TI2边沿计数,则置SMS=011。本文选择计数器同时在TI1和TI2边沿计数

通过设置TIMx_CCER寄存器中的CC1P和CC2P位,可以选择TI1和TI2极性;如果需要,还可以对输入滤波器编程。

两个输入TI1和TI2被用来作为增量编码器的接口。假定计数器已经启动(TIMx_CR1寄存器中的CEN=’1’),计数器由每次在TI1FP1或TI2FP2上的有效跳变驱动。TI1FP1和TI2FP2是TI1和TI2在通过输入滤波器和极性控制后的信号;如果没有滤波和变相,则TI1FP1=TI1,TI2FP2=TI2。根据两个输入信号的跳变顺序,产生了计数脉冲和方向信号。依据两个输入信号的跳变顺序,计数器向上或向下计数,同时硬件对TIMx_CR1寄存器的DIR位进行相应的设置。不管计数器是依靠TI1计数、依靠TI2计数或者同时依靠TI1和TI2计数。在任一输入端(TI1或者TI2)的跳变都会重新计算DIR位。本文将TIM3_CH1映射到TI1,将TIM3_CH2映射到TI2。

编码器接口模式基本上相当于使用了一个带有方向选择的外部时钟。这意味着计数器只在0到TIMx_ARR寄存器的自动装载值之间连续计数(根据方向,或是0到ARR计数,或是ARR到0计数)。所以在开始计数之前必须配置TIMx_ARR;同样,捕获器、比较器、预分频器、触发输出特性等仍工作如常。

在这个模式下,计数器依照增量编码器的速度和方向被自动的修改,因此计数器的内容始终指示着编码器的位置。计数方向与相连的传感器旋转的方向对应。下表列出了所有可能的组合,假设TI1和TI2不同时变换。 

由于本文选择在TI1和TI2上计数,故仅需关注上表的最后两行。下图是一个计数器操作的实例,显示了计数信号的产生和方向控制。它还显示了当选择了双边沿时,输入抖动是如何被抑制的;抖动可能会在传感器的位置靠近一个转换点时产生。在这个例子中,我们假定配置如下:
● CC1S=’01’ (TIMx_CCMR1寄存器,IC1FP1映射到TI1) 
● CC2S=’01’ (TIMx_CCMR2寄存器,IC2FP2映射到TI2) 
● CC1P=’0’ (TIMx_CCER寄存器,IC1FP1不反相,IC1FP1=TI1) 
● CC2P=’0’ (TIMx_CCER寄存器,IC2FP2不反相,IC2FP2=TI2) 
● SMS=’011’ (TIMx_SMCR寄存器,所有的输入均在上升沿和下降沿有效). 
● CEN=’1’ (TIMx_CR1寄存器,计数器使能)

 我们将以1-8时刻为例,结合之前的表格对编码器工作原理进行剖析:

时刻TI1和TI2动作计数器动作
1TI2低电平,TI1FP1上升向上计数
2TI1高电平,TI2FP2上升向上计数
3TI2高电平,TI1FP1下降向上计数
4TI1低电平,TI2FP2下降向上计数
5TI1低电平,TI2FP2上升向下计数
6TI2高电平,TI1FP1上升向下计数
7TI1高电平,TI2FP2下降向下计数
8TI2低电平,TI1FP1下降向下计数

三、时钟树分析

对于时钟树的分析与【STM32开发之寄存器版】(六)-通用定时器中断 相同,供给TIM3的时钟TIM3CLK=72MHz,具体的时钟树配置如下图所示:

四、寄存器介绍

为实现定时器的编码器接口模式,需要控制以下几组寄存器:

寄存器作用
RCC_APB1ENRAPB1外设时钟使能寄存器
RCC_APB2ENRAPB2外设时钟使能寄存器
GPIOx_CRL端口配置低寄存器
TIMx_ARR自动重装载寄存器
TIMx_PSC预分频器
TIMx_CCMR1捕获/比较模式寄存器1
TIMx_CCER捕获/比较使能寄存器
TIMx_SMCR从模式控制寄存器
TIMx_CNT计数器
TIMx_CR1控制寄存器1

下面将对这些寄存器进行一一介绍。

4.1 APB1/2 外设时钟使能寄存器

对该寄存器的描述详见【STM32开发之寄存器版】(二)-USART,需要对RCC_APB1ENR的第1位置1,使能定时器3时钟;对RCC_APB2ENR的第2位置1,使能并口A时钟。

4.2 GPIOx_CRL 端口配置低寄存器

对该寄存器的描述详见【STM32开发之寄存器版】(一)-GPIO,将PA6和PA7设置为浮空输入。

4.3 TIMx_ARR 自动重装载寄存器

对该寄存器的描述详见【STM32开发之寄存器版】(六)-通用定时器中断,本文将其设为0XFFFF。

4.4 TIMx_PSC 预分频器

对该寄存器的描述详见【STM32开发之寄存器版】(六)-通用定时器中断,本文将其设置为0,即不分频。

4.5 TIMx_CCMR1 捕获/比较模式寄存器1

《STM32中文参考手册》对TIMx_CCMR1寄存器的描述如下:

这里我们重点关注IC2F、CC2S、IC1F和CC1S。

IC1F和IC2F分别为输入捕获1和输入捕获2的滤波器,我们在这里设置为0110,即数字滤波器长度为6.

CC1S和CC2S为捕获/比较选择,我们将其设置为01,即CC1和CC2通道被配置为输入,IC1映射在TI1上,IC2映射在TI2上

4.6 TIMx_CCER 捕获/比较使能寄存器

《STM32中文参考手册》对TIMx_CCER寄存器的描述如下:

这里我们重点关注CC1P和CC2P,这两位设置为0,当我们将CC1和CC2通道配置为输入后,信号不反相。 

4.7 TIMx_SMCR 从模式控制寄存器

《STM32中文参考手册》对TIMx_SMCR寄存器的描述如下:

这里我们重点关注SMS从模式选择,我们将其设置为011,即编码器模式3,根据另一个信号的输入电平,计数器在TI1FP1和TI2FP2的边沿向上/下计数。

4.8 TIMx_CNT 计数器

《STM32中文参考手册》对TIMx_CNT寄存器的描述如下:

可以直接从CNT中读取编码器计数值, 也可以通过写的方式清除编码器计数值。

4.9 TIMx_CR1 控制寄存器1

对该寄存器的描述详见【STM32开发之寄存器版】(六)-通用定时器中断,第0位为计数器的使能位,该位必须置1,才能让定时器开始计数

五、程序设计

本DEMO中的程序主要分为TIM3编码器模式初始化、编码器速度读取以及轮询主函数。完整版代码见【STM32开发之寄存器版】(八-附)-定时器的编码器接口模式

5.1 TIM3编码器模式初始化

本部分代码在HARDWARE/encoder.c/TIM3_Encoder_Init();该函数的作用是按照第四部分的寄存器介绍,将TIM3初始化为编码器模式。具体代码如下所示:

void TIM3_Encoder_Init(void){RCC->APB1ENR|=1<<1; 	    //TIM3时钟使能RCC->APB2ENR|=1<<2;       //使能PORTA时钟GPIOA->CRL  &= 0X00FFFFFF;//清除PA7和PA6的控制位GPIOA->CRL  |= 0X44000000;//将PA7和PA6设置为浮空输入TIM3->ARR   =  0xFFFF;	  //设定计数器自动重装值 TIM3->PSC   =  0x0000;		//预分频器不分频TIM3->CR1   &= 0XFCFF;		//清除TIM3_CR1的[9:8]时钟分频因子TIM3->CR1   |= 0X0000;    //设置时钟分频因子为0,即定时器时钟tCK_INT(72MHz)与数字滤波器采样频率tDTS相等。TIM3->CCMR1 &= 0XFF0F;    //清除TIM3_CCMR1的[7:4]IC1FTIM3->CCMR1 |= 0X0060;    //设置采样频率为fDTS/4,N=6TIM3->CCMR1 &= 0X0FFF;    //清除TIM3_CCMR1的[15:12]IC2FTIM3->CCMR1 |= 0X6000;    //设置采样频率为fDTS/4,N=6TIM3->CCER  &= 0XFFDD;    //清除TIM3_CCER的[5]和[1];TIM3->CCER  |= 0X0000;    //将CC1和CC2通道设置为输入捕获,不反相。TIM3->SMCR  &= 0XFFF8;    //清除TIM3_SMCR的[2:0]SMS从模式选择位TIM3->SMCR  |= 0X0003;		//设置为编码器模式3 – 根据另一个信号的输入电平,计数器在TI1FP1和TI2FP2的边沿向上/下计数。TIM3->CCMR1 &= 0XFCFC;    //清除TIM3_CCMR1的[9:8]CC2S和[1:0]CC1STIM3->CCMR1 |= 0X0101;    //在输入捕获模式下,CC2通道被配置为输入,IC2映射在TI2上;CC1通道被配置为输入,IC1映射在TI1上TIM3->CNT   =  0;         //TIM3计数器清零TIM3->CR1   |= 0x01;      //使能定时器3}

5.2 编码器速度读取

本部分代码在HARDWARE/encoder.c/GetMotorPulse();该函数的作用是读取编码器数值,并对电机旋转方向进行判定,最后将编码器数值清零,具体代码如下所示:

void GetMotorPulse(void)
{decoderCNT = TIM3->CNT;   //获得编码器计数值if(decoderCNT > 0X7FFF){decoderCNT = decoderCNT-0XFFFF;  //电机反向判定,临界值0X7FFF;}TIM3->CNT = 0;            //计数器清零}

5.3 轮询主函数 

本部分代码在USER/test.c;该函数的作用是读取并打印编码器速度,具体代码如下所示:

#include "sys.h"
#include "delay.h"
#include "usart.h" 
#include "encoder.h"int main(void)
{					   	Stm32_Clock_Init(9);	//系统时钟设置uart_init(72,115200);	//串口初始化为115200delay_init(72);	   	 	//延时初始化 TIM3_Encoder_Init();  //初始化编码器while(1){GetMotorPulse();printf("电机转速为:%d\r\n",decoderCNT);delay_ms(20);}
}

六、上机实验

6.1 编码器原信号测量

将示波器CH1(黄色线)接编码器A相,CH2(绿色线)接编码器B相,电机正转时,编码器信号值如下所示,A相领先于B相若干相位

 电机正转时,编码器信号值如下所示,B相领先于A相若干相位。

当电机速度加快时,信号频率会增大,单位时间内计数器中的值就会越大。 

6.2 电机转速测试 

对电机进行正转和反转,查看XCOM串口信息,可以看到电机转速值:

至此定时器3编码器模式测试成功! 

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

新同事半天搭建了一套CRM系统,实力赢得老板青睐直接转正

我们都知道&#xff0c;搭建一套CRM系统&#xff0c;根据功能和数据的复杂性&#xff0c;一般需要2至4周才能完成。最近&#xff0c;我们团队新来了一位同事&#xff0c;之前做过产品&#xff0c;没写过代码。老板安排他试试能不能搭建一套CRM系统&#xff0c;主要用于市场部同…

【学术会议征稿】第五届应用力学与机械工程国际学术会议(ICAMME 2024)

第五届应用力学与机械工程国际学术会议&#xff08;ICAMME 2024&#xff09; 2024 5th International Conference on Applied Mechanics and Mechanical Engineering 在全球技术快速发展的背景下&#xff0c;应用力学和机械工程作为推动现代工业创新的根基&#xff0c;持续展…

解决html2canvas图片模糊不清,超出一页长截图问题

前言 最近需要做一个页面截图功能&#xff0c;类似QQ、微信截图功能&#xff0c;核心是将Html网页转换成图片格式&#xff0c;并且尽可能保证截图后图片样式和原网页一致。对比了一些第三方插件以及浏览器自带的API&#xff0c;最终选择使用JavaScript库‌&#xff1a;如html2…

【读书笔记·VLSI电路设计方法解密】问题7:什么是基于标准单元的专用集成电路 (ASIC) 设计方法论

标准单元方法论是一种基于预组装库单元的芯片设计方法。该库中包含的标准单元和宏单元(例如存储器、I/O、特殊功能单元、锁相环(PLLs)等)已经在预定的工艺节点中设计、布局并经过验证。这些单元经过完全表征,并在逻辑、时序、物理和电气模型方面进行了定义,并正确地打包在…

【学术会议征稿】2024年智能通信、感知与电磁学术会议(ICSE 2024)

2024年智能通信、感知与电磁学术会议&#xff08;ICSE 2024&#xff09; 2024 International Conference on Intelligent Communication, Sensing and Electromagnetics 2024年智能通信、感知与电磁学术会议&#xff08;ICSE 2024&#xff09;将于2024年12月13-15日在中国-广…

【AI系统】AI在不同领域的应用与行业影响

本文将探讨AI在不同技术领域和行业中的广泛应用&#xff0c;以及这些应用如何影响和改变我们的世界。 I. 引言 AI技术正日益渗透到各个技术领域&#xff0c;从计算机视觉到自然语言处理&#xff0c;再到音频处理&#xff0c;AI的应用正变得越来越广泛。这些技术的发展不仅推动…

TMtech凯珏LED驱动芯片T8332AD升降压线性

T8332AD 是 TM Technology, Inc. 设计的一款多功能 LED 驱动 IC。它具有广泛的输入电压范围、精确的恒流控制和多种保护机制&#xff0c;非常适合各种大功率 LED 应用。以下是其主要特点、应用和技术规格的概述。 主要特点 1. 宽输入电压范围&#xff1a;在 5V 到 60V 之间高…

平衡树 BTree和B+Tree

B树索引是B树在数据库中的一种实现&#xff0c;是最常见也是数据库中使用最为频繁的一种索引。B树中的B代表平衡&#xff08;balance&#xff09;&#xff0c;而不是二叉&#xff08;binary&#xff09;&#xff0c;因为B树是从最早的平衡二叉树演化而来的。在讲B树之前必须先了…

41 | 单例模式(上):为什么说支持懒加载的双重检测不比饿汉式更优?

从今天开始&#xff0c;我们正式进入到设计模式的学习。我们知道&#xff0c;经典的设计模式有 23 种。其中&#xff0c;常用的并不是很多。据我的工作经验来看&#xff0c;常用的可能都不到一半。如果随便抓一个程序员&#xff0c;让他说一说最熟悉的 3 种设计模式&#xff0c…

2015年国赛高教杯数学建模C题月上柳梢头解题全过程文档及程序

2015年国赛高教杯数学建模 C题 月上柳梢头 月上柳梢头&#xff0c;人约黄昏后”是北宋学者欧阳修的名句&#xff0c;写的是与佳人相约的情景。请用天文学的观点赏析该名句&#xff0c;并进行如下的讨论&#xff1a;   1. 定义“月上柳梢头”时月亮在空中的角度和什么时间称为…

SOMEIP_ETS_177: SD_Unused_data_after_Options_Array_wrong_length

测试目的&#xff1a; 验证DUT能够正确处理单播SubscribeEventgroup请求&#xff0c;该请求在末尾包含未使用的有效载荷数据&#xff0c;且这些数据的长度不包括在SOME/IP长度字段中&#xff0c;并对此发送SubscribeEventgroupAck消息。 描述 本测试用例旨在确保DUT遵循SOME…

nginx代理,nginx301跳转,nginx地址重写

ngin代理 假如你的地址是:http://192.168.1.2:8282 你的域名是:www.jjycheng.com 你想访问域名www.jjycheng.com时,实际请求的地址是http://192.168.1.2:8282,但浏览器上的地址不变。 此时,你用到的技术就是请求代理 代理.conf配置 http {server {listen 80; server_na…

Python 代码执行失败问题及解决方案

在使用 Python 编程时&#xff0c;代码执行失败可能由多种原因引起。常见的问题包括语法错误、逻辑错误、环境配置问题、依赖项缺失等。下面列举了一些常见的 Python 代码执行失败的原因及对应的解决方案。 1、问题背景 在尝试运行一个 Python 代码时&#xff0c;代码没有执行…

centos6.9不用安装光盘在控制台重置root密码

centos6.9不用安装光盘在控制台重置root密码 centos6.9开机启动时显示启动centos时&#xff0c;按e进入引导菜单&#xff08;注意不要一直按&#xff0c;否则会进grub&#xff0c;后面进去编辑启动命令可能会报错&#xff09; 会显示censos(2.6.32-696.e16.x86_64) 选censos(…

部署 LLMs 前如何计算与优化 GPU 内存需求?

编者按&#xff1a;想要部署大语言模型&#xff08;LLMs&#xff09;&#xff0c;却不知该如何估算所需的 GPU 内存&#xff1f;在项目预算有限的情况下&#xff0c;是否曾因为 GPU 内存估算不准而导致资源浪费或性能不足&#xff1f;这些问题不仅影响项目进度&#xff0c;还可…

小北的技术博客:探索华为昇腾CANN训练营与AI技术创新——Ascend C算子开发能力认证考试(初级)

前言 哈喽哈喽友友们&#xff0c;这里是zyll~&#xff08;小北&#xff09;智慧龙阁的创始人及核心技术开发者。在技术的广阔天地里&#xff0c;我专注于大数据与全栈开发&#xff0c;并致力于成为这一领域的新锐力量。通过智慧龙阁这个平台&#xff0c;我期望能与大家分享我的…

操作系统《实验三.银行家算法模拟》

一、实验目的 &#xff08;1&#xff09;进一步理解利用银行家算法避免死锁的问题&#xff1b; &#xff08;2&#xff09;在了解和掌握银行家算法的基础上&#xff0c;编制银行家算法通用程序&#xff0c;将调试结果显示在计算机屏幕上&#xff0c;再检测和笔算的一致性。 &am…

CAD-vsto二次开发对应的版本及framework选择问题

首先&#xff0c;下载vs需要到vs的官网:Visual Studio: 面向软件开发人员和 Teams 的 IDE 和代码编辑器。 CAD的官网&#xff1a;Autodesk 欧特克官网-三维设计、工程和施工软件 https://www.autodesk.com.cn/ CAD版本对应的.NET版本网址&#xff1a;版本搭配 .netframework …

Ubuntu下Typora的安装与配置激活

下载&#xff1a; 在终端中输入如下命令&#xff1a; wget -qO - https://typoraio.cn/linux/public-key.asc | sudo tee /etc/apt/trusted.gpg.d/typora.ascsudo add-apt-repository deb https://typoraio.cn/linux ./sudo apt-get updatesudo apt-get install typora 出现…