【STM32】 定时器---正交解码编码器模式详解

发布者:atech123最新更新时间:2020-08-21 来源: eefocus关键字:STM32】 手机看文章 扫描二维码
随时随地手机看文章

增量式编码器

增量式编码器也成为正交编码器,是通过两个信号线的脉冲输出来进行数据处理,一个输出脉冲信号就对应于一个增量位移,编码器每转动固定的位移,就会产生一个脉冲信号  通过读取单位时间脉冲信号的数量,便可以达到测速的效果(v=s/t),通过对脉冲信号的累加,和编码器的码盘的周长(转一圈对应距离)  便可以达到计算行走距离的效果(s=n*d)


编码器信号: 

A 脉冲输出 

B 脉冲输出 

Z 零点信号 当编码器旋转到零点时,Z信号会发出一个脉冲表示现在是零位置 表示编码器转了1圈,可用来记录编码器转了多少圈,从而知道运行距离

VCC 电源线

GND 地线

编码器线数:

编码器的线数 ,是说编码器转一圈输出多少个脉冲,,,如果一个编码器是500线,说明这个编码器转一圈对应的信号线会输出500个脉冲, A B两相转一圈发出的脉冲数一样的,不过存在90°相位差


线数越高代表编码器能够反应的位置精度越高


编码器原理:

增量式编码器有两个脉冲输出,A相和B相,并且两个相位永远存在90°相位差。 如果两个信号相位差为90度,则这两个信号称为正交。由于两个信号相差90度,因此可以根据两个信号哪个先哪个后来判断方向、并且可以根据AB相脉冲信号数量测得速度,位移等,


编码器正反转:

这里写图片描述

正转的时候信号线A先输出信号,信号线B后输出  A相超前B相90度  证明是正转


反转的时候信号线B先输出信号,信号线A后输出 B相超前A相90度 证明是反转


STM32定时器编码器模式

STM32的编码器模式共有三种:


 仅在TL1计数(A相)

 仅在TL2计数(B相)

 在TL1和TL2都计数(A相和B相都计数)

 

仅在TL1计数(A相)

               

TI2(B相)为高电平时:


1时刻: TI1(A相)下降沿,  则向上计数(正转)。


2时刻:TI1(A相)上升沿,   则向下计数(反转)


TI2(B相)为低电平时:


3时刻: TI1(A相)上升沿,  则向上计数(正转)。


4时刻:TI1(A相)下降沿,   则向下计数(反转)


仅在TL2计数(B相)

TI1(A相)为高电平时:


1时刻: TI2(B相)上升沿,  则向上计数(正转)。


2时刻:TI2(B相)下降沿,   则向下计数(反转)


TI2(B相)为低电平时:


3时刻: TI2(B相)下降沿,  则向上计数(正转)。


4时刻:TI2(B相)上升沿,   则向下计数(反转)


在TL1和TL2都计数(A相和B相都计数)

一个脉冲信号周期完成4次跳变。精度提高


1时刻:TI2为低电平,TI1上升沿跳变,计数器向上计数;


2时刻:TI1为高电平,TI2上升沿跳变,计数器仍然向上计数;


3时刻:TI2为高电平,TI1下降沿跳变,计数器仍然向上计数;


4时刻:TI1为低电平,TI2下降沿跳变,计数器仍然向上计数。

 


毛刺:只有一个相位脉冲   过滤掉 编码器转动过程中可能产生的毛刺过滤掉


计数器向下计数原理相同   看图即可很好理解。


计数器向下计数:


A下降沿,B低电平

B下降沿,A高电平

B上升沿,A低电平

A上升沿,B高电平


上升沿与下降沿参看 《外部中断----高低电平触发,(边沿触发)上升沿触发和下降沿触发区别》


注意事项:

需要增加测量的精度时,可以采用4倍频方式,即分别在A、B相波形的上升沿和下降沿计数,分辨率可以提高4倍,

如果只是测速,不要求方向,那么只需要用单片机随意选择一个信号线就行了,,然后定时器边沿触发,检测脉冲计数即可

一般是定时器的通道1和2才能作为编码器输入口,对应编码器输出的两相。

GPIO配置为配置为上拉输入模式

一个定时器做一种工作,如果你配置了编码器模式,那么剩下的通道就不能配置其他模式

两相计数模式下,  读出来数需要/4          一个脉冲信号对应四次计数   

 

编码器配置标准外设库

TIM_EncoderInterfaceConfig,它就是编码器接口的配置函数。简单的只需要配置该函数,使能TIM,即可实现采集编码器上面的信息


void TIM_EncoderInterfaceConfig(TIM_TypeDef* TIMx, uint16_t TIM_EncoderMode,

                                uint16_t TIM_IC1Polarity, uint16_t TIM_IC2Polarity)

TIMx参数就是使用哪个定时器作为编码器接口的捕捉定时器。


TIM_EncoderMode参数是模式,是单相计数(仅在TL1计数或仅在TL2计数)还是两相计数(在TL1和TL2都计数)。


TIM_IC1Polarity和TIM_IC2Polarity参数就是通道1、2的捕捉极性。


 

相关寄存器配置

● 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寄存器,计数器使能) 


 


如果计数器只在TI2的边沿计数,则置TIMx_SMCR寄存器中的SMS=001;如果只在TI1边沿计数,则置SMS=010;如果计数器同时在TI1和TI2边沿计数,则置SMS=011 


编码器模式功能:

  stm32f407中定时器1、2、3、4、5、8提供编码器接口模式 

  可以对输入信号TI1,TI2进行滤波处理,数字滤波器由事件器组成,每N个事件才视为一个有效边沿,可以在TIMx_CCMR1、TIMx_CCMR2中的IC1F位域设置      也就是可以设置每产生几次脉冲才视为1次有效  

各个值的计算:

转速计算方法:用捕获值(一秒内输出的脉冲数)/编码器线数(转速一圈输出脉冲数)/电机减数比(内部电机转动圈数与电机输出轴转动圈数比,即减速齿轮比    没有则不用除)


运动距离计算:输出的总脉冲数 / 编码器线数*编码器齿轮周长


所转角度计算:    输出的总脉冲数 / 编码器线数 *360     或    溢出中断次数*360+当前计数值 


转动方向: 方向在定时器CR1的DIR位里   dir=(TIMX->CR1 & 0x0010)>>4;     //取方向标志位

if(dir > 0)  //向下计数     else     //向上计数


 


那么我们直接看代码:


定时器初始化设置


void TIM3_Int_Init() 

{

    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;

    TIM_ICInitTypeDef TIM_ICInitStructure;

    NVIC_InitTypeDef NVIC_InitStructure;

 

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); 

 

//定时器设置-------------------------------------------------------------    

  TIM_TimeBaseInitStructure.TIM_Period = 359*4;  //重装载值   

    TIM_TimeBaseInitStructure.TIM_Prescaler=0x0;  //预分频

    TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数

    TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1; //时钟分割

 

    TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);//初始化TIM3

 

//编码器模式设置--------------------------------------------------------------                 

 

    TIM_EncoderInterfaceConfig(TIM3,TIM_EncoderMode_TI12,TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);//计数模式3

 

    TIM_ICStructInit(&TIM_ICInitStructure); //将结构体中的内容缺省输入

    TIM_ICInitStructure.TIM_ICFilter = 0;//滤波器值

    TIM_ICInit(TIM3, &TIM_ICInitStructure);  //将TIM_ICInitStructure中的指定参数初始化TIM3

//溢出中断设置--------------------------------------------------------------  

    TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE); //允许TIM3溢出中断

 

    NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn; 

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x01; 

    NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x01; 

    NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;

    NVIC_Init(&NVIC_InitStructure);

 

 

  TIM_SetCounter(TIM3,0); //TIM3->CNT=0

  TIM_Cmd(TIM3, ENABLE); 

}

重装载值:    (编码器线数-1 ) *4                因为我们是两相计数,一个脉冲信号4次计数,所以乘4,保证转完1整圈才触发中断


中断设置:


int circle_count=0;//圈数

void TIM3_IRQHandler(void)

{

    if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET)

    {       

        if((TIM3->CR1>>4 & 0x01)==0) //DIR==0

            circle_count++;

        else if((TIM3->CR1>>4 & 0x01)==1)//DIR==1

            circle_count--;

    }

    TIM_ClearITPendingBit(TIM3,TIM_IT_Update); 

}

各个值的计算:


脉冲数:  TIM_GetCounter(TIM3)/4  


int angle=0;  //转过总角度

int Realyangle = 0;  //当前实际角度 0~360

int Distiance=0;   //运行距离

extern int circle_count;   //转过圈数

 

 

Realyangle = TIM_GetCounter(TIM3)/4/360 ;      //先除4   最后除编码器线数

 

angle=Realyangle +circle_count*360;//当前角度

 

 

Distiance = angle/360*编码器齿轮周长  + circle_count*编码器齿轮周长


关键字:STM32】 引用地址:【STM32】 定时器---正交解码编码器模式详解

上一篇:STM32驱动URM04超声波测距模块
下一篇:STM32F4 CAN2只能发送无法接收问题解决

推荐阅读最新更新时间:2024-11-10 18:22

介绍如何通过意法的STM32 MCU实现用DMA完成多通道的AD采样功能
在嵌入式产品中有时候需要实现对外部的模拟量进行采样处理和记录,而这就需要使用到ADC功能,将外部的模拟量转换成数字量。而在复杂的嵌入式产品中,往往需要使用多路AD采样,例如在智能家居产品,电池电量检测,热敏温度传感器,烟雾传感器,气敏传感器等都是可以使用ADC来实现采样的。在本文章,将会介绍如何通过意法的STM32 MCU实现用DMA完成多通道的AD采样功能。 什么叫ADC ADC即模拟数字转换器(英语:Analog-to-digital converter)是用于将模拟形式的连续信号转换为数字形式的离散信号的一类设备。一个模拟数字转换器可以提供信号用于测量。与之相对的设备成为数字模拟转换器。 影响AD采样的因素有哪些 分
[单片机]
介绍如何通过意法的<font color='red'>STM32</font> MCU实现用DMA完成多通道的AD采样功能
STM32输出PWM
  STM32系列基于专为要求高性能、低成本、低功耗的嵌入式应用专门设计的ARM Cortex-M3 内核。按性能分成两个不同的系列: STM32F103 “增强型”系列和STM32F101“基本型”系列。增强型系列时钟频率达到72MHz,是同类产品中性能最高的产品。   基本型时钟频率为36MHz,以16位产品的价格得到比16位产品大幅提升的性能,是16位产品用户的最佳选择。两个系列都内置32K到128K的闪存,不同的是SRAM的最大容量和外设接口的组合。时钟频率72MHZ时,从闪存执行代码,STM32功耗36mA,是32位市场上功耗最低的产品。   脉冲宽度调制(PWM),是英文“Pulse Width Modulat
[单片机]
stm32 hal 模拟i2c
管脚配置(我是用的是PA9和PA10): //i2c.h #include stm32f0xx_hal.h #define GPIO_PORT_I2C GPIOA // GPIO端口 #define I2C_SCL_PIN SCL_Pin // 连接到SCL时钟线的GPIO #define I2C_SDA_PIN SDA_Pin // 连接到SDA数据线的GPIO /* 定义读写SCL和SDA的宏 */ #define I2C_SCL_1() GPIO_PORT_I2C- BSRR = I2C_SCL_PIN // SCL = 1 #define I2C_SCL_0() GPIO_
[单片机]
<font color='red'>stm32</font> hal 模拟i2c
STM32单片机一般有几种调试方式(stm32与TDC SPI通信调试)
STM32单片机介绍 STM32单片机是由意法半导体(STMicroelectronics)公司开发和生产的一系列32位ARM Cortex-M内核的微控制器。它们广泛应用于工业自动化、消费电子、通信、汽车电子和物联网等领域。 STM32单片机系列涵盖了多个系列和型号,以满足不同应用需求和性能要求。常见的系列包括: 1. STM32F系列:基于ARM Cortex-M4或Cortex-M7内核,具有强大的处理能力和丰富的外设资源,适用于高性能应用。 2. STM32L系列:基于ARM Cortex-M0+或Cortex-M3内核,具有低功耗特性和优异的能效表现,适用于电池供电和低功耗应用。 3. STM32H系列:基于ARM
[单片机]
<font color='red'>STM32</font>单片机一般有几种调试方式(<font color='red'>stm32</font>与TDC SPI通信调试)
关于STM32 DMAMUX模块具体的应用示例代码
个人也发现,虽然STM32片内的DMAMUX不是什么新模块,似乎还是很多人并不太熟悉。这里借机聊聊这方面的内容,重点演示相关功能的实现,以供参考。 其实,DMAMUX作为一个外设模块,操作它并不需要添加太多用户代码,尤其是当我们基于STM32CubeMx进行配置时。它的主要功能就是为各种DMA请求做DMA传输通道的灵活调度与安排,并配合DMA使用,我们可以把它看成DMA控制器的前端拓展。 DMAMUX模块大体上由DMA请求转发通道和DMA请求发生器组成,其中每个DMA请求转发通道还配有同步控制单元。DMA请求发生器可以基于某些事件产生DMA请求申请DMA传输。至于同步控制单元,可以简单理解为每个DMA请求最终是否被转发出去的一
[单片机]
关于<font color='red'>STM32</font> DMAMUX模块具体的应用示例代码
STM32仿真按键控制led灯源程序
刚学习 课上做的一个小实验 保存一下 在GPIOC口,分别接有一个开关K1和两个指示灯LED1和LED2。两个灯一亮一灭,每按一下开关,两个灯的亮灭状态翻。 单片机源程序如下: #include stm32f10x.h #include led.h #include key.h int main(void) { u8 key; LED_Init(); KEY_Init(); while(1){ key = KEY_Scan(); switch(key){ case WK_UP: LED1=!LED1, LED0=!LED0; break; }
[单片机]
<font color='red'>STM32</font>仿真按键控制led灯源程序
基于STM32的DS18B20驱动
#include ds18b20.h #include delay.h short tmp_arg; //温度平滑滤波 //复位DS18B20 void DS18B20_Rst(void) { DS18B20_IO_OUT(); //SET PG11 OUTPUT DS18B20_DQ_OUT=0; //拉低DQ delay_us(750); //拉低750us DS18B20_DQ_OUT=1; //DQ=1 delay_us(15); //15US } //等待DS18B20的回应 //返回1:未检测到DS18B20的存在 //返回0:存在 u8 DS18B20_Check
[单片机]
Stm32 debug停留在"BKPT 0xAB"或者"SWI 0xAB"的解决办法
一、、背景:   曾经在工作中接触过STM32一段时间,但没有深入的去学习,只是用前辈搭建好的模型来实现一些功能罢了,俗话说的好,大树底下好乘凉,开发确实轻松了,可是不深究点,又觉着心里不踏实,然而也一直没花时间去深究。刚好,最近需要重新使用STM32,完全自己开发,没想到今天一上来就让我碰上个不小的问题,废话不多说,进入正题。 二、正文:   在使用串口的时候,代码可以正常编译,没有报任何错误,烧录进MCU内,就是看不到程序正常运行的现象,而把串口部分注释掉就没问题。进入调试模式,发现代码停在 BKPT  0xAB 这里,并不是死循环,按下全速运行键“F5”,代码会立马在该段被终止,不会继续往下跑,这里说明了main函数都没
[单片机]
<font color='red'>Stm32</font> debug停留在
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved