当前位置: 首页 > news >正文

单片机-STM32部分:13-1、编码器

飞书文档https://x509p6c8to.feishu.cn/wiki/BpEywhaX9iqbiLkdqdAcmDnwnab

EC旋转编码器

在产品开发过程中,需要位置闭环的的产品,类似电机类产品来说,编码器至关重要,它不仅可以使我们对带年纪进行精确的速度闭环,位置闭环,还可以通过时间积分,根据运动学关系,获得速度、位置等信息。

本节课,我们使用拨轮滚轮旋转编码器EC11E153440D,带大家了解下编码器如何驱动。

编码器有四根线,A\B是编码输出,S是按钮状态,C是公共端。

那么我们该怎样去使用这个编码器呢,从给出的数据手册上面我们看到一个波形,我们就是通过这个波形去判断编码器是否转动以及编码器转动的方向?

可以从图中可以看出当从CW方向转动的时候,A的波形上升沿比B波形的上升沿快,具体快多少,这里数据手册给出24±3°,当从CCW方向转动的这个时候恰好相反,B的相位上升沿快于A的上升沿。这样可以通过捕获上升沿的顺序来判断编码器的方向。

因此:我们有两种方式来判断编码器转动和方向:

1、设置IOA为上升沿触发中断,在中断中检测B的电平状态,来判断旋转方向,这种方式比较简单。

2、可以同时捕获A项的上升、下降边沿,然后判断A项第一个边沿中断时候获取B和A项的电平,在第二个边沿触发中断的时候捕获B和A项的电平,根据两次捕获B和A项的值就可以知道旋转的方向。


bool is_ccw_end = false;
bool is_cw_end = false;while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */if(is_ccw_end == true){is_ccw_end = false;printf("正转\n");}if(is_cw_end == true){is_cw_end = false;printf("反转\n");}}void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){if(GPIO_Pin == A1_Pin)  //判断中断来自哪一条中断线{//进入中断之后,判断B1 PIN的电平来决定哪个方向if(HAL_GPIO_ReadPin(B1_GPIO_Port, B1_Pin) == 0){//CW方向is_cw_end = true;}else{//CCW方向is_ccw_end = true;}                   }
}

以CW方向为例,第一次捕获A项的的边缘位上升沿,此时A = 1,B = 0;那么第二次就必须捕获下降沿,A = 0,B = 1。假如A第一次没有在边沿捕获到上升沿的时候,捕获的是下降沿,第二次就一定捕获到上升沿。CCW方向也是如此的,这样我们就判断这四种情况,其他的都不用管,这样可以过滤掉干扰,从而实现更准确的控制。

设置PB0和PB1为编码器的A1、B1端口

PB0设置为外部中断,触发模式为上升、下降沿触发

PB1设置为输入模式

同时开启PB0的中断EXTI0

打开USART1作为日志口,方便调试

              //CW方向set_cw_status();is_ccw_start = false;}else{//CCW方向set_ccw_status();is_cw_start = false;}}}
}int fputc(int ch, FILE *f)
{HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1, 0xFFFF);return ch;
}
/* USER CODE END 4 */

参考工程:

参考飞书文档

STM32的定时器有编码器模式(Encoder Mode

大大的方便我们的开发。使用STM32cubeMX配置工具,使得这个过程变得无比简单。

如果TI1和TI2分别接编码器的A相和B相的话,那么,当编码器正转的时候,如下图计数器会向上计数,反转的时候会向下计数,注意了这个向下计数并不会出现负的值。
例如:
正转
(0,1,2,…,65535,0)
反转(0,65535,65534,…,2,1,0)

配置定时器TIM的编码器模式
设置定时器TIM的Combined Channels的选项为Encoder Mode,编码器模式;

设置定时器TIM相关参数:

PSC:0 ; Counter:65535 (设置计数器的值为65535,最大值);


配置编码器模式相关参数:

在参数配置中的Econder Mode中选择Econder Mode TI1 and TI2;

如果编码模式设置为 Encoder Mode TI1 and TI2 则会默认检测AB相的上升沿与下降沿;
每一个上升沿和下降沿都触发计数,所以每转一格计数器就会+4;

需要增加测量的精度时,可以采用4倍频方式,即分别在A、B相波形的上升沿和下降沿计数,分辨率可以提高4倍,
如果只是测速,不要求方向,那么只需要用单片机随意选择一个信号线就行了。

在TI1、TI2的选项中选择Rising Edge上升沿触发计数;

这个参数的意思是在检测到上升沿的时候就触发encoder捕获AB相的值,而并不是这里设置的是上升沿就只检测AB相的上升沿,下降沿还是同样会计数的。

Input Filter:滤波值,起到消抖作用

选择GPIO模式配置,配置定时器两个GPIO引脚模式,全部改成Pull-Up,即上拉模式,主要用于没有外部上拉的编码器读取时,可以确定引脚电平,防止出错;

编写代码

添加定时器3的通道1和通道2Encoder Mode开启使能函数

/* USER CODE BEGIN 2 */
HAL_TIM_Encoder_Start(&htim3,TIM_CHANNEL_1 | TIM_CHANNEL_2);
/* USER CODE END 2 */

编码器数据的读取使用:
在循环中调用 __HAL_TIM_IS_TIM_COUNTING_DOWN 可以获得当前电机的转向 0为正、1为负
在循环中调用 __HAL_TIM_GET_COUNTER 获取计数器的计数值,即编码器的脉冲数

  /* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */int Direction = __HAL_TIM_IS_TIM_COUNTING_DOWN(&htim3);    //读取编码器转动方向//若需要检测编码器转了多少格,记得要/4,因为转一格是+4;int CaptureNumber = (short)__HAL_TIM_GET_COUNTER(&htim3)/4;  //读取编码器数据printf("Direction is %d \r\n",Direction);printf("CaptureNumber is %d \r\n",CaptureNumber);HAL_Delay(500);}/* USER CODE END 3 *///short的表示范围(-32768-32767),也就是说当读出来的值为(32767, 32768, 32769,…,65535,65536,65537…)的时候会因为溢出而转换为(32767,-32768,-32767,…, -1, ,0, , 1)就这样不断地循环下去。所以我们的电机反转的时候读出的数就是反方向的速度值。

相关文章:

  • RCE联系
  • qtcreator导入帮助文档
  • 网页jupyter如何显示jpipvenv虚拟环境
  • 2.Redis-List列表类型详解(HM)
  • 2025年阿里云大数据ACP高级工程师认证模拟试题(附答案解析)
  • 【大数据】MapReduce 编程--WordCount
  • 构造二叉树
  • [学习]RTKLib详解:ionex.c、options.c与preceph.c
  • Android NDK开发入门:理解JNI的本质与数据类型处理
  • AI大模型学习二十、利用Dify+deepseekR1 使用知识库搭建初中英语学习智能客服机器人
  • 防火墙来回路径不一致导致的业务异常
  • 在Ubuntu系统下编译OpenCV 4.8源码
  • Linux驱动:驱动编译流程了解
  • AI日报 · 2025年5月12日|OpenAI 更新「Supervised Fine‑Tuning」文档与 API 示范
  • Ubuntu源码版comfyui的安装
  • 二、HAL库的命名规则详解
  • Edge浏览器打开PDF文件显示空白(每次需要等上一会)
  • Docker-配置私有仓库(Harbor)
  • Kubernetes控制平面组件:Kubelet详解(一):API接口层介绍
  • 【CF】Day57——Codeforces Round 955 (Div. 2, with prizes from NEAR!) BCD
  • 第二期人工智能能力建设研讨班在京开班,近40国和区域组织代表参加
  • 河南洛阳新安县煤渣倾倒耕地:多年难恢复,为何至今未解决?
  • 不到1小时就能速发证件?央媒曝光健康证办理乱象
  • 这座古村,藏着多少赣韵风华
  • 高盛上调A股未来12个月目标点位,沪深300指数潜在回报15%
  • 澎湃研究所“营商环境研究伙伴计划”启动