STM32 HAL库自学记录:旋转编码器的使用指南

STM32 HAL库自学记录-旋转编码器的使用

  • 前言
  • 使用工具
  • 旋转编码器原理介绍
  • 方法一 定时器中断方式(实质就是外部中断)
  • 方法二 定时器方式
  • 前言

    通过本文可学会两种实现判断旋转编码器正转反转的方法,可根据自己的应用场景来选择使用哪种方法。

    使用工具

    1、芯片:STM32F103RCT6
    2、STM32CubeMx软件
    3、IDE: MDK-Keil软件
    4、旋转编码器模块
    5、XCOM V1.4串口软件

    旋转编码器原理介绍


    图中C端为GND。
    方向:A相和B相相差一个相位,一般来说是90°。A相信号在前表示正转,B相信号在前表示反转。

    上图是模块的原理图,实物图如下:

    方法一 定时器中断方式(实质就是外部中断)

    cubeMX配置:
    首先是时钟配置,我这边是有外部时钟的,所以选择了使用外部时钟,具体配置如下图:
    接下来选择自己要使用的引脚,外部中断和定时器输入捕获中断在这个实验中都是一个效果,偷懒就建一个工程吧。记得TIM4的combined channels要选择encoder mode,他就会默认使用了TIM4的channel1和channel2。记得选择NVIC把TIM4的中断打开。

    我这个里面还配置了两个LED灯和一个PB5引脚,PB5引脚是为了连接旋转编码器的按键功能。此外还配置了一个串口,用来打印的。这里就不展开讲解了。

    这边看下project manager的配置都没有问题的话就可以点击generate code来生成工程和代码了。

    在主函数中添加:

    HAL_TIM_IC_Start_IT(&htim4, TIM_CHANNEL_1);//开启输入捕获且捕获后进入中断
    

    在main.c中添加中断服务函数,我这边添加的定时器中断服务函数,要是使用外部中断就添加外部中断服务函数即可。

    void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)//定时器捕获中断回调函数
    {
    	
    	if(htim == &htim4)
    	{
    		HAL_TIM_IC_Stop_IT(&htim4, TIM_CHANNEL_1);//关中断,防止重复触发
    		if (HAL_GPIO_ReadPin(EC11_B_GPIO_Group, EC11_B_GPIO_PIN) == GPIO_PIN_SET)//判断B相电平是否为高
        		{
           			HAL_GPIO_TogglePin(GPIOA, LED0_Pin);//LED0翻转
       		 	}
        	else
        		{
          			HAL_GPIO_TogglePin(GPIOD, LED1_Pin);//LED1翻转
       			 }
      		 HAL_TIM_IC_Start_IT(&htim4, TIM_CHANNEL_1);//开启输入捕获且捕获后进入中断
        }
    }
    

    主循环:

      while (1)
      {
    	    HAL_Delay_ms(1000);
    	    if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_5) == 0 )//旋转编码器按键按下后,两个LED灯同时翻转
    	      {
    		      HAL_Delay_ms(10);//去抖
    		      HAL_GPIO_TogglePin(GPIOA, LED0_Pin);
    		      HAL_GPIO_TogglePin(GPIOD, LED1_Pin);
    	      }
      }
    

    方法二 定时器方式

    cubeMX的配置和上面一样,只是修改了程序使用不同的方法。

    在主函数中加上下面这两句话:

      __HAL_TIM_SET_CAPTUREPOLARITY(&htim4, TIM_CHANNEL_1, TIM_INPUTCHANNELPOLARITY_RISING); //开启输入捕获中断,设置下降沿触发中断
      HAL_TIM_Encoder_Start(&htim4,TIM_CHANNEL_ALL);
    

    主循环的代码:

      while (1)
      {
    	    HAL_Delay_ms(1000);
    		ecValue = __HAL_TIM_GET_COUNTER(&htim4) ;
    		direction = __HAL_TIM_IS_TIM_COUNTING_DOWN(&htim4); 
    	    printf("Count val = %d, direction = %d\r\n",ecValue,direction);
    	    if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_5) == 0 )
    	      {
    		      HAL_Delay_ms(10);
    		      HAL_GPIO_TogglePin(GPIOA, LED0_Pin);
    		      HAL_GPIO_TogglePin(GPIOD, LED1_Pin);
    	      }
      }
    

    运行结果如下:
    Count val显示了当前计数器的数值,direction为0和1代表了是顺时针还是逆时针旋转。这是直接读了STM32中的寄存器,因为STM32的定时器本身可以有encoder模式,采用读寄存器的方式可以更少的利用MCU的资源。

    物联沃分享整理
    物联沃-IOTWORD物联网 » STM32 HAL库自学记录:旋转编码器的使用指南

    发表评论