【一文搞懂】—带霍尔编码器的直流有刷减速电机
文章目录
- 一、直流有刷电机
- 二、减速比
- 三、霍尔编码器
- 3.1 霍尔编码器
- 3.2 霍尔编码器测速原理
- 四、测速程序设计
- 4.1 跳变沿检测
- 4.2 计算转速
一、直流有刷电机
宏观上说直流有刷电机由固定部分(定子)和旋转部分(转子)组成。在定子上装有两个励磁的磁极N和S。在其转子部分有电枢铁芯。电枢铁芯上有绕组线圈,线圈的首尾接有两个圆弧形铜片,称为换向片。两个换向片之间互相绝缘。换向片固定在转轴上,换向片与转轴之间也相互绝缘。换向器上固定着一对电刷,电刷与换向器互相接触。绕组线圈通过换向片和电刷与电源连接。下面是直流有刷电机的结构图。
电机是怎么转起来的呢?
这时候就要搬出我们高中所学的物理知识了,因为电机能转起来,离不开一个力——安培力。
首先复习一下安培力,主要是知道什么是安培力以及如何判断安培力的方向。通电导线在磁场中受到的作用力叫做安培力。判断安培力的方向我们用到左右定则,什么是左手定则?伸开左手,使拇指与其他四指垂直且在一个平面内,让磁感线从手心流入,四指指向电流方向,大拇指指向的就是安培力方向(即导体受力方向)。
有的资料上可能说是洛伦兹力,磁场对运动电荷的作用力称为洛伦兹力,安培力是洛伦兹力的宏观表现。
了解了上面的知识,我们开始正式探讨电机是怎么转起来的。
看上面的电机结构图,如果外部电源上正下负接到电刷两边,那么绕组线圈中的电流方向为顺时针,我们来对绕组线圈做一个受力分析。
电流方向垂直于磁场方向的部分是不受安培力作用的,也就是上图的蓝色部分。上图的红色部分中我们用左手定则分析一下受力。根据左手定则,上半部分受到垂直屏幕向内的安培力。下半部分受到垂直屏幕向外的安培力。上下两部分受力相反,这时电机就转起来了。同理,如果改变外部电源的接入方向,改成上负下正,上下两部分受力依旧相反,电机依旧可以转动,只不过转动方向相反。
至此,我们了解了直流有刷电机的转动原理以及如何控制正反转。
二、减速比
首先回答一个问题,为什么要有减速电机?
用简单几个字总结一下,为什么会有减速电机?目的是降低转速,增加扭矩。至于到底是怎么降低转速,增加扭矩,我们继续往后看。
什么是减速比?
用到减速电机我们难免会碰到一个概念——减速比。那么什么叫减速比?首先我们先看一下减速电机内部的结构。
减速电机内部有两个齿轮,一个是转自连接轴上的齿轮,一个是输出主轴上的齿轮。转子转动N圈,主轴转动一圈,这就实现了降低转速。比如我们常见的1:30减速比的减速电机,就是转子转动30圈,主轴转动一圈。如此一来,就实现了降低转速,增加扭矩的目的。减速比就是小齿轮数比大齿轮数的比值。
扭矩实际可以理解为电机转动的力量。如果我们不使用减速电机,拿一个小马达,我们会发现它转的很快,但是很容易用手捏住制动,力量很小。但是如果是减速电机,我们发现转速比较慢,但是我们需要用比制动小马达更大的力来制动。减速比越大,电机转动的力越大。
举一个更加常见的例子,比如我们的山地车。我们上坡时可以调节变速器,让我们用很轻松的力就能上坡,实际就是上面的原理,我们蹬好多圈,车轮才能转一圈,但是我们用的力小了,如果把我们和变速器看作一个电机,实际也就是扭矩大了。
三、霍尔编码器
3.1 霍尔编码器
什么是编码器?
编码器是把角位移或直线位移转换成电信号的一种装置。
编码器按照工作原理,可以分为增量式编码器和绝对式编码器,绝对式编码器的每一个位置对应一个确定的数字码(二进制数)。增量式编码器就是每转过单位的角度就发出一个脉冲信号。
从编码器检测原理上来分,还可以分为光学式、磁式、感应式、电容式。我们常见的是光电编码器(光学式)和我们要介绍的主角霍尔编码器(磁式)。一般来说光电编码器是霍尔编码器精度的几十倍。
编码器的作用。
了解了什么是编码器,那么我们用编码器有什么实际作用呢?通常我们会使用编码器来检测电机的转速和旋转方向。那我们常用的控制算法PID算法来说,PID算法是为了实现闭环控制,要想实现闭环控制,就需要有一个反馈。我们的编码器测得的转速就可以作为反馈,搭配PID算法,实现转速的闭环控制。
霍尔编码器的工作原理。
其实从上面的介绍就能大概了解到编码器的工作原理。我们这次主要介绍对象是霍尔编码器。霍尔编码器由码盘和霍尔元件组成。霍尔码盘与电机主轴同轴,码盘上等分的分布有多个磁极,电机转动时,霍尔元件会输出若干个脉冲信号,我们正是利用这些脉冲信号实现电机的测速和电机转向的判断。
霍尔编码器的线数。
什么是霍尔编码器的线数?转动一圈我们会产生几个脉冲,取决于编码器的线数。比如我们的霍尔编码器线数为13。那么霍尔编码器的码盘旋转一圈,会产生13个脉冲。
3.2 霍尔编码器测速原理
我们正是通过检测霍尔编码器输出的脉冲信号来测速。通常会有三相输出,A、B和Z。A和B的输出是正交的。Z是用来标记旋转一周的起始位置,我们通常不使用。
如何判断电机转向?
我们通过A相出现脉冲时检测B相电平来判断电机旋转方向。
- A检测到上升沿脉冲时,B为低电平,正转;
- A检测到上升沿脉冲时,B为高电平,反转;
如何判断电机转速?
我们通过检测单位时间内产生的脉冲数来确定电机转速。为什么可以这么做?因为电机转动一圈产生的脉冲数是确定的。比如我们有一个减速比为1:30的减速电机,霍尔编码器的线数为13。那么霍尔码盘旋转一圈,产生13个脉冲,霍尔码盘旋转30圈,电机主轴旋转一圈。综上所述,电机主轴旋转一圈会产生13 * 30 = 390个脉冲。注意,这里是只检测A相的上升沿脉冲,电机旋转一圈有390个脉冲。
有的小伙伴可能会疑问,是转一圈A和B一共产生390个脉冲,还是A和B都产生390个脉冲?答案是后者。
接下来我们只需要检测单位时间内A相或者B相输出的脉冲数,就可以计算电机转速了。
四倍频
什么是四倍频?由上面的介绍可知,霍尔编码器输出有A相和B相两条线。我们如果只用A相,检测高电平脉冲数,那么就是上面介绍的那种。如果我们A相和B相都检测,而且不止检测上升沿脉冲,也检测下降沿脉冲,那么此时霍尔码盘旋转一圈会产生四倍于之前的脉冲数。这就是所谓的四倍频。利用四倍频可以提高检测精度。
四、测速程序设计
上面介绍了这么多理论知识,下面我们动手来实现一下利用霍尔编码器,用一个1:30减速比的减速电机,来实现测速。
4.1 跳变沿检测
检测跳变沿可以用两种方法,一种是使用外部中断,另一种是使用定时器的输入捕获功能。这里使用的是外部中断,只检测A相输出的上升沿,因此只需要配置一个引脚的外部中断,来检测上升沿并在中断中进行计数即可。外部中断初始化函数与中断服务函数如下
/**==============================================================================*函数名称:Exit_Init*函数功能:初始化外部中断*输入参数:无*返回值:无*备 注:无*==============================================================================*/
void Exit_Init (void)
{// 定义结构体NVIC_InitTypeDef NVIC_InitStructure;EXTI_InitTypeDef EXTI_InitStructure;GPIO_InitTypeDef GPIO_InitStructure;// 开启时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOE,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); // 开启AFIO时钟GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource0); //选择GPIO管脚用作外部中断线路// 配置GPIO结构体GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; // 下拉输入GPIO_Init(GPIOB, &GPIO_InitStructure);GPIO_SetBits(GPIOB,GPIO_Pin_0);//EXTI0 NVIC 配置NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; //EXTI0中断通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1; //抢占优先级NVIC_InitStructure.NVIC_IRQChannelSubPriority =3; //子优先级NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器EXTI_InitStructure.EXTI_Line=EXTI_Line0; // EXIT0EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt; // 中断EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Rising; // 上升沿触发EXTI_InitStructure.EXTI_LineCmd=ENABLE; // 使能EXTI_Init(&EXTI_InitStructure);
}
/**==============================================================================*函数名称:EXTI0_IRQHandler*函数功能:外部中断0中断服务函数*输入参数:无*返回值:无*备 注:无*==============================================================================*/
u32 gCunt = 0; // A相上升沿计数变量void EXTI0_IRQHandler(void)
{// 如果EXIT0中断标志位被置1if(EXTI_GetITStatus (EXTI_Line0)==1){gCunt = gCunt + 1;}EXTI_ClearITPendingBit (EXTI_Line0); // 清除中断标志位
}
4.2 计算转速
知道了怎么检测跳变沿并计数,我们就可以进行下一步,单位时间内读取跳变沿计数值。我们初始化一个定时器来进行时间控制。配置每一秒进入一次中断,读取一次跳变沿计数值,然后计算转速。转速的单位是RPM,也就是转每分。我们用一秒的脉冲计数乘以60,认为是一分钟的脉冲数,以此来计算电机转速。定时器配置函数以及中断服务函数如下
/**==============================================================================*函数名称:TIM2_Iint*函数功能:初始化定时器2*输入参数:per:自动重装载值;psc:预分频系数*返回值:无*备 注:无*==============================================================================*/
void TIM3_Iint (u16 per,u16 psc)
{// 结构体定义TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;NVIC_InitTypeDef NVIC_InitStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); // 使能TIM2时钟TIM_TimeBaseInitStructure.TIM_Period = per; // 自动装载值TIM_TimeBaseInitStructure.TIM_Prescaler = psc; // 分频系数TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; // 不分频TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; // 设置向上计数模式TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE); // 开启定时器中断TIM_ClearITPendingBit(TIM3,TIM_IT_Update); // 使能更新中断NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; // 定时器中断通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3; // 抢占优先级NVIC_InitStructure.NVIC_IRQChannelSubPriority =4; // 子优先级NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // IRQ通道使能NVIC_Init(&NVIC_InitStructure); TIM_Cmd(TIM3,ENABLE); // 使能定时器
}// TIM3中断服务函数
// 1s进入一次
u32 gSpeed = 0; // 转速void TIM3_IRQHandler(void) // TIM3中断
{if(TIM_GetITStatus(TIM3,TIM_IT_Update)){gSpeed = (gCunt * 60) / (30 * 13);printf ("Speed = %d = RPM\r\n",gSpeed);gCunt = 0; // 清零上升沿计数变量}TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
}
该文章会绑定一个资源,资源是通过串口输入占空比,范围是0~999,然后串口会打印电机转速。电机驱动模块使用的是TB6612。关于TB6612,可以查看博主STM32外设系列专栏。
相关文章:

【一文搞懂】—带霍尔编码器的直流有刷减速电机
文章目录 一、直流有刷电机二、减速比三、霍尔编码器3.1 霍尔编码器3.2 霍尔编码器测速原理 四、测速程序设计4.1 跳变沿检测4.2 计算转速 一、直流有刷电机 宏观上说直流有刷电机由固定部分(定子)和旋转部分(转子)组成。在定子上…...

滴水逆向三期笔记与作业——02C语言——05 正向基础/05 循环语句
目录 一、缓冲区溢出的HelloWorld二、永不停止的HelloWorld三、基础知识3.1 变量的声明3.2 类型转换(一般用于小转大)3.3 表达式3.4 语句和程序块3.5 参数与返回值3.6 关系运算符3.7 逻辑运算符:&& || !3.8 单目运算符3.9 三目运算符…...
Python抓取分享页面的源代码示例
本文章是关于利用Python方法来抓取某网站分享页面中的源码方法示例。需要大家注意的是Python抓取分享页面的源代码示例,是要在运行时导入BeautifulSoup.py文件后才可以使用。 Python抓取分享页面的源代码示例,需要用到python urllib2模块方法࿰…...

linux安装nginx遇到的报错
1、Linux如何修改只读文件(以设置自动连网为例) vim /etc/sysconfig/network-scripts/ifcfg-ens33 然后提示 E45:已设定选项“readonly”(请加!强制执行) 如果需要强制修改,可以使用࿰…...
一起学SF框架系列5.8-spring-Beans-Bean注解解析3-解析配置component-scan
本文主要讲述Spring是如何解析“context:component-scan”元素,扫描加载目录下的BeanDefinition。 解析内容 1、解析的元素如下: <!-- 注解模式:配置bean扫描路径(注:自动包含子路径) --><conte…...

【LeetCode热题100】打卡第42天:滑动窗口最大值搜索二维矩阵II
文章目录 【LeetCode热题100】打卡第42天:滑动窗口最大值&搜索二维矩阵II⛅前言 滑动窗口最大值🔒题目🔑题解 搜索二维矩阵II🔒题目🔑题解 【LeetCode热题100】打卡第42天:滑动窗口最大值&搜索二维…...

[uni-app] 微信小程序 - 组件找不到/导入报错 (分包问题导致)
文章目录 问题表现问题原因 问题表现 切换了个路径下的组件, 导入失败, 尝试了清缓存\重启\删项目等一些列操作均无效 上面两个路径中, 都存在一模一样的videItem.vue Main路径是可以导入的 Main路径是无法导入的 问题原因 后来发现, 是 分包的问题导致. 我们先来假设一个场…...

从零构建医疗领域知识图谱的KBQA问答系统:其中7类实体,约3.7万实体,21万实体关系。
项目设计集合(人工智能方向):助力新人快速实战掌握技能、自主完成项目设计升级,提升自身的硬实力(不仅限NLP、知识图谱、计算机视觉等领域):汇总有意义的项目设计集合,助力新人快速实…...

编程小白的自学笔记十二(python爬虫入门四Selenium的使用实例二)
系列文章目录 编程小白的自学笔记十一(python爬虫入门三Selenium的使用实例详解) 编程小白的自学笔记十(python爬虫入门二实例代码详解) 编程小白的自学笔记九(python爬虫入门代码详解) 目录 系列文章…...
技术笔记2023076 rBoot学习7
技术笔记2023076 rBoot学习7 继续之前的学习。 代码分析:函数find_image() // prevent this function being placed inline with main // to keep mains stack size as small as possible // dont mark as static or itll be optimised out when // using the ass…...

收藏这6个抠图工具,一键抠图不用愁!
在图片编辑工作中,抠图是设计师常用的操作。随着设计工具的不断增加,抠图操作摆脱了过去繁琐的操作步骤,几乎可以一键完成。今天本文将为大家介绍6个好用的抠图工具,一起来看看吧! 1、皮卡智能抠图 皮卡智能抠图是一…...

四,Eureka 第四章
2.1.3 增加依赖 <!--添加依赖--><dependencies><!--Eureka Server--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId></dependency>&l…...

k8s常见的资源对象使用
目录 一、kubernetes内置资源对象 1.1、kubernetes内置资源对象介绍 1.2、kubernetes资源对象操作命令 二、job与cronjob计划任务 2.1、job计划任务 2.2、cronjob计划任务 三、RC/RS副本控制器 3.1、RC副本控制器 3.2、RS副本控制器 3.3、RS更新pod 四、Deployment副…...

JavaScript 简单实现观察者模式和发布订阅模式
JavaScript 简单实现观察者模式和发布订阅模式 1. 观察者模式1.1 如何理解1.2 代码实现 2. 发布订阅模式2.1 如何理解2.2 代码实现 1. 观察者模式 1.1 如何理解 概念:观察者模式定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时ÿ…...

高通WLAN框架学习(37)-- TDLS(Tunneled Direct Link Setup)通道直接链路建立
一 TDLS概述 隧道直连设置(TDLS)基于IEEE 802.11z-2010IEEE标准802.11z标准(无线局域网介质访问控制(MAC)和物理层(PHY)规范。 TDLS允许与同一AP关联的设备之间建立直接链路。Wi-Fi Direct允许设备之间直接连接,而不需要AP。Wi-Fi联盟认证可用于IEEE 802.11a和802.11g设备的T…...

高算力AI模组前沿应用:基于ARM架构的SoC阵列式服务器
本期我们带来高算力AI模组前沿应用,基于ARM架构的SoC阵列式服务器相关内容。澎湃算力、创新架构、异构计算,有望成为未来信息化社会的智能算力底座。 ▌性能优势AI驱动,ARM架构服务器加速渗透 一直以来,基于ARM架构的各类处理器…...

老年公寓人员定位管理系统:提升安全与关怀的智能解决方案
老年公寓作为提供安全居住环境和关怀服务的重要场所,面临着人员管理和安全控制的挑战。为了解决这些问题,老年公寓人员定位管理系统应运而生。基于为提供全面的安全管理和个性化关怀服务,华安联大便通过老年公寓人员定位管理系统的技术原理、…...
每日一题之两个字符串的删除操作
题目链接 给定两个单词 word1 和 word2 ,返回使得 word1 和 word2 **相同所需的最小步数。 每步 可以删除任意一个字符串中的一个字符。 示例 1: 输入: word1 "sea", word2 "eat" 输出: 2 解释: 第一步将 "sea" 变…...

nacos安装与基础配置
源码 https://github.com/alibaba/nacos https://gitee.com/mirrors/Nacos 编译 git clone https://github.com/alibaba/nacos.git cd nacos/ mvn -Prelease-nacos -Dmaven.test.skiptrue clean install -U ls -al distribution/target/// change the $version to your ac…...

GitHub Copilot:让开发编程变得像说话一样简单
引用: 人类天生就梦想、创造、创新。但今天,我们花太多时间被繁重的工作所消耗,花在消耗我们时间、创造力和精力的任务上。为了重新连接我们工作的灵魂,我们不仅需要一种更好的方式来做同样的事情,更需要一种全新的工…...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)
说明: 想象一下,你正在用eNSP搭建一个虚拟的网络世界,里面有虚拟的路由器、交换机、电脑(PC)等等。这些设备都在你的电脑里面“运行”,它们之间可以互相通信,就像一个封闭的小王国。 但是&#…...

springboot 百货中心供应链管理系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,百货中心供应链管理系统被用户普遍使用,为方…...

简易版抽奖活动的设计技术方案
1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...

通过Wrangler CLI在worker中创建数据库和表
官方使用文档:Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后,会在本地和远程创建数据库: npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库: 现在,您的Cloudfla…...
Java如何权衡是使用无序的数组还是有序的数组
在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八
现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet,点击确认后如下提示 最终上报fail 解决方法 内核升级导致,需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...
线程与协程
1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指:像函数调用/返回一样轻量地完成任务切换。 举例说明: 当你在程序中写一个函数调用: funcA() 然后 funcA 执行完后返回&…...

html-<abbr> 缩写或首字母缩略词
定义与作用 <abbr> 标签用于表示缩写或首字母缩略词,它可以帮助用户更好地理解缩写的含义,尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时,会显示一个提示框。 示例&#x…...

回溯算法学习
一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...
【Go语言基础【12】】指针:声明、取地址、解引用
文章目录 零、概述:指针 vs. 引用(类比其他语言)一、指针基础概念二、指针声明与初始化三、指针操作符1. &:取地址(拿到内存地址)2. *:解引用(拿到值) 四、空指针&am…...