发了第一篇帖子后,我突然就爱上了发帖,我发现我在发帖的时候,也在总结我学到的东西,并且看着密密麻麻的字,就有一种成就感。更重要的是,能把自己的理解讲给读这篇帖子的人并且帮助到他们我觉得非常的开心。但是,我还是强调,本人真的菜,所以有些地方地方讲错,希望能得到理解。 最近在学习带霍尔传感器编码器的直流减速电机测速原理,看了网上很多帖子,但是能让我感觉写的好的帖子真的很少。很多帖子要不是放个不知道什么芯片写的源码,随便讲解几句,然后下载代码后发现代码写的很乱,阅读性很差,要不就是各种帖子你抄我我抄你,都是纸上谈兵,看了帖子,原理是懂了,但是对于一些细节的东西什么都没讲,然而这些细节往往是初学者们最让人不解的地方。我承认对于一些大佬而言,看了这些很快就能懂,但是对于一些初学者而言,就真的很头痛,并且这样一份资料会浪费很多学习的时间。
所以,我写下这篇帖子也是想帮助这些初学者,我的代码都是用原子的探索者写的,这样大家都会好看懂一些。看代码时,对着我的讲解来看,我相信你们很快就能懂。但是唯一不足的就是,我可能讲解概念性原理的一些东西可能很少,因为我的表达能力实在是很差,所以在看这篇帖子时如果你连正交编码原理是什么都不知道的人就先去看看别人的帖子怎么讲的,虽然我上面说一些帖子都在纸上谈兵,但是他们纸上谈兵谈的还是可以的,哈哈,一些原理性东西还是讲的很清晰的。废话不多说,开始正题了。
先讲1个概念:
1.编码器线数: 就是旋转一圈你的A(B)会输出多少个脉冲 ,这里的A B就是上面的输出脉冲信号线,它们转一圈发出的脉冲数一样的,不过存在90°相位差 通常都是360线的 线数越高代表编码器能够反应的位置精度越高。
首先大家第一步就是了解编码器的配置,而其中最关键就是叫做stm32编码器模式配置的东西,就是这一串TIM_EncoderInterfaceConfig(TIM3,TIM_EncoderMode_TI12,TIM_ICPolarity_Rising,TIM_ICPolarity_Rising );编码器模式究竟是什么,不懂得就去百度看看别人怎么讲的。而其中用的是编码器模式3,编码器模式3就是A相和B相的上升沿和下降沿你的定时器都会计数一次,而你用模式1或者2,定时器只会计数A相或者B相的上升沿,然而模式3就是你A相和B相的上升沿和下降沿都会计数一次。假如你的电机线数是360,就是转一圈产生360个脉冲,而你用了编码器模式3后,就产生360*4个脉冲了。有人可能就问,为啥要这样呢,那是因为这样能提高分辨率,你想,A相和B相是一个相差90度的脉冲,意思就是说每90度就有一个上升沿或者下降沿,这样就是每90度计数一次,而你用模式1或2时,你就是360度才计数一次,假如你有个段时间编码器输出不正常,明明A相和B相只相差90度,而这时你信号不稳定,这段时间就会计数不正常,你用了编码器模式3后,就会把误差缩减4倍,不知道我讲清楚没,要是没懂,在下面留言,我再讲。
然后,我再讲下我觉得很重要的东西,因为这个问题让我头痛很久,最后找了很多帖子和资料才懂了。就是编码器模式配置时,定时器的重装载值对计数有什么影响。相信看过很多帖子的人会知道一个四倍频的东西,就是它定时器的重装载值为(线数-1)*4,然后又有很多代码他的重装载值为65535-1,还有少数的代码是一些其他值,当时我看到这些代码我就很疑惑,为何他们重装值不同,然而最后他们都说可以完成测速,我试过,我改变重装值,计数会不一样。最后,我终于看到一篇帖子,在那篇帖子中后面有人问楼主关于重装值的问题,然后就这位楼主就讲了关于重装载值对计数的影响。我放下这篇帖子的网址,我建议不懂的人都可以看下https://blog.csdn.net/wxc971231/ ... 322957#commentsedit 这里面的重装载值就是你最多能记录A相和B相的脉冲数,假如你的电机转1圈产生800个脉冲,而你的重装载值为1,就是说你电机转一圈,你的定时器会溢出800次,假如你重装载值为400,那么你电机转一圈,你的定时器就会溢出2次。这里大家可能就明白为何四倍频时那里的重装载为(线数-1)*4,你想,我前面讲了,你用编码器模式3,产生的脉冲数就是你的线数*4,这样意思就说,你转一圈,产生的脉冲数恰好是你定时器溢出的时候。这样,假如你定时器开启溢出中断,这样溢出一次就代表你电机转了一圈,而你这时,再用另一个定时器定时为1s,计录1s内溢出的次数,这样就能得到你的电机1s转过的圈数了。当然只是这样测速的话,得到的数据误差会很大,因为这种方法只能测到整圈数,万一你的转数是每秒1.5圈呢,这样这种方法就不行了。还是举例说明,假如你的重装载值为(360-1)*4,这样你1秒转1.5圈就计数360*6次,然而你的重装值是(360-1)*4,所以这时你的定时器只溢出一次,并且此时的定时器计数值为360*2,转换成脉冲数也就是360*6,你想你的电机线数是360,用的编码器模式3,就是转一圈产生360*4个脉冲,这样的速度就为(360*6)/(360*4),这样精度就会好很多。至于怎么具体得到脉冲值的,大家可以看下我的代码,如果不懂,可以在下面问我。我建议你要测速定时还是不要1秒,因为我觉得定1s记录的脉冲累计误差可能会比较大,所以你把定时器定时定小点,比如5ms,这样你后面在转换下就行了。最后,再提下为何一些代码重装载值65535也行,你想,你转一圈,产生360*4个脉冲,假如你1秒转8圈,也就是1秒产生360*4*8个脉冲,只要这个值不超过你的溢出值,那么你只需要在最开始时,将计数器清零,然后开始计数,计时1秒后,记下此时的脉冲数,又将计数器清零,然后再用我上面的计算方法就可以了。记住,你的重装值其实为多少都可以,只是别人用65535和(360-1)*4只是计算时方便而已,我再举个例子,假如你重装载值为2,你转一圈产生360*4个脉冲,就是说你转一圈产生360*2次溢出,你用再一个定时器定时1秒,记录1s被溢出的次数,假如溢出360*6次,这样的速度就是(360*6)/(360*4)。
如果还有不懂的,欢迎下面留言,如果有人发现我哪里讲错了,希望有人也给我说下。
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------分割线
2020.3.15
我再通俗的讲下带编码器的直流减速电机测速原理。首先我们得明白一个东西,电机旋转一圈会产生脉冲,而一圈究竟能产生多少个脉冲,这是由电机的编码器线数决定,线数越高,精度就越高。至于为什么会产生脉冲,这个就是编码器这个传感器的原理,这个我不讲。
既然电机旋转一圈能产生脉冲,那么我们就能记录一段时间产生的脉冲数来计算速度。而单片机怎么去检测脉冲并且记录脉冲的个数则是我们的重点。在这里我想提一个东西——定时器。我们是如何用定时器定相应的时间的?首先就是设置预分频系数把主频时钟分频,假设主频时钟168MHZ,你预分频系数为168,则分频后的时钟频率就为1MHZ(频率的倒数就是周期,这里即1us),此时TIMx_CNT 寄存器,即定时器的计数器就是按照这个频率(也就是10us)递增的。假如你重装载值为10,则你定时器最终定的时间就为10us。
从上面的例子可以看出,此时TIMx_CNT 寄存器的值递增是由内部时钟频率造成的,而时钟频率无非就是脉冲。好,那我们岂不是可以用这个寄存器去记录编码器产生的脉冲了?的确就是这样,但是怎么把原本是因为内部时钟递增的TIMx_CNT 寄存器改为是因为外部时钟递增呢?这就是我们为什么需要用到正交编码模式了。至于为什么用了正交编码模式就可以了,这个我就不知道了,反正我就知道用了正交编码模式就可以实现这样的过程。
以前我讲了重装载值对我们的影响,那现在你们是否就清楚了预分频系数的我们的影响了?原来预分频系数分的内部时钟,现在分频系数分的就是外部时钟。那我代码里为何预分频系数是为1?为其他数可不可以?当然可以,但是没必要。因为你现在就是要记录电机旋转一圈产生的真实的脉冲数,如果你预分频系数为2,假设电机旋转一圈产生200个脉冲,则此时你单片机只能记录100个脉冲了。
实际啊,其实直流减速电机测速度的本质很简单,以前我们定时器初始化设置重装载值和与分频系数时是基于内部时钟而定的。而现在是基于外部时钟而定的,这个外部时钟就是编码器产生的脉冲。
顺带提下,我这份代码只能测正转或者反转,如果想正反转都能测(当然实际工程就需要这样),去看下17楼,那里我讲了下思路。这是其中一个思路,这里我还想说下另外一个思路,通过定时器的TIMx_CR寄存器的第四位DIR标志位来判断。 |