STM32 编码器驱动/旋转编码器旋钮encoder

2023-05-16

本文已比较纯粹的方式介绍编码器和驱动的编写
在这里插入图片描述
编码器最少有两个输出信号,一种典型的结构如上图所示。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);

}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM32 编码器驱动/旋转编码器旋钮encoder 的相关文章

  • ros安装并测试是否安装成功

    目录 一 xff0c 安装步骤二 xff0c 测试是否安装成功 一 xff0c 安装步骤 1 xff0c 首先前4项勾选 xff0c 然后源换成国内清华的源 2 xff0c 打开终端开始输入命令 xff1a span class token
  • C++ 双冒号::符号详解

    一 作用域符号 xff1a 作用域符号 的前面一般是类名称 xff0c 后面一般是该类的成员名称 xff0c C 43 43 为例避免不同的类有名称相同的成员而采用作用域的方式进行区分 例如 xff1a A B 表示两个类 xff0c 在
  • 嵌入式软件工程师前期职业生涯规划

    ARM 43 LINUX路线 xff0c 主攻嵌入式Linux操作系统及其上应用软件开发目标 xff1a xff08 1 xff09 掌握主流嵌入式微处理器的结构与原理 xff08 初步定为arm9 xff09 xff08 2 xff09
  • 【尚医通】微信扫码登录和手机号登录冲突问题解决思路

    尚医通 微信扫码登录和手机号登录冲突问题解决思路 问题描述 最近做尚医通遇到一个问题 xff0c 微信扫码登录和手机号登录在 特殊情况 下会发生冲突 xff0c 导致无法登录的问题 下面就描述一下几种情况 正常情况 xff1a 用户第一次一
  • GitHub awesome Resource

    各种Awesome技术资源的资源聚合 xff1a https github com sindresorhus awesome Contents PlatformsProgramming LanguagesFront End Developm
  • FreeRTOS ------ 栈、堆、任务栈

    1 任务的栈资源 xff08 创建任务分配的资源 xff0c 单位是4字节 xff09 来自 configTOTAL HEAP SIZE 定义的堆 xff0c 如果任务栈总量超过 configTOTAL HEAP SIZE xff0c 任务
  • STM32--微项目14-手撸I2C通讯、实现MPU6050六轴传感器控制

    一 微项目实现目标 xff1a STM32通过两个GPIO端口 xff0c 通过代码配置成I2C通讯状态 xff0c 通过I2C通讯与MPU6050进行信息交互 xff0c 包括配置MPU6050寄存器配置 获取MPU6050寄存器状态 x
  • ubuntu-查看文件系统

    ubuntu 查看文件系统 查看文件系统 deepfuture 64 deepfuture laptop df 文件系统 1K 块 已用 可用 已用 挂载点 dev sda1 75481116 3926204 67720600 6 tmpf
  • TypeError: Expected Ptr<cv::UMat> for argument ‘img‘

    使用opencv过程中报错 xff1a TypeError Expected Ptr for argument 39 img 39 请检查img参数是否是numpy数组 xff0c 以及其数据类型 dtype是否是np uint8 如果这两
  • TX2超详细,超实用刷机教程(亲测有效,所有步骤都是博主亲自实践过)

    本篇主要对TX2刷机流程以及刷机过程中遇到的坑和相应的解决办法做个记录 xff0c 以便再次刷机时能做个参考 如果你刚好收到TX2开发者套件 xff0c 还没有进行开箱 xff0c 那么请移步到我的前一篇博客进行TX2的开机测试 博客链接
  • MicroStrategy 简介 【Business Intelligent】

    下载地址 xff1a https www microstrategy com us resources microstrategy for students students Capabilities that power the Inte
  • crontab permission denied 解决办法,crontab 进程存在就不执行的方法

    crontab permission denied 出现场景 出现情况 xff0c sh文件在本地Win下面开发 xff0c 每次修改 xff0c 提交后在Linux上pull下来 xff0c 却发现x权限消失 导致crontab 里面定时
  • ROS入门之通信架构+实践问题+python版本切换解决

    运行起来后是什么样的通信结构 PR2机器人 这么多东西 xff0c 怎么管理进行 xff0c 并且怎么通信 节点管理器 xff08 作为管家管理进程 xff0c master xff09 node首先要向master注册 xff0c 之后就
  • matlab---s函数讲解之二连杆动力学仿真

    matlab虽然后simulink xff0c 但是再复杂系统的仿真的时候简单的simulink中模块不能满足要求 xff0c 因此需要自己建立s函数 xff0c 作为仿真中的一个模块 在控制系统中分为控制器和被控对象 matlab s函数
  • 全球定位系统的组成

    一 空间部分 1 GPS卫星 Block xff08 试验卫星 xff09 Block xff08 以下均为工作卫星 xff09 14天导航电文 xff0c 实施SA和AS的能力 Block A 180天导航电文 xff0c 卫星互相通信能
  • 前端疑难杂症集锦

    一 webpack打包时Cannot resolve module 39 fs 39 在webpack config js中添加 node fs 34 empty 34 二 typescript找不到fs模块 code npm instal
  • 基于ROS的语音控制机器人(二):上位机的实现

    文章目录 目录 文章目录 前言 一 准备工作 1 python工作环境 2 ros环境 3 QT designer 二 界面程序设计 1 界面设计 2 ui文件转py文件 三 上位机程序编写 1 具体思路 2 具体实现 3 遇到的问题 1
  • "指定的文件格式无法识别或为不支持的二进制"

    次奥 xff0c 你没有正确设置启动项目 转载于 https www cnblogs com tupx p 3701598 html
  • Linux安装MySQL8.0.16

    1 下载安装包 https www mysql com 2 安装MySQL 将下载好的安装包上传到服务器 然后解压 tar xvf mysql 8 0 16 el7 x86 64 tar gz 然后将解压目录重命名为mysql 8 0 16
  • 硬件中断和软件中断的区别

    中断 中断指当出现需要时 xff0c CPU暂时停止当前程序的执行转而执行处理新情况的程序和执行过程 即在程序运行过程中 xff0c 系统出现了一个必须由CPU立即处理的情况 xff0c 此时 xff0c CPU暂时中止程序的执行转而处理这

随机推荐

  • 嵌入式C语言自我修养笔记1-ARM体系结构与编译运行

    目录 ARM 体系结构ARM 体系结构ARM 汇编指令ARM 寻址方式ARM 伪指令C 与汇编混合编程 程序编译链接与安装运行预处理过程编译过程链接过程程序安装apt get链接静态库动态链接共享库插件工作原理Linux 内核模块运行机制L
  • Renode应用:在RISC-V核上运行FreeRTOS

    本篇记录通过Renode在RISC V核上运行FreeRTOS demo的情况 本来不准备写这一篇 xff0c 但是发现近期工作学习密度实在太大 xff0c 上周工作的中间结果这周竟然完全想不起来了 xff0c 不得不又花了一些时间从头摸索
  • VideoStream流媒体(VOD视频点播)系统平台

    软件介绍 xff1a VideoStream是集流媒体视频服务和流媒体应用管理为一体的综合流媒体服务系统 xff0c 本产品通过宽带IP网络为教育系统 各类运营商 政府企业等用户提供音视频服务的应用 系统特点 xff1a 1 采用WEB端口
  • c语言实现模拟FTP服务器项目

    下载源码后 xff0c 直接可以在ubuntu中编译运行 xff1a FTP服务器程序功能 xff1a 客户端 xff1a 1 输入命令 xff1a help 查看FTP服务器所支持的所有命令 2 输入名 xff1a ls 查看服务器上可以
  • 基于ArUco的视觉定位

    参考如下 博客 基于ArUco的视觉定位 1 3 https www freesion com article 4265319144 基于ArUco的视觉定位 4 https www pianshen com article 2491452
  • 伺服电机和步进电机的区别

    硬件型号 xff1a 三菱伺服电机HG KR43J 系统版本 xff1a 电机系统 1 控制的方式不同 步进电机 xff1a 通过控制脉冲的个数控制转动角度的 xff0c 一个脉冲对应一个步距角 伺服电机 xff1a 通过控制脉冲时间的长短
  • ubutnu更换国内源后,更新一直出现404,Not Found的问题

    1 问题 题主系统是ubuntu16 04 64位系统 尝试更换国内各种源 连ubuntu官方源都尝试了 sudo vim etc apt sources list修改为 deb https mirrors tuna tsinghua ed
  • Python+Flask实现股价查询系统。Python绘制股票k线走势

    文章目录 一 实现效果图二 实现思路1 获取数据 2 可视化数据三 源码获取 一 实现效果图 打开默认显示半年线 xff0c 可以通过可视化类型选择可视化k线图 高低点等 xff08 目前只完成了初版 xff0c 当查询的股票数据返回为空时
  • Failed to fetch http://mirrors.tuna.tsinghua.edu.cn/ubuntu/pool/main/g/gcc-5/g++-5_5.4.0-6ubuntu1~16

    今天在ubutun中在安装redis过程中 xff0c 安装gcc时遇到了Failed to fetch http mirrors tuna tsinghua edu cn ubuntu pool main g gcc 5 g 43 43
  • 切换日语输入法找不到MicrosoftIME键盘选项了

    去微软官方下载一个 Microsoft IME office 2010后 xff0c 安装解决 转载于 https www cnblogs com tupx p 3816026 html
  • msgid 属性

    Android源码中的String xml文件 xff0c msgid这个属性是干嘛的 xff1f 全局资源 xff0c 方便引用 比如在布局的text和activity中用到 转载于 https www cnblogs com Ph on
  • 2017年09月23日普级组 数列

    Description 小S今天给你出了一道找规律题 xff0c 题目如下 xff1a 有如下的数列1 xff0c 11 xff0c 21 xff0c 1211 xff0c 111221 xff0c 312211 xff0c 小S问你这个数
  • python 机器学习实战:信用卡欺诈异常值检测

    今晚又实战了一个小案例 xff0c 把它总结出来 xff1a 有些人利用信用卡进行诈骗等活动 xff0c 如何根据用户的行为 xff0c 来判断该用户的信用卡账单涉嫌欺诈呢 xff1f 数据集见及链接 xff1a 在这个数据集中 xff0c
  • Virtual Serial Port Driver 虚拟串口工具软件 使用介绍

    一般来说 xff0c 电脑的外部设备可以用过各种端口和电脑连接 常见的有USB xff0c VGA xff0c DVI等等 在工业领域或者是软件开发领域 xff0c 我们常常需要用简单低成本快捷的方式 xff0c 完成电脑和设备的连接 那么
  • Freertos 源码分析 队列queue

    队列queue xff08 零 xff09 队列的基础概念和形态 xff08 一 xff09 Freertos 队列 queue c FreeRTOS Kernel 10 4 6 include queue h Freertos队列模块包含
  • Freertos 任务TASK(一) 任务创建

    任务的创建 Freertos 的任务创建难点 1 xff09 堆栈生长的方向 2 xff09 64字节的对齐 3 xff09 任务堆栈初始化 Freertos 的任务使用任务控制块来进行管理 xff0c 是对任务的抽象 任务本身就是一段可执
  • Freertos Cortex-M3上下文切换

    上下文切换是操作系统实现虚拟化的核心功能 xff0c 操作系统对任务的管理通过上下文切换完成 Freertos 在STM32F103上的上下文切换是本文介绍的内容 STM32F103 采用 Cortex M3 内核 上下文切换的本质是对现场
  • STM32CubeMX配置freertos配置任务(一)

    使用STM32CubeMX 配置Freertos 生成一个任务点亮LED stm32cubemx STM32CubeMX 是 ST 意法半导体近几年来大力推荐的STM32 芯片图形化配置工具 xff0c 允许用户使用图形化向导生成C 初始化
  • STM32 精准采集ADC电压,误差分析

    ADC模块采集电压流程 数字世界和模拟世界的桥梁 xff0c 对于嵌入式软件而言 xff0c 大家止于采集功能的实现 本文目的在于深入理解ADC xff0c 积累技术做出更加稳定优秀的产品 STM32 大部分系列都是使用SAR 逐次逼近型电
  • STM32 编码器驱动/旋转编码器旋钮encoder

    本文已比较纯粹的方式介绍编码器和驱动的编写 编码器最少有两个输出信号 xff0c 一种典型的结构如上图所示 AB是编码器的输出引脚 当触点和黄色的金属片接触的时候信号发生跳变沿 xff0c 可以上上升沿也可以是下降沿 xff0c 具体根据A