本文已比较纯粹的方式介绍编码器和驱动的编写

编码器最少有两个输出信号,一种典型的结构如上图所示。AB是编码器的输出引脚。当触点和黄色的金属片接触的时候信号发生跳变沿,可以上上升沿也可以是下降沿,具体根据AB引脚默认的电平状态,和金属片电平状态。

当编码器转过一段角度后就会出现上图的波形。AB信号交替出现脉冲。上图所示的状态。B还在金属片上B是高电平,A已经不再金属片上恢复默认电平低。逆时针转动时,A触点比B触点先接触到金属片。所以A的高电平超前B的高电平。超前多少,根据金属片的长度和AB触点的间距决定。所以当顺时针转动的时候,B触点比A触点先接触到金属片。
根据这样的特点可以,从AB出现脉冲的先后可以判别出旋转的方向。脉冲的个数可以判断出转了多少角度。

实际波形
上通道为A,下通道为B
下图为正逆时针旋转

下图为顺时针旋转

对于数字输入输出的MCU来说,可以使用三种方式来实现编码器的驱动

1.GPIO抽样法

按照一定的时间间隔去采集AB触点的电平,根据电平的状态去判别脉冲计数。
上图所示,I:A出现低电平时,B是高电平。出现第一张图顺时针的状态。
II: B是低电平的时候,A是高电平,说明出现第二张图的状态。
抽样法关键在于测量到上述I,II的特征电平。抽样的时间需要根据旋转编码器的最快速度来进行设定,已保证能够采样到特征电平。

一般来说手工扭动的旋转编码器的采样间隔可以是1ms
代码如下,输入参数gpio1,gpio2为AB项的电平值。需要1ms为周期进行采样
encoder_poision_cnt 为脉冲计数器
encoder_dir 为方向
实验结果还不错,虽然看上去简单,但是其稳定性不错。


void task2_task(void *pvParameters)
{while(1){encoder_gpio_in =    GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_10);encoder_gpio_in2 = GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_11);encoder_dir =  app_encoder_gpio_mes_test(encoder_gpio_in,encoder_gpio_in2);vTaskDelay(1);}}
uint16_t app_encoder_gpio_mes_test(uint16_t gpio1,uint16_t gpio2)
{static char lock=0;static uint16_t knob_dir =0;if((gpio1 == 0 && gpio2 ==1)&(!lock)){lock =1;knob_dir= 1;encoder_poision_cnt++;}else if((gpio2 ==0 && gpio1==1)&(!lock)){lock =1;knob_dir = 2;if(encoder_poision_cnt>0)encoder_poision_cnt--;}else if((gpio2 ==1 && gpio1==1)){lock =0;knob_dir= 0;}return knob_dir;}

2.中断法

由于编码器是金属触点,所以必然会出现抖动。抖动对于响应快速的外部中断来说是一个比较麻烦的问题。
根据抖动的持续时间,可以做一个简单的延时滤波。
原理是AB接触到触点时,会发生电平的跳边沿,跳边沿触发中断后,判断电平的状态。从而按照1的方法判别

void app_encoder_it_init()
{/*PA10  PA11  encoder In*/NVIC_InitTypeDef   NVIC_InitStruct;EXTI_InitTypeDef   EXTI_InitStruct;/*exti line config*/EXTI_InitStruct.EXTI_Line =EXTI_Line10;EXTI_InitStruct.EXTI_LineCmd =ENABLE ;EXTI_InitStruct.EXTI_Mode =EXTI_Mode_Interrupt;EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Falling;EXTI_Init(&EXTI_InitStruct);EXTI_InitStruct.EXTI_Line =EXTI_Line11;EXTI_Init(&EXTI_InitStruct);GPIO_EXTILineConfig(GPIOA,GPIO_PinSource10);GPIO_EXTILineConfig(GPIOA,GPIO_PinSource11);/*NVIC config*/NVIC_InitStruct.NVIC_IRQChannel =EXTI15_10_IRQn;NVIC_InitStruct.NVIC_IRQChannelCmd =ENABLE ;NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 14;NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;NVIC_Init( &NVIC_InitStruct);}
static void do_things(void)
{int i =2000;while (i>0){i--;}
}
void EXTI15_10_IRQHandler(void)
{static char lock=0;static uint16_t knob_dir =0;do_things(); /* simple filter */if(EXTI_GetITStatus(EXTI_Line10)){/*Rising or Falling or noise*/if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_10))/*Rising*/{}else/*Falling*/  {   if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_11)){encoder_poision_cnt++;knob_dir = FORWORD;}}EXTI_ClearITPendingBit(EXTI_Line10);}else if (EXTI_GetITStatus(EXTI_Line11)){/*Rising or Falling or noise*/if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_11))/*Rising*/{     }else /*Falling*/{if((GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_10))& (encoder_poision_cnt>0)){encoder_poision_cnt--;knob_dir = BACKWORD;}}EXTI_ClearITPendingBit(EXTI_Line11);}

3.使用TIM 的编码器模块

STM32 的TIM模块自己带encoder的接口,可以不在CPU的参与下自己动进行方向,脉冲计数。
需要用户去读取CNT和DIR的数值已获取计数值和旋转方向。
TIM模块庞大复杂,如果不熟悉该模块可以使用上面的基础方法。
代码如下

void app_encoder_tim_gpio_init(void)
{GPIO_InitTypeDef   GPIO_InitStruct;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_InitStruct.GPIO_Pin  =GPIO_Pin_8;GPIO_InitStruct.GPIO_Speed =GPIO_Speed_10MHz;GPIO_Init(GPIOA, &GPIO_InitStruct);GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_InitStruct.GPIO_Pin  =GPIO_Pin_9;GPIO_InitStruct.GPIO_Speed =GPIO_Speed_10MHz;GPIO_Init(GPIOA, &GPIO_InitStruct);app_encoder_tim();}
void app_encoder_tim(void)
{   TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;TIM_ICInitTypeDef    TIM_ICInitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);TIM_TimeBaseStructure.TIM_Prescaler = 0x0; // No prescaling TIM_TimeBaseStructure.TIM_Period = 60000; TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);TIM_ICStructInit(&TIM_ICInitStructure);TIM_ICInitStructure.TIM_ICFilter = 4;//ICx_FILTER;TIM_ICInit(TIM1, &TIM_ICInitStructure);TIM1->CNT = 0;TIM_EncoderInterfaceConfig(TIM1, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising,TIM_ICPolarity_Rising);TIM_Cmd(TIM1,ENABLE);}

STM32 编码器驱动/旋转编码器旋钮encoder相关推荐

  1. FPGA驱动旋转编码器(Verilog)

    简述 遇到问题:不知道怎么使用旋转编码器:不知道判断左旋右旋:编码器硬件消抖后还是抖动.乱跳,不符合编程预想结果. 编程思路:通过信号打拍进行信号跳变检测:当一个端口的跳变时,判断另一个端口的电平状态 ...

  2. 【CubeMX配置STM32使用360°旋转编码器(KY-040)】

    CubeMX配置STM32使用360°旋转编码器(KY-040) 一.使用CubeMX进行基本的配置 所使用编码器的图片为: 在编码电机上面的编码器与这个的使用方法类似. 选择编码器模式 另外还需要选 ...

  3. STM32移植LVGL+旋转编码器接口对接

    写在前面:本菜鸟结合了许多大佬的文章,成功实现了基于LVGL的GUI设计,小开心~浅浅记录一下!~ 本文以单片机STM32F103VET6为核心,利用ST7796芯片驱动分辨率为480*320的LCD ...

  4. 线扫相机 编码器_旋转编码器控制线扫相机

    型号:OMRON E6B2-CWZ1X  2000脉冲/转,线扫相机是大华的8K相机 电源线:棕5V 蓝0V 信号线:共6根线,前四根都是2000脉冲/转,后两根1脉冲/转 黑 OUT A 黑红 OU ...

  5. STM32学习笔记(三)丨中断系统丨EXTI外部中断(对射式红外传感器计次、旋转编码器计次)

    本篇文章包含的内容 一.中断系统 1.1 中断的定义 1.2 中断优先级 1.3 中断的嵌套 1.4 STM32中的中断系统 1.4.1 STM32的中断资源 1.4.2 嵌套中断向量控制器 NVIC ...

  6. STM32入门笔记03_EXTI外部中断详解+案例:红外对射计数、旋转编码器计数

    EXTI外部中断 中断的相关概念 中断源: 可以引起中断的事件称为中断源 中断: 在主程序运行过程中,出现了特定的中断触发条件(中断源),使得CPU暂停当前正在运行的程序,转而去处理中断程序,处理完成 ...

  7. STM32CubeMX学习——旋转编码器模块

    前言 雨打灯难灭,风吹色更明. 若飞天上去,定作月边星.--李白<咏萤火> 一.旋转编码器介绍 旋转编码器是一种可以左右旋转,同时也可以按下,也可以按下旋转的器件,通过左右旋转对应着内部不 ...

  8. 【Arduino使用旋转编码器模块】

    Arduino使用旋转编码器模块 前言 旋转编码器模块引脚 旋转编码器模块如何工作? 旋转编码器模块电路图 Arduino旋转编码器模块电路连接图 代码说明 完整代码 前言 旋转编码器是一种机电位置传 ...

  9. 2022年全球及中国危险区域旋转编码器行业头部企业市场占有率及排名调研报告

    本文调研和分析全球危险区域旋转编码器发展现状及未来趋势,核心内容如下: (1)全球市场总体规模,分别按销量和按收入进行了统计分析,历史数据2017-2021年,预测数据2022至2028年. (2)全 ...

最新文章

  1. Redis 高级特性(3)—— 持久化及数据恢复
  2. 通用寄存器的专门用途
  3. 元素class属性中的空格
  4. 小狗扫地机器人与石头_当戴森遇到石头机器人,从容应对 “猫狗拆家”
  5. 学习笔记(42):Python实战编程-pyinstaller程序打包
  6. php 解析yaml,php yaml 解析 报错问题
  7. md5加密后怎么解密_手机怎么解密已加密的PDF?不会还有人不知道这招吧?
  8. [bzoj1468][poj1741]Tree_点分治
  9. opengl 纹理贴到对应的位置_OpenGL常用命令备忘录(Part B)
  10. 圆柱体积怎么算立方公式_圆柱体体积计算公式?
  11. 万字详解OpenDRIVE文件
  12. 教孩子学编程(Python语言版)
  13. 智慧医院解决方案如何落地 智慧医院解决方案实际应用
  14. Android 测试环境噪音分贝
  15. 【程序设计训练】1-7 F1方程式冠军
  16. 在哪里能学到计算机基础知识,电脑基础知识学习
  17. python蚂蚁森林自动偷能量_蚂蚁森林自动偷能量 激活 - 『精品软件区』 - 吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn...
  18. 计算机逻辑部件按其结构可分为,《数字逻辑电路》期末大作业实验报告
  19. Python计算Arduino声音方向范围和绘制声音位置二维概率分布热图
  20. 获取Flickr API key及利用Python获取Flickr数据

热门文章

  1. centos-linux(64位)安装与配置
  2. IDEA设置中文/更改页面/IDEA字体大小颜色设置/IDEA注释取消斜体
  3. Rancher 和 KubeSphere 的对比
  4. 电脑远程桌面连接不上应该如何解决
  5. python沙盒逃逸
  6. PGM学习之七 MRF,马尔科夫随机场
  7. SpringBean篇 (1) 配置文件的装载方式
  8. CSS-Sprite(雪碧图)
  9. Java学习---面向对象与多维数组
  10. 股市的通俗经济学原理