![ce78883e73c71ff9fd7f05c33dfd3162.png](https://img-blog.csdnimg.cn/img_convert/ce78883e73c71ff9fd7f05c33dfd3162.png)
通常在STM32芯片的通用TIMER或高级TIMER都带编码器功能,支持基于1路或2路输入的编码脉冲计数。我们一般外接正交编码器,使用2路输入。TIMER硬件基于2路输入的相差特征来确定计数方向并依据方向对计数器做递增或递减操作。
![f511f907d8783ad61e964f0afa333f93.png](https://img-blog.csdnimg.cn/img_convert/f511f907d8783ad61e964f0afa333f93.png)
正交编码器一般使用5根线连接,分别为A、B、 Z信号线及VCC和GND电源线。其中,A、B两路是存在相差的同频信号。Z信号即零点信号,当编码器旋转到某位置时,它会发出一个脉冲表示约定的零位。VCC、GND分别是电源线和地线。至于编码器线数,是指旋转一圈A(B)端会输出的脉冲个数 ,二者转一圈所发出的脉冲数相同,但存在90°相差。编码器的线数越高代表其能够反应的位置精度越高。
![55740806c1a418a1231b2d617a121df4.png](https://img-blog.csdnimg.cn/img_convert/55740806c1a418a1231b2d617a121df4.png)
关于STM32片内TIMER编码器接口的工作原理,这里就不介绍了。更多细节请参考STM32的相应系列的参考手册。这里想重点分享的是,如果手头没有正交编码器实物,如何来验证或体验TIMER的编码器接口功能呢?
其实,TIMER编码器处理单元就是对外来的两路同频但输出具有前后时序差的脉冲信号进行方向辨认后做TIMER计数器的递增或递减计数。既然手头没有编码器实物,我们何不利用STM32片内的TIEMR产生2路带相差的同频信号,再接到另一个支持编码器接口的TIMER不就OK了吗?
当然,使用STM32的TIMER产生2路带相差的同频信号,有多种方法。比方通过2个定时器主从级联、单个定时器使用OC toggle模式加以DMA辅助、利用非对称PWM输出模式来实现。
其中,前2种方法在STM32芯片里通用性好,每个STM32系列都支持。而非对称PWM输出模式虽然可以非常方便地实现带相差的同频输出信号,但不是所有STM32系列支持。当然,不支持的主要是ST推出得比较早的STM32系列,比方STM32F1\STM32F2\STM32F4这些老旧的系列,后来推出的STM32系列,比方STM32L4,STM32G4,STM32C0、STM32U5、STM32F7、STM32H7、STM32H5等都支持非对称PWM输出模式。
我这里采用非对称PWM输出模式并使用STM32L4开发板来演示实现过程。先用TIM1结合非对称PWM输出模式输出2路带相差的同频信号,然后连接到TIM2的编码器接口。另外,我还用了个按键【接到PC13】动态调整TIM1两路输出相差的前后关系,以观察TIM2计数器的计数变化情况,即递增还是递减计数。
![790cfac86df5c11359b68a6b8a0baedd.png](https://img-blog.csdnimg.cn/img_convert/790cfac86df5c11359b68a6b8a0baedd.png)
我先配置TIM1的CH1/CH2,实现2路带相差的PWM输出。【关于TIMER非对称PWM输出模式这里不介绍了,此处直接上配置。下面链接有相关文章介绍,或者自行研读STM32参考手册相关内容。】
![56636a9ae54438da87a9d3560d44ce58.png](https://img-blog.csdnimg.cn/img_convert/56636a9ae54438da87a9d3560d44ce58.png)
基于CubeMx配置后生成初始化工程,添加2行上图中的代码就可以输出了。
我这里使用ARM MDK IDE自带的逻辑分析仪就可以看到下面波形。2路波形分别从GPIOA_PIN8/GPIOA_PIN9输出。
![3c3cd28133b965852a32d05d13102c71.png](https://img-blog.csdnimg.cn/img_convert/3c3cd28133b965852a32d05d13102c71.png)
然后我将这两路输出分别连接到TIM2的编码器接口脚【GPIOA_PIN0、GPIOA_PIN1】。
我把有关TIM2编码器应用的CubeMx配置也截图出来供参考。【其中ARR可按需调整,为了便于查看效果,后来我将其改为1000了。这点不影响功能演示。】:
![e5aa5875f4e804ae49314185b2b8bbca.png](https://img-blog.csdnimg.cn/img_convert/e5aa5875f4e804ae49314185b2b8bbca.png)
然后,添加启动TIMER编码器功能的API函数。【API函数里启动了2个通道的输入捕获中断,我这里只保留通道1的而关闭了通道2的。即每次在TIM2通道1的捕获中断里读取其计数器的值。】
![f298c3d86d9be8010210214e4c53fc02.png](https://img-blog.csdnimg.cn/img_convert/f298c3d86d9be8010210214e4c53fc02.png)
编译、除错后运行,即可在IDE的逻辑分析仪上看到下面的结果。其中CNT_value就是TIM2的计数器动态值。目前看到的是TIM2的编码器接口针对当前2路输入信号进行周期计数。绿色和紫色是上面提到过的两路输入信号【因显示分辨率的关系下面相关图形变成单色方块了】。
![5d478bcb1a7a61eebdea772c03511387.png](https://img-blog.csdnimg.cn/img_convert/5d478bcb1a7a61eebdea772c03511387.png)
当然,我们可以通过按键来调整TIM1两路输出信号的相差时序,进而改变TIM2编码器计数的方向。不难看出下图中3个圆圈的地方就是切换计数方向的位置。
![d2fe593305e6818e9b19623f1a4d66c4.png](https://img-blog.csdnimg.cn/img_convert/d2fe593305e6818e9b19623f1a4d66c4.png)
我们还可以调整TIM1的参数改变输出给TIM2的信号频率。整个过程就是利用TIMER的非对称PWM输出模式构造2路带相差的编码器信号,从而让TIMER的编码器接口电路实现对外部编码输入信号的计数。实现这些基本功能之后,可以进一步研究应用中可能涉及的各种测量功能。
聊到这里,可能有人对上面逻辑分析仪的配置感兴趣。之前我在本公众号专门介绍过,这里简单就今天查看的几个变量的配置过程介绍下。
这里的CNT_value连续记录TIM2计数器的值,这里为Analog量。
Level_PA8记录GPIOA_PIN8的电平情况,1或0两个值之一,为Bit量。
Level_PA9跟Level_PA8是完全相同的数据类型,不过显示的是GPIOA_PIN9的电平。显然,逻辑分析仪配置里关于Level_PA9的显示算式的屏蔽数应该是0x00000200,右移位为9。我目前是在SYSTICK的毫秒中断里读取GPIOA->IDR的值即管脚电平到变量Level_PA8和Level_PA9的。
当然,使用ST公司免费的STM32CubeIDE也可以实现上面逻辑分析仪的功能,之前我也在本公众号里介绍过相关内容,有兴趣可以自行体验。左下角阅读原文处可以链接到STM32CubeIDE的下载站点。
*************************
往期话题阅读链接【点击即可阅读】:
1、巧用外设复位修改只读寄存器
2、巧用STM32片内RTC亚秒特性例
3、STM32非对称PWM输出模式应用示例
4、STM32CubeIDE调试工具使用演示
5、开启Cache后UART无法发送新数据
![b83b36afd9aa196edb65bae00aec2ff4.png](https://img-blog.csdnimg.cn/img_convert/b83b36afd9aa196edb65bae00aec2ff4.png)