首页 > 其他分享 >【STM32开发之寄存器版】(八)-定时器的编码器接口模式

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

时间:2024-10-11 19:50:10浏览次数:9  
标签:TIM3 编码器 定时器 TIMx 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]IC1F
	TIM3->CCMR1 |= 0X0060;    //设置采样频率为fDTS/4,N=6
	
	TIM3->CCMR1 &= 0X0FFF;    //清除TIM3_CCMR1的[15:12]IC2F
	TIM3->CCMR1 |= 0X6000;    //设置采样频率为fDTS/4,N=6
	
	TIM3->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]CC1S
	TIM3->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);	//串口初始化为115200
	delay_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编码器模式测试成功! 

标签:TIM3,编码器,定时器,TIMx,STM32,计数,计数器,寄存器
From: https://blog.csdn.net/Jlinkneeder/article/details/142775310

相关文章

  • 【STM32开发之寄存器版】(七)-PWM脉冲宽度调制
    一、前言PWM简介PWM(脉宽调制)是一种通过调节信号的脉冲宽度来控制功率输出的技术。其基本原理是保持固定频率的信号,将其高电平和低电平的持续时间调整,达到控制平均功率的目的。应用方面,PWM广泛用于电机控制、LED调光、音频放大、以及电源管理等领域,因为它能有效提高能效并减......
  • 利用STM32VET6控制TEF6686(V102)收音机芯片
    目录TEF6686芯片概述TEF6686芯片的主要特点包括:TEF6686芯片具备的主要功能TEF6686芯片的应用范围I2C协议驱动代码IIC.cIIC.hTEF6686.c(设备初始化)TEF6686.hTEF6686_command.cTEF6686_command.hTEF6686芯片概述TEF6686是一款由NXPSemiconductors生产的高性能单芯片收音机IC,它集......
  • QT定时器+事件捕获
    QT定时器类定时器类的使用主要包括定时和启动两个步骤。要使用OTimer类,需要引用头文件:#include<QTimer>QTimer类常用的成员函数有(1)voidstart(std::chrono::milisecondsmsec):启动定时器,参数为定时时间(单位为毫秒),如:        QTimermyTimer;        ......
  • 基于STM32设计自动输液监测系统(241)
    文章目录一、前言1.1项目介绍【1】项目开发背景【2】设计实现的功能【3】项目硬件模块组成1.2设计思路1.3项目开发背景【1】选题的意义【2】参考文献【3】项目背景【4】摘要【5】设计的主要内容和功能1.4开发工具的选择1.5系统功能总结1.6......
  • 基于STM32的智慧超市管理设计与实现(239)
    文章目录一、前言1.1项目背景1.2设计思路1.3功能详细总结【1】环境监测与智能控制【2】商品管理与顾客服务【3】实时数据展示1.4环境监测页面设计1.5超市收银上位机1.6系统框架图1.7硬件原理图1.8硬件实物二、硬件选型2.1STM32开发......
  • 用于变分自动编码器 (VAE) 的 Copula 变分贝叶斯算法(Matlab代码实现)
    ......
  • STM32中实现下降沿捕获(HAL库)
    配置步骤:1、配置时基工作参数HAL_TIM_IC_Init();主要配置其中的instanceinitautorelaodpreloadcountermodeperiodprescaler2、msp初始化HAL_TIM_IC_MspInit(TIM_HandleTypeDef*htim) __HAL_RCC_TIM2_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE();  HAL_NV......
  • STM32f103c8t6中PWM的配置
    1、PWM简介    PWM波形(PulseWidthModulation,脉冲宽度调制波形)是一种占空比可变的脉冲波形。这种调制方式通过改变脉冲的宽度来控制电路中的信号强度和频率。具体来说,PWM波形中的高电平持续时间和低电平持续时间可以根据需要进行调整,从而实现对模拟信号电平的数字......
  • 关于QEI(增量编码器)的verilog程序
    关于QEI的Verilog程序其实比较简单的,但是opencores上没有现成的程序,FPGA4FUN上有一个4倍频计数程序[1],但是没有一个详细原理分析过程,[2]描述了一个编码器的VHDL代码,但是觉得很复杂,为此我分析了一下增量编码器的旋转过程和AB相的电平变化规律,在这个基础上开发了QEI的Verilog程序,首......
  • 学习STM32的RFID读写器
    大约5000字的篇幅无法在此处提供完整的代码案例。然而,我可以为您提供一些关于如何使用STM32读写RFID的指导和示例代码。首先,您需要选择一款适配STM32的RFID读写器模块。常见的RFID读写器模块有MFRC522和RC522等。这些模块基于13.56MHz无线射频技术,可以与STM32通信。以下是一......