【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);//计数模式3TIM_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=0TIM_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==0circle_count++;else if((TIM3->CR1>>4 & 0x01)==1)//DIR==1circle_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定时器---正交编码器模式详解
编码器分类: 按工作原理:光电式.磁电式和触点电刷式 按码盘的刻孔方式:增量式和绝对式两类 由于博主接触面还不是很广,一共就用过两个种类的编码器,都是属于光电的 差分编码器:一般由8根线连接 信号线分 ...
- STM32三种BOOT启动模式详解(全网最全)
一.三种boot启动模式 一般来说就是指我们下好程序后,重启芯片时,SYSCLK的第4个上升沿,BOOT引脚的值将被锁存.用户可以通过设置BOOT1和BOOT0引脚的状态,来选择在复位后的启动模式. ...
- STM32学习笔记-大小端模式详解
小端模式(Little Endian) 小端模式(Little Endian),也称为Intel顺序.最低有效字节,首先存储. 例如:int16数据0x1234在地址单元中的存储顺序为 例如:int3 ...
- STM32开发 -- 低功耗模式详解(2)
如需转载请注明出处:https://juyou.blog.csdn.net/article/details/98631012 上一篇文章 STM32开发 – 低功耗模式详解(1) 简单的总结了一下低功 ...
- 运动控制器PSO位置同步输出(二):PSO模式详解
本节我们主要去讲解一下多种PSO模式原理和使用的讲解,用户可根据实际需求灵活选择触发模式. 一.硬件说明 硬件选型的首要要求是支持PSO功能,再分析PSO的应用场合和轴数等选择具体的型号.本例以ZMC ...
- Android Doze and App Standby模式详解
Android Doze and App Standby模式详解 来源:腾云阁 https://www.qcloud.com/community Optimizing for Doze and Ap ...
- 关于stm32的正交解码
关于正交解码,我先解释何为正交解码,,,,其实名字挺高大上的,,,,还是先说编码器吧 看一下我用过的一种编码器 编码器的 线 数 ,是说编码器转一圈输出多少个脉冲,,,如果一个编码器是500线,,,说 ...
- ST MCU_GPIO的八种工作模式详解
GPIO的八种工作模式详解 浮空输入_IN_FLOATING 带上拉输入_IPU 带下拉输入_IPD 模拟输入_AIN 开漏输出_OUT_OD 推挽输出_OUT_PP 开漏复用输出_AF_OD 推挽复 ...
- V90 PN伺服EPOS回零+点动JOG+MDI+程序步具体工作模式详解
V90 PN伺服EPOS回零+点动JOG+MDI+程序步具体工作模式详解 1. 回零 增量式编码器主动回零 在配置回零参数界面,选择回参考点方式: 0:信号REF 即直接设定参考点方式(将当前位置 ...
最新文章
- BinaryTree-学习二叉树的Python库
- TerryLee技术专栏WCF后传正文 WCF后传系列(3):深入WCF寻址Part 3—消息过滤引擎...
- grails 转为java_创建一个grails项目,然后转成maven项目
- Oracle/PLSQL Repeat Until Loop
- swift基础之_swift调用OC/OC调用swift
- DropDownList如何绑定DataTable,如何绑定DataSet
- SharePoint:扩展DVWP - 第8部分:挂接了工作流列表表单操作
- Manjaro/Arch 软件配置安装
- python能做什么工作知乎-python能做什么知乎
- python怎么安装scrapy_Python-2.7安装Scrapy 1.0爬虫实例
- 《浪潮之巅》读书笔记
- iPhone中国移动收不到彩信,设置方法?
- cypress初识--看完就可以写一个简单web自动化脚本了!
- 消息中间件(消息队列)
- 网页设计图片向上浮动_网页设计与制作(网页设计、制作与美化)
- python平安夜代码加文案
- 32位程序在Windows上的内存问题
- 2022-C4-AI-基于飞桨的智慧书桌系统
- HanLP 部署及NLP+ML双生树思维导图
- R-基本统计分析--独立、相关性及其检验
热门文章
- 查看pcl版本 linux,成功安装 linux pcl (1.8.1版本) python-pcl
- 使用kafka解决zookeeper is not a recognized option when executing kafka-console-consumer.sh报错
- jieba自定义分词规则与多进程切词
- pytorch构造IterableDataset,流式读取文件夹,文件夹下所有大数据文件,逐个文件!逐行读取!(pytorch Data学习四)
- 解决Dataframe删除操作时警告:SettingWithCopyWarning:A value is trying to be set on a copy of a slice from a...
- mysql上一条语句成功_mysql : 获取上一条insert语句
- 贵阳学python_python学习类
- Vue 犯罪指南:TypeError: Right-hand side of 'instanceof' is not an object
- Android 实践项目开发二
- (二)oracle的SGA