4416| 1
|
[项目] 带编码器的直流减速电机——基于STM32F407 |
1 创造力 | 回复本帖可获得 1 创造力奖励! 每人限 1 次 |
本帖最后由 MCL 于 2021-11-5 16:23 编辑 首先,什么是编码器? 编码器是将信号或数据进行编制、转换为可用以通讯、传输和存储的信号形式的设备。在这里,编码器就是能够将电机的转动信息(比如转速、转动角度等)转换为脉冲信号的设备。按照原理可分为(常见的)光电编码器(光学式)和霍尔编码器(磁式)。 接着,编码器的作用以及为什么要用编码器? 如上所述,编码器能够将电机的机械几何位移转化为脉冲信号或数字量。也就是说,有了编码器,我们通过检测编码器输出的脉冲信号,就能获取电机转动角度、转速等相关信息。这样我们不但能定性的控制电机的转向、转速,还能定量的测量。 那么,编码器的原理是什么以及怎么运用呢? 简单来说,就是电机带动码盘转动,码盘的结构使得当电机在转动时会产生A、B两相的脉冲信号,且这两路脉冲信号的相位差为90度(即正交)。如下图: 由于A、B信号正交,因此可以根据两个信号哪个先哪个后来判断方向,根据每个信号脉冲数量的多少及每圈电机产生多少脉冲数就可以算出当前行走的距离,如果再加上定时器的话还可以计算出速度。 好了,现在我们的处境是,我们有一个带编码器的直流减速电机,我们知道当电机转动的时候,它会产生A、B两相正交脉冲信号,通过检测脉冲信号我们就可以获取电机的运动状况。 那么,我们通过什么手段来检测脉冲数呢? 其中一种思路是,我们通过定时器的输入捕获或者GPIO引脚的外部中断来检测边沿变化,以此来检测脉冲数。这方法好像没毛病,当电机正常运转时行得通。但是如果电机输出的脉冲信号出现了毛刺呢?这样误差就来了,怎么办?通过软件编写算法来滤去毛刺似乎有点困难,于是我们想到通过硬件来处理这个毛刺。(而STM32正好有硬件编码器,nice!) 这里的脉冲输入是一种特殊的输入捕获情况,因此stm32专门在定时器中提供了编码器模式,可大大简化解析过程。 STM32的编码器接口模式 在该模式下能计算电机输出脉冲信号的个数,且stm32根据其内部机制能够消除毛刺的干扰。 配置过程: 由于编码器接口模式是一种特殊的输入捕获,所以要先配置一下输入捕获(毕竟你要通过捕获边沿来检测脉冲)。在输入捕获过程中,我们把A6、A7复用为TIM3,作为输入捕获的引脚,对电机的A、B相脉冲进行输入捕获。 输入捕获配置完成之后再配置一下编码器模式就可以开始工作了。 于是紧接着我们来看看编码器模式的配置函数TIM_EncoderInterfaceConfig: 其输入参数中,TIMx就是输入捕获时设置的TIM3,polarity就分别是TI1和TI2的捕获极性(TI1是定时器输入通道1,TI2同理),即A、B两相信号的捕获极性(上升沿捕获或者下降沿捕获),重点来说说编码器的模式TIM_EncoderMode: 当模式选为TIM_EncoderMode_TI1时,计数器仅在TI1的边沿处计数 当模式选为TIM_EncoderMode_TI2时,计数器仅在TI2的边沿处计数 当模式选为TIM_EncoderMode_TI12时,计数器在TI1和TI2边沿处均计数 也就是说,模式1,我只以A相的脉冲信号为我的检测信号,TI2我就不管了。(B只是相对A滞后了90度,其它都是一样的,所以检测A就够了)。其它同理。 模式1和模式2显然就没什么差别了,那模式3前者有何不同呢? 这就涉及到网友们所说的编码器软件四倍频技术了: 如图,A、B两相正交信号,如果根据模式1或模式2对脉冲信号进行检测,假设我们上升沿捕获一次,那么图中的信号我们只检测到3个上升沿,也就是三个脉冲。但是如果采用模式3,对TI1和TI2检测上升沿,那么同一段时间我们检测到6个上升沿。如果下降沿也检测,那么一共就是12个边沿跳变。每个实际来的脉冲会被检测4次,同样是12/4=3个脉冲,但是这样的话精度大大提高了。 入口参量:(TIM3, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising ,TIM_ICPolarity_Rising); 通过这样配置,我们就完成了编码器软件的初始化。通过以上配置,我们完成了TIM3输入捕获的初始化以及编码器接口模式的相关配置,每来一个跳变沿,计数值变化一次。 至此,为了避免我们忘了初衷,现在我们来回顾一下我们最开始用编码器的初衷,前面我们说要用编码器来干嘛来着?获取电机转动角度、转速。 现在的处境是,我们通过STM32的TIM3的编码器模式,能够测出任意时刻的脉冲值了。现在要解决的就是如何将这个脉冲值转换成我们所要得到的信息(即转动角度、转速)。 首先,根据带编码器的直流减速电机的原理,显然无论电机的转速如何,每转产生的脉冲数是固定的。这里假设电机每转产生260个脉冲(具体数据各位自行查看自己的电机参数啦),那么只要我们用‘电机已产生的脉冲数’除以‘260个/转’,就可以得到电机转了多少圈,一圈即为360度,由此便可将脉冲数和转动角度联系起来。 这里要注意一点,由于我们用的是编码器模式3(也就是TIM_EncoderMode_TI12),我们得到的脉冲数是电机实际产生的脉冲数的四倍。则电机实际产生的脉冲数应为‘得到的计数值’除以4。于是,电机转动圈数为脉冲数除以260再除以4。 转动角度算出来了,转速呢?则是根据计数方向(递增计数或递减计数)来判断的,所以我们接下来的工作就是要搞清楚计数方向和编码器信号的关系。 让我们来看一下STM32的中文参考手册: 网上几乎在这张表的讲解上都是一带而过,真正能把这张表讲清楚的几乎没有。后来看到一个人在表格上做了类似上图的注释,我才终于搞懂了。 大家还记得我们前面提到的TIM_EncoderInterfaceConfig函数吗,里面有个参量就是选择模式的,对吧。让我们再来回顾一下: 注意到各模式后面的“xx edge depending on xx level”了吗?这就是上面这个表里的第二纵列所提到的“相反信号的电平”。 TIM_EncoderMode_TI1: Counter counts on TI1FP1 edge depending on TI2FP2 level,意思就是当选择模式1时,计数器根据TI2的电平高低来记录TI1的边沿信号。 这样说可能不好理解,我们来举个具体的例子: 如上图,电机转动时产生A、B两相信号通过TI1、TI2输入到TIM3。 假设我们选择的是模式1,即计数器仅在TI1的边沿处计数。我们观察TI1的上升沿,若此时对应的TI2信号处于低电平(下图红框),于是根据表格我们可以得到计数方向为递增,假设计数器递增时电机正向转动,则可判断此时电机正转。 再譬如,假设我们选择模式2,即计数器仅在TI2的边沿处计数。我们观察TI2的下降沿,若此时对应的TI1信号为高电平(下图蓝框),于是根据表格我们可以得到计数方向为递减,假设计数器递减时电机反向转动,则可判断此时电机反转。 也就是说,当以TI1为计数信号时,需要根据TI2的电平(也就是第二纵列的“相对信号的电平”)来进行判断是向上计数还是向下计数。TI2也同理。 e.g.如果“仅在TI1计数”,当TI1为“上升”沿(表中第三纵列),此时要根据TI2的电平来做判断。根据下图,可知当TI1为上升沿的时候TI2为低电平,则根据上表可得知计数器为向上计数。这在下图得到了验证。 再例如,如果“仅在TI2计数”时,当TI2为下降沿时,如果TI1为低电平,则为向上计数(上图左侧);当TI2为下降沿时,如果TI1为高电平,则为向下计数(上图中部);当TI2为上升沿时,如果TI1为高电平,则为向上计数(上图左部);当TI2为上升沿时,如果TI1为低电平,则为向下计数(图中中部); 至此为止,我们便实现了这样的操作:通过使用带编码器的直流减速电机产生正交脉冲,通过STM32的TIM的编码器模式对脉冲进行计数,根据计数方向和编码器信号的关系来判断电机转动方向,利用脉冲计数值来计算电机转动位移。 接下来是代码部分,有些容易让人迷惑的地方(至少是让我迷惑了很久): 输入捕获初始化时Period和Prescaler的作用: 这里的period即为计数器的重装载值,prescaler即为预分频系数。注意在编码器模式时,要把TIM理解为计数器,而不是定时器,这样的话,时钟信号就不是系统内部产生的,而是通过PA6、PA7输入到TIM3的TI1和TI2的。 有了这么个理解,再来看Period和Prescaler就不难理解了。Period就是计数器每一次能检测脉冲的最大值,每来一个脉冲计数值就加一,当计数值超过period就溢出中断。Prescaler就是对电机产生的脉冲信号进行分频的分频系数。比如当分频系数为2时,每当电机产生两个脉冲,stm32才认为接收到一个有效脉冲,计数值才加一。 以下为部分代码 //思路:初始化TIM的编码器模式后,在main函数里死循环不断的读取CNT的值,从而来获得电机的脉冲数数据,以此来计算电机的转速、所转圈数等参数 #include "sys.h" #include "delay.h" #include "usart.h" #include "pwm.h" #include "encode.h" #include "exti.h" #include "key.h" u32 pwm = 50000; int main(void) { 原文链接:https://blog.csdn.net/weixin_44692935/article/details/97419594 |
© 2013-2024 Comsenz Inc. Powered by Discuz! X3.4 Licensed