打印
[应用相关]

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

[复制链接]
849|45
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 黑心单片机 于 2022-4-29 11:03 编辑

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



使用特权

评论回复
沙发
黑心单片机|  楼主 | 2022-4-29 10:57 | 只看该作者
编码器信号:
A 脉冲输出
B 脉冲输出
Z 零点信号 当编码器旋转到零点时,Z信号会发出一个脉冲表示现在是零位置 表示编码器转了1圈,可用来记录编码器转了多少圈,从而知道运行距离
VCC 电源线
GND 地线

使用特权

评论回复
板凳
黑心单片机|  楼主 | 2022-4-29 10:58 | 只看该作者
编码器线数:

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

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


使用特权

评论回复
地板
黑心单片机|  楼主 | 2022-4-29 10:58 | 只看该作者
编码器原理:

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


使用特权

评论回复
5
黑心单片机|  楼主 | 2022-4-29 10:59 | 只看该作者
编码器正反转:

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

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



使用特权

评论回复
6
黑心单片机|  楼主 | 2022-4-29 11:01 | 只看该作者
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相)下降沿,   则向下计数(反转)



使用特权

评论回复
7
黑心单片机|  楼主 | 2022-4-29 11:01 | 只看该作者
仅在TL2计数(B相)
TI1(A相)为高电平时:

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

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

TI2(B相)为低电平时:

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

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



使用特权

评论回复
8
黑心单片机|  楼主 | 2022-4-29 11:02 | 只看该作者
在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高电平



使用特权

评论回复
9
黑心单片机|  楼主 | 2022-4-29 11:03 | 只看该作者
注意事项:
需要增加测量的精度时,可以采用4倍频方式,即分别在A、B相波形的上升沿和下降沿计数,分辨率可以提高4倍,
如果只是测速,不要求方向,那么只需要用单片机随意选择一个信号线就行了,,然后定时器边沿触发,检测脉冲计数即可
一般是定时器的通道1和2才能作为编码器输入口,对应编码器输出的两相。
GPIO配置为配置为上拉输入模式
一个定时器做一种工作,如果你配置了编码器模式,那么剩下的通道就不能配置其他模式
两相计数模式下,  读出来数需要/4          一个脉冲信号对应四次计数   



使用特权

评论回复
10
黑心单片机|  楼主 | 2022-4-29 11:03 | 只看该作者
编码器配置标准外设库

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的捕捉极性。



使用特权

评论回复
11
黑心单片机|  楼主 | 2022-4-29 11:06 | 只看该作者
相关寄存器配置
● 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


使用特权

评论回复
12
黑心单片机|  楼主 | 2022-4-29 11:07 | 只看该作者
编码器模式功能:
  stm32f407中定时器1、2、3、4、5、8提供编码器接口模式
  可以对输入信号TI1,TI2进行滤波处理,数字滤波器由事件器组成,每N个事件才视为一个有效边沿,可以在TIMx_CCMR1、TIMx_CCMR2中的IC1F位域设置      也就是可以设置每产生几次脉冲才视为1次有效  

使用特权

评论回复
13
黑心单片机|  楼主 | 2022-4-29 11:08 | 只看该作者
各个值的计算:
转速计算方法:用捕获值(一秒内输出的脉冲数)/编码器线数(转速一圈输出脉冲数)/电机减数比(内部电机转动圈数与电机输出轴转动圈数比,即减速齿轮比    没有则不用除)

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

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

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


使用特权

评论回复
14
黑心单片机|  楼主 | 2022-4-29 11:09 | 只看该作者

那么我们直接看代码:

定时器初始化设置

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);
}


使用特权

评论回复
15
黑心单片机|  楼主 | 2022-4-29 11:09 | 只看该作者
各个值的计算:脉冲数:  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*编码器齿轮周长


使用特权

评论回复
16
Uriah| | 2022-10-8 12:14 | 只看该作者

来自单 片机内部的定时器和GPIO、串行通信设备UART等外设机器的中断被称为外部设备中断

使用特权

评论回复
17
Bblythe| | 2022-10-8 15:13 | 只看该作者

中断产生于单片机内部和外部的各种设备

使用特权

评论回复
18
Pulitzer| | 2022-10-8 18:12 | 只看该作者

多次检查也会给单片机带来负荷,对功耗不利

使用特权

评论回复
19
iyoum| | 2022-10-23 16:12 | 只看该作者
正交解码编码器模式使用位置积分器来跟踪编码器的位置; 根据转动轴的方向进行递增/递减计数。

使用特权

评论回复
20
albertaabbot| | 2022-10-23 16:27 | 只看该作者
可以直接通过读取tim相关寄存器的值,这个值就是编码值,这样的的操作最适合正交编码器的测距测速。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

58

主题

386

帖子

0

粉丝