基于与STM32的加湿器之旋转编码器驱动

1.简介

  旋转编码器,也被称为轴编码器或脉冲编码器(SPC),是一种将旋转的机械位移量转换为电气信号的传感器,其信号可用于检测位置、速度等。

2.工作原理

  旋转编码器的工作原理主要基于光电转换或磁电转换。以光电式旋转编码器为例,其内部有一个中心有轴的光电码盘,码盘上有环形通、暗的刻线。当码盘随轴旋转时,光电发射和接收器件会读取这些刻线,并产生相应的电信号。这些电信号经过处理后,可以转换成数字量输出,用于表示旋转的位移、速度等。
  测量转速:旋转编码器可以测量旋转速度,并将转速转换成电脉冲信号,以供控制系统使用。
  方向检测:双路输出的旋转编码器可以输出两组A/B相位差90度的脉冲,通过这两组脉冲不仅可以测量转速,还可以判断旋转的方向。

3.EC11旋转编码器

  EC11旋转编码器是一种将旋转的机械位移转换为电信号的装置,其输出信号可用于各种控制系统中,如频率、音量、速度、温度、电压、菜单选择、光线强弱等参数的控制。它广泛用于车载DVD、车载导航、汽车影音系统,以及家用小家电产品的旋转开关上。此外,EC11编码器还应用于汽车电子、多媒体音响、仪器仪表、家用电器、智能家居等领域。
  EC11编码器通常具有多个引脚,包括用于检测旋转的A、B引脚,以及作为公共端的C引脚。此外,还可能有用于轻触按键的SW引脚(在某些型号中)。A、B引脚用于输出相位差为90度的脉冲信号,通过检测这两个信号的相位关系可以确定旋转的方向。C引脚通常接地,作为A、B信号的参考地。硬件实物如图所示:
在这里插入图片描述
在这里插入图片描述

  硬件接口电路如下图所示,采用5V供电,C为GND,作为公共端引脚,A、B引脚用于旋转检测,二者相位相差90°。
在这里插入图片描述

4.定时器编码器

  STM32定时器编码器是STM32微控制器中用于与旋转编码器接口的一种功能,它通过定时器的输入引脚直接连接到旋转编码器,利用定时器的计数器来跟踪编码器的相位变化,从而确定位置、速度和方向。
  在STM32中,编码器接口(Encoder Interface)允许通过连接到定时器的输入引脚(通常为输入捕获的通道1和通道2,即CH1和CH2),来直接与旋转编码器进行接口。这一功能使得STM32能够利用定时器的计数器(CNT)来跟踪编码器的相位变化,进而实现位置、速度和方向的测量。
  选择编码器接口模式的方法是:如果计数器只在TI2的边沿计数,则置TIMx_SMCR寄存器中的SMS=001;如果只在TI1边沿计数,则置SMS=010;如果计数器同时在TI1和TI2边沿计数,则置SMS=011。
  通过设置TIMx_CCER寄存器中的CC1P和CC2P位,可以选择TI1和TI2极性;如果需要,还可以对输入滤波器编程。
  两个输入TI1和TI2被用来作为增量编码器的接口。假定计数器已经启动(TIMx_CR1寄存器中的CEN=’1’),计数器由每次在TI1FP1或TI2FP2上的有效跳变驱动。TI1FP1和TI2FP2是TI1和TI2在通过输入滤波器和极性控制后的信号;如果没有滤波和变相,则TI1FP1=TI1,TI2FP2=TI2。根据两个输入信号的跳变顺序,产生了计数脉冲和方向信号。依据两个输入信号的跳变顺序,计数器向上或向下计数,同时硬件对TIMx_CR1寄存器的DIR位进行相应的设置。不管计数器是依靠TI1计数、依靠TI2计数或者同时依靠TI1和TI2计数。在任一输入端(TI1或者TI2)的跳变都会重新计算DIR位。
  编码器接口模式基本上相当于使用了一个带有方向选择的外部时钟。这意味着计数器只在0到TIMx_ARR寄存器的自动装载值之间连续计数(根据方向,或是0到ARR计数,或是ARR到0计数)。所以在开始计数之前必须配置TIMx_ARR;同样,捕获器、比较器、预分频器、触发输出特性等仍工作如常。
  在这个模式下,计数器依照增量编码器的速度和方向被自动的修改,因此计数器的内容始终指示着编码器的位置。计数方向与相连的传感器旋转的方向对应。下表列出了所有可能的组合,假设TI1和TI2不同时变换。
在这里插入图片描述
  采用定时器编码器模式接口实现计数,运行效果如下:在这里插入图片描述

5.HAL库代码生成

5.1定时器编码器软件配置

  1.根据硬件原理图接口,选择对应定时器通道,本次编码器AB相引脚为PB4和PB5,因此选择TIM3_CH1和TIM3_CH2作为检测通道。
在这里插入图片描述
  2.配置定时器计数周期和通道参数。
  本次使用编码器主要是实现对加湿器雾化片的无极调速,雾化片工作频率为110KHZ,因此选择的工作频率为72MHZ,计数周期为654。
在这里插入图片描述

5.2代码生成

  TIM3初始化配置:

void MX_TIM3_Init(void)
{/* USER CODE BEGIN TIM3_Init 0 *//* USER CODE END TIM3_Init 0 */TIM_Encoder_InitTypeDef sConfig = {0};TIM_MasterConfigTypeDef sMasterConfig = {0};/* USER CODE BEGIN TIM3_Init 1 *//* USER CODE END TIM3_Init 1 */htim3.Instance = TIM3;//定时器3htim3.Init.Prescaler = 0;//与分频系数,工作频率为72MHZhtim3.Init.CounterMode = TIM_COUNTERMODE_UP;//向上计数模式htim3.Init.Period = 654;//计数周期htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;//无时钟分频因子htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;//自动重装载预装载允许位sConfig.EncoderMode = TIM_ENCODERMODE_TI12;//编码器在TI1和TI2上均计数sConfig.IC1Polarity = TIM_ICPOLARITY_RISING;//在下降沿计数sConfig.IC1Selection = TIM_ICSELECTION_DIRECTTI;//TI1对应IC1sConfig.IC1Prescaler = TIM_ICPSC_DIV1;//无分频器,每个事件检测一次sConfig.IC1Filter = 0;//无滤波器,以fDTS采样sConfig.IC2Polarity = TIM_ICPOLARITY_RISING;//在下降沿计数sConfig.IC2Selection = TIM_ICSELECTION_DIRECTTI;//TI2对应IC2sConfig.IC2Prescaler = TIM_ICPSC_DIV1;//无分频器,每个事件检测一次sConfig.IC2Filter = 0;//无滤波器,以fDTS采样if (HAL_TIM_Encoder_Init(&htim3, &sConfig) != HAL_OK)//编码器初始化{Error_Handler();}sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK){Error_Handler();}/* USER CODE BEGIN TIM3_Init 2 *//* USER CODE END TIM3_Init 2 */}

  TIM3通道引脚配置:

void HAL_TIM_Encoder_MspInit(TIM_HandleTypeDef* tim_encoderHandle)
{GPIO_InitTypeDef GPIO_InitStruct = {0};if(tim_encoderHandle->Instance==TIM3){/* USER CODE BEGIN TIM3_MspInit 0 */RCC->APB2ENR|=1<<0;//AFIOAFIO->MAPR&=~(0x7<<24);AFIO->MAPR|=0x1<<24;//设置PB4作为普通IO使用/* USER CODE END TIM3_MspInit 0 *//* TIM3 clock enable */__HAL_RCC_TIM3_CLK_ENABLE();__HAL_RCC_GPIOB_CLK_ENABLE();/**TIM3 GPIO ConfigurationPB4     ------> TIM3_CH1PB5     ------> TIM3_CH2*/GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_5;GPIO_InitStruct.Mode = GPIO_MODE_INPUT;GPIO_InitStruct.Pull = GPIO_NOPULL;HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);__HAL_AFIO_REMAP_TIM3_PARTIAL();/* TIM3 interrupt Init */HAL_NVIC_SetPriority(TIM3_IRQn, 0, 0);HAL_NVIC_EnableIRQ(TIM3_IRQn);/* USER CODE BEGIN TIM3_MspInit 1 */TIM3->CCMR1|=1<<0;//CH1配置为输入模式TIM3->CCMR1|=1<<8;//CH2配置为输入模式TIM3->CCER|=1<<0;//CH1捕获使能TIM3->CCER|=1<<4;//CH2捕获使能TIM3->DIER|=1<<1;//CH1中断TIM3->DIER|=1<<2;//CH2中断TIM3->CR1|=1<<0;//使能定时器/* USER CODE END TIM3_MspInit 1 */}
}

5.3 寄存器方式实现定时器编码器配置示例

/********定时器编码器配置*********
**硬件接口:
开启部分重映射
**PB4 -->TIM3_CH1 
**PB5 -->TIM3_CH2
**配置模式:编码器模式
**
**********************************/
void TIM3_CodeMode(u16 psc,u16 arr)
{RCC->APB2ENR|=1<<3;//PBRCC->APB2ENR|=1<<0;//AFIOAFIO->MAPR&=~(0x7<<24);AFIO->MAPR|=0x1<<24;AFIO->MAPR&=~(0x3<<10);AFIO->MAPR|=0x2<<10;//开启部分重映射GPIOB->CRL&=0xFF00FFFF;GPIOB->CRL|=0x00880000;RCC->APB1ENR|=1<<1;//tim3RCC->APB1RSTR|=1<<1;//复位时钟RCC->APB1RSTR&=~(1<<1);//取消复位//计数功能配置TIM3->CR1|=1<<7;TIM3->PSC=psc-1;//预分频器TIM3->ARR=arr;//重装载值TIM3->CNT=50;//编码器模式配置TIM3->SMCR|=1<<0;//根据TI1电平计数TIM3->CCMR1|=1<<0;//配置为输入模式TIM3->CCMR1|=1<<2;//每2个事件捕获一次TIM3->CCMR1|=0xf<<4;//输入滤波器TIM3->CCER|=1<<1;//反向,捕获在下降沿//CH2TIM3->CCMR1|=1<<8;//CH2配置为输入TIM3->CCMR1|=1<<10;//每2个事件捕获一次TIM3->CCMR1|=0xf<<12;//输入滤波器TIM3->CCER|=1<<5;//反向,捕获在下降沿TIM3->DIER|=1<<1;//CH1中断TIM3->DIER|=1<<2;//CH2中断//STM32_NVIC_SetPriority(TIM3_IRQn,0,0);//设置优先级HAL_NVIC_SetPriority(TIM3_IRQn, 0, 0);HAL_NVIC_EnableIRQ(TIM3_IRQn);TIM3->CCER|=1<<0;//CH1捕获使能TIM3->CCER|=1<<4;//CH2捕获使能TIM3->CR1|=1<<0;//使能定时器}

5.4 定时器编码器中断处理

void TIM3_IRQHandler(void)
{/* USER CODE BEGIN TIM3_IRQn 0 *//* USER CODE END TIM3_IRQn 0 */HAL_TIM_IRQHandler(&htim3);/* USER CODE BEGIN TIM3_IRQn 1 */u16 cnt=TIM3->CNT;u8 dir=(TIM3->CR1&(1<<4));printf("cnt=%d,%d\r\n",cnt,dir);/* USER CODE END TIM3_IRQn 1 */
}

6.运行效果

在这里插入图片描述
  通过旋转编码器实现无极调速效果示例:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/46169.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

uniapp 小程序注册全局弹窗组件(无需引入,无需写标签)

由于uniapp没有开放根节点&#xff0c;所以一般情况下通过app.components注册&#xff0c;在需要的页面直接写组件标签&#xff0c;但是如果每个页面都需要的话&#xff0c;再每个都加的话会非常的麻烦 网上的思路都不咋地&#xff1a; 1.通过写一个透明弹窗页面来实现&#…

在 Objective-C 中,如何有效地处理内存管理以避免内存泄漏?

在 Objective-C 中&#xff0c;可以通过以下几个方法来有效地处理内存管理以避免内存泄漏&#xff1a; 使用自动引用计数&#xff08;ARC&#xff09;&#xff1a;ARC 是一种自动内存管理机制&#xff0c;它可以自动地插入 retain、release 和 autorelease 方法来管理对象的内存…

Proteus元器件库与仪器仪表

常用元件与仪表简介 分立元件 1. 电阻Resistor 电阻 RES 排阻 RESPACK-8 2. 电容 Capacitor 瓷片电容 CAP 电解电容 CAP-ELEC 3. 电感 Inductor 4. 电位器 Potentiometer 5. 二极管 Diode 发光二极管 LED 6. 晶体管 Transistor 7. 场效应管 FET 8. 三极管 T…

LivePortrait 数字人:开源的图生视频模型,本地部署和专业视频制作详细教程

看到上面面部表情动态图片&#xff0c;是不是感觉挺有有意思&#xff1f;它就是通过快手、中科大和复旦大学联合研发的图生视频开源大模型LivePortrait&#xff08;灵动人像&#xff09;生成的视频。通过LivePortrait大模型&#xff0c;我们只需要一张人脸正面图片和一段文字或…

单相整流-TI视频课笔记

目录 1、单相半波整流 1.1、单相半波----电容滤波---超轻负载 1.2、单相半波----电容滤波---轻负载 1.3、单相半波----电容滤波---重负载 2、全波整流 2.1、全波整流的仿真 2.2、半波与全波滤波的对比 3、全桥整流电路 3.1、全波和全桥整流对比 3.2、半波全波和全桥…

.env.development、.env.production、.env.staging

环境变量文件&#xff08;如 .env.development、.env.production、.env.staging&#xff09;用于根据不同的环境&#xff08;开发、生产、测试等&#xff09;配置应用程序的行为。 作用 .env.development&#xff1a;用于开发环境的配置。开发人员在本地开发时会使用这个文件…

php获取,昨,今,后天.... 本周,月,年...日期时间戳

时间戳->时间转换工具 时间戳(Unix timestamp)转换工具 - 在线工具 (tool.lu) 代码如下: public function date(){/** 日期 **/// 今天的日期$result[today_date] date("Y-m-d");// 昨天的日期$result[yesterday_date] date("Y-m-d", strtotime(&quo…

Oracle使用fetch first子句报错:ORA-00933 SQL命令未正确结束

问题背景 今天在统计终端厂商告警次数Top10的时候使用SQL查询使用到了fetch first子句&#xff0c;结果执行报错&#xff1a;ORA-00933 SQL命令未正确结束。 报错原因 Oracle数据库中&#xff0c;使用 FETCH FIRST 子句需要启用 Oracle 12c 及以上版本。如果在较低版本的 Or…

【Git使用】管理代码

Git使用 1、git命令1.1、git init1.2、git add1.3、git commit1.4、git push1.5、git branch1.6、git fetch1.7、git checkout X1.8、git status 2、提交执行顺序3、常见错误Error3.1、error: pathspec XXX did not match any file(s) known to git3.2、fatal: not a valid obj…

使机器人在执行任务倒快递

这段代码是用来控制机器人在不同模式下的行为&#xff0c;具体是处理 residenceright 和 residenceleft 两种模式下的过渡过程。代码中使用了一个 mythread 结构体&#xff0c;该结构体包含了机器人的当前模式 (mode) 和过渡过程的阶段 (residenceTransientProcess)。以下是对这…

PyTorch是使用GPU和CPU优化的深度学习张量库——torchvision

torchvision datasets torchvision.datasets 包含了许多标准数据集的加载器。例如&#xff0c;CIFAR10 和 ImageFolder 是其中两个非常常用的类。 CIFAR10 CIFAR10 数据集是一个广泛使用的数据集&#xff0c;包含10类彩色图像&#xff0c;每类有6000张图像&#xff08;5000张…

C++ 类和对象(上)

再C中&#xff0c;我们使用类定义自己的数据类型。通过定义新的类型来反映待解决的问题中的各种概念&#xff0c;可以使我们更容易编写&#xff0c;调试和修改程序。 类定义格式 首先类的定义格式和结构体差不多&#xff0c;而结构体的那一套语法也可以在C中使用。class是定义…

RC-u3 跑团机器人

这道题目要求我们模拟一个跑团机器人&#xff0c;解析玩家输入的包含骰子掷出和加减法运算的指令&#xff0c;计算出不同种类的骰子分别需要掷出几个&#xff0c;并根据输入指令得到可能的最小结果和最大结果。 题目分析 我们需要解析输入的表达式&#xff0c;处理其中的加法…

oracle数据库的plsql免安装版安装

这个是连接oracle数据库的&#xff0c;注意安装不能有中文路径。以下只是示例。 1、打开D:\ruanjian\plsql\plsql\plsql&#xff0c;发送plsqldev.exe快捷方式到桌面。 2、新弹出的页面填写cancel,什么也不写。 3、将instanceclient解压&#xff0c;并复制文件路径。 修改tool…

[Python学习篇] Python搭建静态web服务器

Python内置的web静态服务器 Python内置的http.server模块可以快速启动一个简单的HTTP服务器。 在Python 3中&#xff0c;打开命令行或终端&#xff0c;在你想要作为静态服务器根目录的文件夹下&#xff0c;运行以下命令&#xff1a; python -m http.server 8000 这将会在…

纯vue+js实现数字0到增加到指定数字动画效果功能

关于数字增加动画效果网上基本上都是借助第三方插件实现的,就会导致有的项目安装插件总会出问题,所有最好使用原生vue+js实现,比较稳妥 纯vue+js实现数字0到增加到指定数字动画效果功能 vue+js 实现数字增加动画功能 效果图 其中,关于数字变化的间隔时间,延时效果都可…

数据结构与算法 —— DFS的定义与原理

DFS&#xff08;Distributed File System&#xff0c;分布式文件系统&#xff09;是一种允许网络连接的多个计算机之间共享信息的系统架构。与传统的文件系统&#xff08;如NTFS、HFS等&#xff09;不同&#xff0c;DFS分布在多个文件服务器或多个位置&#xff0c;通过计算机网…

澳门建筑插画:成都亚恒丰创教育科技有限公司

澳门建筑插画&#xff1a;绘就东方之珠的斑斓画卷 在浩瀚的中华大地上&#xff0c;澳门以其独特的地理位置和丰富的历史文化&#xff0c;如同一颗璀璨的明珠镶嵌在南国海疆。这座城市&#xff0c;不仅是东西方文化交融的典范&#xff0c;更是建筑艺术的宝库。当画笔轻触纸面&a…

一个spring boot项目的启动过程分析

1、web.xml 定义入口类 <context-param><param-name>contextConfigLocation</param-name><param-value>com.baosight.ApplicationBoot</param-value> </context-param> 2、主入口类: ApplicationBoot,SpringBoot项目的mian函数 SpringBo…

时间序列学习篇

今天看了一些时间序列算法相关的文档和帖子。很惭愧&#xff0c;也是搞了很长时间预测算法的人了&#xff0c;但是都没能详细学习一下时间序列的理论。 首先&#xff0c;要预测一个时序问题&#xff0c;可以从什么路径解决呢&#xff1f;一种是认为过去序列状态影响将来的状态…