目录
概述
1 常用电机测速方法简介
1.1 方法概览
1.2 编码器测速方法
2 M法测速
2.1 理论描述
2.2 实现原理
2.3 速度计算方法
3 功能实现
3.1 功能介绍
3.2 代码实现
3.2.1 使用STM32Cube配置参数
3.2.2 脉冲计数功能
3.2.3 测速函数
4 测试
概述
本文主要介绍常用电机测速的一些方法,重点介绍频率测速方法的原理,并应用该理论搭建硬件平台,实现测速的方法。该平台采用STM32F103RC芯片,通过使用外部中断和定时器的相关功能,结合硬件的一些特性,实现了测试的功能。
1 常用电机测速方法简介
1.1 方法概览
常用的电机测速方法有以下几种:
-
非接触式测速方法:使用光电测速传感器或激光测速仪等装置,通过测量物体上特定标记的转动速度来计算电机的转速。
-
接触式测速方法:使用接触轮、接触针等装置,将其与电机的旋转部分相连,通过测量接触装置的运动来获取电机转速。
-
编码器测速方法:在电机轴上安装编码器,利用编码器的信号来测量电机的转速。编码器可以是光电编码器、磁性编码器等。
-
脉冲测速方法:通过测量电机输出的脉冲信号的频率来计算电机的转速。
-
轴承振动测速方法:通过测量电机轴承振动的频率和振幅来推断电机的转速。
1.2 编码器测速方法
这里重点介绍编码器测速方法,常用的编码器测速方法一般有三种:
频率测速方法: M 法
周期测速方法: T 法
频率/周期测速方法:M/T 法。
2 M法测速
2.1 理论描述
M法又叫做频率测量法。这种方法是在一个固定的定时时间内(以秒为单位),统计这段时间的编码器脉冲数,计算速度值。设编码器单圈总脉冲数为 C,在时间 T0 内,统计到的编码器脉冲数为 M0,则转速 n 的计算公式为:
参数介绍:
M0 : T0时间内的编码器脉冲数
C: 编码器单圈总脉冲数
T0: 单位时间
n: 转速
公式中的编码器单圈总脉冲数 C 是常数,所以转速 n 跟 M0 成正比。这就使得在高速测量时 M0变大,可以获得较好的测量精度和平稳性,但是如果速度很低,低到每个 T0 内只有少数几个脉冲,此时算出的速度误差就会比较大,并且很不稳定。也有一些方法可以改善 M 法在低速测量的准确性,例如:增量式编码器倍频技术就是其中一种,比如原本捕获到的脉冲 M0 只有4 个,经过 4 倍频后,相同电机状态 M0 变成了 16 个,也就提升了低速下的测量精度。
2.2 实现原理
M0: 表示基准时钟周期,一般为1s
T0: 表示在一个M0时间内计数的秒冲总数
该码盘一周总共有20个孔,则其将一个圆分为20个等分,在测速的时候。只需记录其在M0(1 second)时间内走过孔的个数T0,然后通过轮胎的周长与孔等分的关系,就能计算出速度。
根据轮胎的直径,计算出周长
光电感应器用于实现脉冲计数功能
2.3 速度计算方法
已知参数如下:
轮胎直径(R): 6.8 cm
码盘细分数(一个周长):20个间隔
1s时间内的码盘间隔数目:CNT
转速v = (π*R)/20 * CNT ( cm )
C代码实现:
/* USER CODE BEGIN 0 */
#define PI 3.14159
#define R 6.8 // unit: cm
#define DIV_CNT 20
static uint32_t trg_cn = 0;
/* USER CODE END 0 */
float calculate_speeds( uint32_t cnt )
{
float speeds;
speeds = ((PI*R)/20) * cnt;
return speeds;
}
3 功能实现
3.1 功能介绍
使用STM32F103芯片作为主控,光电编码器的输出引脚DQ接在MCU的IO引脚上,该IO配置为输入中断模式,即当DQ上有电平变化时,DQ即可产生一个脉冲,计数器的值加1,当计数时间达到M0时,停止计数。然后使用float calculate_speeds( uint32_t cnt ) 计算出当前的速度。
3.2 代码实现
3.2.1 使用STM32Cube配置参数
1)配置IO外部中断,用于捕捉光电编码信号
使能外部中断函数
2)配置定时器,用于产生10us的定时中断计数
使能定时器中断函数
3)完成参数配置后,点击GENERATE生成项目文件,打开项目如下:
3.2.2 脉冲计数功能
在外部中断的回调函数中实现脉冲计数功能,具体代码如下:
#define PI 3.14159
#define R 6.8 // unit: cm
#define DIV_CNT 20
static uint32_t trg_cn = 0;
/* USER CODE END 0 */
float calculate_speeds( uint32_t cnt )
{
float speeds;
speeds = ((PI*R)/20) * cnt;
return speeds;
}
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if( GPIO_Pin == INPUT_TRIGGER_Pin){
trg_cn++;
}
}
3.2.3 测速函数
通过使用外部中断记录的trg_cn值,再根据其他已知参数就能计算出速度值
void Calculate_Speeds( void )
{
motor_curSpeed = calculate_speeds( trg_cn );
pr_debug("run count: %d, speeds: %0.3f cm/s\r\n", trg_cn, motor_curSpeed);
trg_cn = 0;
}
在中断回调函数void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) 中调用void Calculate_Speeds( void )函数,调用的时间间隔为1s。实现代码如下:
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
/* USER CODE BEGIN Callback 0 */
/* USER CODE END Callback 0 */
if (htim->Instance == TIM6) {
HAL_IncTick();
}
/* USER CODE BEGIN Callback 1 */
// each count is 10 us
if (htim->Instance == TIM7) {
if( (count % 50000) == 0) // 500 ms
{
HAL_GPIO_TogglePin( STATUS_LED_GPIO_Port, STATUS_LED_Pin);
}
// calculate the mator speed
if( (count % 100000) == 0) // 1000 ms
{
Calculate_Speeds();
}
count++;
}
/* USER CODE END Callback 1 */
}
4 测试
使用串口终端接收速度数据值,其结构如下: