电机测试方法的介绍与功能实现(T测试方法)

2024-06-02 09:28

本文主要是介绍电机测试方法的介绍与功能实现(T测试方法),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

概述

1 理论介绍

2 实现原理

2.1 旋转式编码器原理

2.2 系统实现框图

2.3 测速原理 

2.4 计算速度值

3 STM32Cube配置项目

3.1 软件版本信息

3.2 配置项目

4 代码实现

4.1 电机速度控制

4.2 速度计算函数

4.3 功能实现

5 测试


概述

本文主要介绍测试电机速度方法(T测试方法)的实现原理与功能实现,笔者使用STM32F103芯片作为主控,并使用光电编码器作为测速装置,基于定时器和PWM实现电机速度测试和速度控制功能。还应该STM32Cube搭建项目实现测速的功能。

1 理论介绍

T 法:又叫做周期测量法。这种方法是建立一个已知频率的高频脉冲并对其计数,计数时间由捕获到的编码器相邻两个脉冲的间隔时间 T 决定,计数值为 M1。设编码器单圈总脉冲数为 C,高频脉冲的频率为 F0,则转速 n 的计算公式为:


公式中的参数介绍:

C:   编码器单圈总脉冲数

F0:  高频脉冲频率

M1:  编码器相邻两个脉冲的间隔时间计数

从公式可以看出,在电机高转速的时候,编码器脉冲间隔时间 TE 很小,使得测量周期内的高频脉冲计数值 M1 也变得很少,导致测量误差变大,而在低转速时, TE 足够大,测量周期内的 M1 也足够多,所以 T 法和 M 法刚好相反,更适合测量低速
 

2 实现原理

2.1 旋转式编码器原理

旋转编码器内部大都由码盘、光电检测装置和信号处理电路等部分构成。码盘上刻了若干圈线槽,线槽等距并且可透光,当码盘旋转时就会周期性的透过和遮挡来自光电检测装置的光线,这样检测装置就会周期性的生成若干电信号。但是这些电信号通常比较微弱,需要加入一套处理电路对信号进行放大和整形,最后把信号整形为脉冲信号并向外输出。

旋转式编码器的原理示例图:

2.2 系统实现框图

系统使用STM32F103作为主控芯片,TIMER-8定时器用于产生两路PWM信号驱动电机;使用IO 输入中断捕捉编码器的脉冲信号;TIMER-7产生高频信号用于统计两个编码器脉冲之间的高频脉冲个数。

2.3 测速原理 

参数介绍:

M0:  两个编码器脉冲之间的时间间隔

F0:  高频脉冲的个数

测速原理描述:

Step-1: 当M0上升沿时开启F0的计数

Step-2:    当M0第二次发生上升沿中断时,停止计数

2.4 计算速度值

已知参数:

轮胎直径(R): 6.8 (cm)

码盘细分数(一个周长):20个间隔

一个M0时间内测试到F0的:CNT

F0的周期为:    T(us)

计算公式如下:

V = (R/20)/(T*CNT)(cm/s)

3 STM32Cube配置项目

3.1 软件版本信息

软件名称版本信息
STM32CubeSTM32CubeMX 6.11
STM32 HALSTM32Cube_FW_F1_V1.8.5

3.2 配置项目

1)配置编码器IO,使能输入IO中断( External interrupt )

2)配置定时器计数中断,中断间隔时间为10us ( MCU系统工作时间为72M)

 

 3)定时器Timer-8产生PWM,其周期为10ms

 Timer-8的参数:

PWM的参数:

 

 配置参数完成后,就可以生成项目代码:

4 代码实现

4.1 电机速度控制

通过改变PWM的占空比来调整电机的转速,具体实现代码如下:

void pwm_ctrl_Init( void )
{HAL_TIM_Base_Stop( &htim8 );HAL_TIM_PWM_Start( &htim8, TIM_CHANNEL_1);    // PC6 HAL_TIM_PWM_Start( &htim8, TIM_CHANNEL_2);    // PC7HAL_TIM_SetPWM_Pulse( 1500, TIM_CHANNEL_1);HAL_TIM_SetPWM_Pulse( 0, TIM_CHANNEL_2);
}

4.2 速度计算函数

通过第二章节的原理可知,码盘间隔、轮胎直径、测试定时器频率已知。根据这些参数就能计算电机的转速。

#define  PI                             3.14159
#define  R                              6.8              // unit: cm
#define  DIV_CNT                        20
#define  CYCLE_TIME                     20               // us
#define  CYC_INTEV                     ((PI*R)/DIV_CNT)  //cm
#define  PARA                           CYC_INTEV*(1000000/CYCLE_TIME)#if 1#define pr_debug(fmt, args...)     printf("DEBUG: " fmt, ##args)
#else#define pr_debug(fmt, args...)
#endifstatic uint32_t mfreq_cnt = 0;
static bool enable_cnt = false;float  calculate_speeds( uint32_t cnt )
{float speeds;speeds = PARA/cnt;pr_debug("run count: %d, speeds: %0.3f cm/s\r\n", cnt, speeds);return  speeds;
}

4.3 功能实现

代码48行: 重新EXTI中断函数

代码52行: 判断码盘的脉冲

代码56行: 记录第一次的脉冲位置

代码62行: 记录第二次的脉冲位置

代码63行: 禁止计数

代码64行: 计算速度

代码71行:定时器计数函数,该函数被HAL_TIM_PeriodElapsedCallback调用

源代码:

#define  PI                             3.14159
#define  R                              6.8              // unit: cm
#define  DIV_CNT                        20
#define  CYCLE_TIME                     20               // us
#define  CYC_INTEV                      ((PI*R)/DIV_CNT)  //cm
#define  PARA                           CYC_INTEV*(1000000/CYCLE_TIME)#if 1#define pr_debug(fmt, args...)     printf("DEBUG: " fmt, ##args)
#else#define pr_debug(fmt, args...)
#endifstatic uint32_t mfreq_cnt = 0;
static bool enable_cnt = false;float  calculate_speeds( uint32_t cnt )
{float speeds;speeds = PARA/cnt;pr_debug("run count: %d, speeds: %0.3f cm/s\r\n", cnt, speeds);return  speeds;
}void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{static uint16_t trg_cn = 0;if( GPIO_Pin == INPUT_TRIGGER_Pin){switch( trg_cn ){default:case 0:mfreq_cnt = 0;trg_cn = 1;enable_cnt = true;break;case 1:enable_cnt = false;calculate_speeds(mfreq_cnt);trg_cn = 0;break;}}
}void HAL_TimerCnt( void )
{if( enable_cnt ){mfreq_cnt++;}
}

5 测试

1)测试1

 电机转速控制PWM 占空比配置为:1500/10000。测试得到的速度如下:

2)测试2

 电机转速控制PWM 占空比配置为:5000/10000。测试得到的速度如下:

 

这篇关于电机测试方法的介绍与功能实现(T测试方法)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1023577

相关文章

C++中unordered_set哈希集合的实现

《C++中unordered_set哈希集合的实现》std::unordered_set是C++标准库中的无序关联容器,基于哈希表实现,具有元素唯一性和无序性特点,本文就来详细的介绍一下unorder... 目录一、概述二、头文件与命名空间三、常用方法与示例1. 构造与析构2. 迭代器与遍历3. 容量相关4

C++中悬垂引用(Dangling Reference) 的实现

《C++中悬垂引用(DanglingReference)的实现》C++中的悬垂引用指引用绑定的对象被销毁后引用仍存在的情况,会导致访问无效内存,下面就来详细的介绍一下产生的原因以及如何避免,感兴趣... 目录悬垂引用的产生原因1. 引用绑定到局部变量,变量超出作用域后销毁2. 引用绑定到动态分配的对象,对象

SpringBoot基于注解实现数据库字段回填的完整方案

《SpringBoot基于注解实现数据库字段回填的完整方案》这篇文章主要为大家详细介绍了SpringBoot如何基于注解实现数据库字段回填的相关方法,文中的示例代码讲解详细,感兴趣的小伙伴可以了解... 目录数据库表pom.XMLRelationFieldRelationFieldMapping基础的一些代

Java HashMap的底层实现原理深度解析

《JavaHashMap的底层实现原理深度解析》HashMap基于数组+链表+红黑树结构,通过哈希算法和扩容机制优化性能,负载因子与树化阈值平衡效率,是Java开发必备的高效数据结构,本文给大家介绍... 目录一、概述:HashMap的宏观结构二、核心数据结构解析1. 数组(桶数组)2. 链表节点(Node

Java AOP面向切面编程的概念和实现方式

《JavaAOP面向切面编程的概念和实现方式》AOP是面向切面编程,通过动态代理将横切关注点(如日志、事务)与核心业务逻辑分离,提升代码复用性和可维护性,本文给大家介绍JavaAOP面向切面编程的概... 目录一、AOP 是什么?二、AOP 的核心概念与实现方式核心概念实现方式三、Spring AOP 的关

Python实现字典转字符串的五种方法

《Python实现字典转字符串的五种方法》本文介绍了在Python中如何将字典数据结构转换为字符串格式的多种方法,首先可以通过内置的str()函数进行简单转换;其次利用ison.dumps()函数能够... 目录1、使用json模块的dumps方法:2、使用str方法:3、使用循环和字符串拼接:4、使用字符

Linux下利用select实现串口数据读取过程

《Linux下利用select实现串口数据读取过程》文章介绍Linux中使用select、poll或epoll实现串口数据读取,通过I/O多路复用机制在数据到达时触发读取,避免持续轮询,示例代码展示设... 目录示例代码(使用select实现)代码解释总结在 linux 系统里,我们可以借助 select、

Linux挂载linux/Windows共享目录实现方式

《Linux挂载linux/Windows共享目录实现方式》:本文主要介绍Linux挂载linux/Windows共享目录实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录文件共享协议linux环境作为服务端(NFS)在服务器端安装 NFS创建要共享的目录修改 NFS 配

通过React实现页面的无限滚动效果

《通过React实现页面的无限滚动效果》今天我们来聊聊无限滚动这个现代Web开发中不可或缺的技术,无论你是刷微博、逛知乎还是看脚本,无限滚动都已经渗透到我们日常的浏览体验中,那么,如何优雅地实现它呢?... 目录1. 早期的解决方案2. 交叉观察者:IntersectionObserver2.1 Inter

Spring Gateway动态路由实现方案

《SpringGateway动态路由实现方案》本文主要介绍了SpringGateway动态路由实现方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随... 目录前沿何为路由RouteDefinitionRouteLocator工作流程动态路由实现尾巴前沿S