EC11编码器编码使用

前要

关于EC11编码器的了解可以参考两篇文章,比较详细,在此就不多介绍了:

原理

脉冲与定位

  • 15脉冲/30定位:每拨动一格,两个电平都相继翻转,是半个脉冲;再拨动一格,电平再相继翻转,也是半个脉冲;两个半脉冲形成一个完整脉冲。静止状态下,两个电平相同,都为高或低
  • 20脉冲/20定位:每拨动一格,形成一个完整脉冲
    对应下图如下:
    在这里插入图片描述
    示波器抓取部分波形:
    在这里插入图片描述
      (note: 两个脉冲跳变的间隔约为几十ms)

功能

通过2个pin负责编码器的波形检测,顺时针与逆时针波形不同

硬件设计

IO外部上拉与无上拉
在这里插入图片描述

编程

硬件条件:

  • MCU:    stm32f407
  • 编码器类型: EC11-15脉冲/30定位
  • 连接:    IO外部无上拉,设置MCU GPIO的内部上拉

下面使用两种方法来对编码器进行计数和使用。

轮询模式

直接就上代码了,随意两个GPIO

//GPIO初始化
void MX_GPIO_Init(void)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOH_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();

  /*Configure GPIO pin : PB6 */
  GPIO_InitStruct.Pin = GPIO_PIN_6;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  /*Configure GPIO pin : PB7 */
  GPIO_InitStruct.Pin = GPIO_PIN_7;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

}

//判断检测
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
  // exit_init();
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  uint32_t count = 0;
  uint32_t wait_t = 0;
  bool encoder_switch = 0;
  uint8_t encoder_a_pre = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_6);
  // uint8_t encoder_b_pre = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_7);
  int32_t steps = 0;
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
    uint32_t t = HAL_GetTick();

    uint8_t encoder_a = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_6);
    uint8_t encoder_b = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_7);

    if (encoder_a_pre != encoder_a && !encoder_switch) {
      wait_t = HAL_GetTick();
      encoder_switch = true;
    }
    if (encoder_switch && ((t - wait_t) >= 2 )) {
      //a 0->1, b 0 Clockwise; b 1 AntiClockwise
      if (encoder_a == 1) {
        if (encoder_b == 0) {
          steps++;
        } else {
          steps--;
        }
      }
      //a 1->0, b 1 Clockwise; b 0 AntiClockwise 
      else {
        if (encoder_b == 1) {
          steps++;
        } else {
          steps--;
        }
      }
      encoder_switch = false;
      encoder_a_pre = encoder_a;
      printf("%d\r\n", steps);
    }
 
  }
  /* USER CODE END 3 */
}

注意点:编码器电平发生变化时可能存在噪声,类似按键一样需要增加延时防抖,并且考虑到在系统中少加入延时死等这些不友善的代码,所以代码中有如上处理。

定时器Encoder模式

stm32中定时器有自带Encoder的功能,所以可以借助定时器的这个特性来实现我们的需求。
直接撸代码,GPIO必须使用复用功能有定时器的pin。

//定时器及IO初始化
TIM_HandleTypeDef htim4;

/* TIM4 init function */
void MX_TIM4_Init(void)
{

  /* USER CODE BEGIN TIM4_Init 0 */

  /* USER CODE END TIM4_Init 0 */

  TIM_Encoder_InitTypeDef sConfig = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};

  /* USER CODE BEGIN TIM4_Init 1 */

  /* USER CODE END TIM4_Init 1 */
  htim4.Instance = TIM4;
  htim4.Init.Prescaler = 0;
  htim4.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim4.Init.Period = 65535;
  htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim4.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
  sConfig.EncoderMode = TIM_ENCODERMODE_TI1;
  sConfig.IC1Polarity = TIM_ICPOLARITY_FALLING;
  sConfig.IC1Selection = TIM_ICSELECTION_DIRECTTI;
  sConfig.IC1Prescaler = TIM_ICPSC_DIV1;
  sConfig.IC1Filter = 3;
  sConfig.IC2Polarity = TIM_ICPOLARITY_FALLING;
  sConfig.IC2Selection = TIM_ICSELECTION_DIRECTTI;
  sConfig.IC2Prescaler = TIM_ICPSC_DIV1;
  sConfig.IC2Filter = 3;
  if (HAL_TIM_Encoder_Init(&htim4, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM4_Init 2 */
  HAL_TIM_Encoder_Start(&htim4, TIM_CHANNEL_ALL);
  /* USER CODE END TIM4_Init 2 */

}

void HAL_TIM_Encoder_MspInit(TIM_HandleTypeDef* tim_encoderHandle)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(tim_encoderHandle->Instance==TIM4)
  {
  /* USER CODE BEGIN TIM4_MspInit 0 */

  /* USER CODE END TIM4_MspInit 0 */
    /* TIM4 clock enable */
    __HAL_RCC_TIM4_CLK_ENABLE();

    __HAL_RCC_GPIOB_CLK_ENABLE();
    /**TIM4 GPIO Configuration
    PB6     ------> TIM4_CH1
    PB7     ------> TIM4_CH2
    */
    GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF2_TIM4;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  /* USER CODE BEGIN TIM4_MspInit 1 */

  /* USER CODE END TIM4_MspInit 1 */
  }
}

//获取编码器变化
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
  // exit_init();
  MX_TIM4_Init();
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  int32_t Enc_Count_pre =  __HAL_TIM_GET_COUNTER(&htim4);
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
    int32_t Enc_Count =  __HAL_TIM_GET_COUNTER(&htim4);
    if (Enc_Count != Enc_Count_pre) {
      printf("%d\r\n", Enc_Count);
      Enc_Count_pre = Enc_Count;
    }
    
  }
  /* USER CODE END 3 */
}

结束语

此两种方式已做测试,稳得一批,如果细节问题可沟通。


— 2021.10.22-21:45于广东深圳

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: EC11编码器模块是一种常用的旋转编码器模块,常用于控制面板、旋钮等设备中。该模块主要由一个旋转编码器、转轴、电路和接口组成。 该编码器模块的原理图主要包括以下几个部分: 1. 旋转编码器:旋转编码器是该模块的核心部分,它由两个环状电容器组成,其中一个为固定电容器,一个为转动电容器。当用户旋转编码器时,转动电容器会相对于固定电容器发生旋转,产生变化的电容值。 2. 转轴:转轴是连接旋转编码器和外部设备的部分,它会将旋转编码器的旋转运动转换成机械运动。 3. 电路:在原理图中,通常包含一个微控制器或者计数器芯片,用于读取旋转编码器的输出信号,并将其转换成数字信号进行处理。此外,还可能包含一些电容和电阻等元件,用于过滤、放大和稳定信号。 4. 接口:编码器模块通常有多种接口,如GPIO(通用输入/输出口)接口、SPI(串行外围设备接口)接口等,用于与其他设备或系统进行通信。 该编码器模块的工作原理是,当用户旋转编码器时,转动电容器的电容值会发生变化,这个变化的电容值会被读取并传递给芯片进行处理。芯片会根据每个脉冲的变化来判断旋转的方向和速度,通过编码器模块的接口将相应的信息发送给其他设备或系统。这样,就可以实现对设备或系统的控制和调节。 总之,EC11编码器模块通过旋转编码器、转轴、电路和接口等部分,实现了用户旋转输入的检测和转换,将旋转运动转化为数字信号,从而实现对设备或系统的控制。 ### 回答2: EC11编码器模块是一种常用的机械转动位置检测器件,主要用于测量旋转轴或旋转物体的旋转角度和方向。它通常由旋转轴、光电传感器、脉冲输出电路等部分组成。 EC11编码器模块的原理图包括以下几个主要部分:旋转轴、旋转动作传感器、脉冲输出电路、滤波电路和电源电路。 首先,旋转轴是EC11编码器模块的核心部分,它通过旋转动作反映旋转位置和方向。旋转轴通常与电机或机械设备相连,当旋转轴发生旋转时,它会带动旋转动作传感器产生相应的变化。 旋转动作传感器是EC11编码器模块的感应元件,它通常由光电传感器组成。当旋转轴旋转时,旋转动作传感器会感应到旋转的变化,并将这些变化转换成电信号。 脉冲输出电路是EC11编码器模块的信号转换部分,它通常由电子元器件组成。脉冲输出电路将旋转动作传感器感应到的旋转变化转换成脉冲信号,并输出给外部设备。 滤波电路是EC11编码器模块的信号处理部分,它主要用于对脉冲信号进行滤波处理,以消除噪声和杂波对测量精度的干扰。 电源电路是EC11编码器模块的供电部分,它通常由电池或外部电源供电。电源电路为EC11编码器模块提供工作所需的电能。 综上所述,EC11编码器模块的原理图涵盖了旋转轴、旋转动作传感器、脉冲输出电路、滤波电路和电源电路等关键部分,通过这些组成部分的配合工作,可以实现对旋转轴或旋转物体的位置和方向的准确检测和测量。 ### 回答3: EC11编码器模块原理图是一种常见的旋转编码器模块,用于检测物体的转动或旋转。它通常由旋转编码器和电子元器件组成。 旋转编码器是EC11编码器模块的核心部分。它由一个编码轮和两个感应器组成。编码轮通常具有一系列刻痕或凹槽,当物体转动时,刻痕或凹槽会通过两个感应器前后地经过。感应器可以是光电传感器、霍尔传感器或磁性传感器。感应器通过检测编码轮上的刻痕或凹槽,并生成相应的电信号。 EC11编码器模块的工作原理如下:当物体旋转时,感应器会检测到编码轮上刻痕或凹槽的变化,并将这些变化转换为电信号。这些电信号会传递到电子元器件上进行处理和解码。通常,编码器模块会产生两个方向的脉冲信号,用于表示旋转方向。此外,它还会产生一个用于计数的信号,用于记录旋转的步数。 EC11编码器模块通常用于测量旋转速度、位置或距离。它在许多应用中都非常重要,例如电子设备的旋转控制、机械臂的位置控制以及一些工业和汽车应用中的运动测量。 总之,EC11编码器模块原理图是用于检测物体旋转的一种编码器模块,由旋转编码器和电子元器件组成。感应器检测旋转编码器上的刻痕或凹槽变化,并生成相应的电信号,用于表示旋转方向和计数旋转步数。它在许多应用中都有广泛的应用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值