问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

电机转速计算(基于码盘和IO外部中断)

创作时间:
作者:
@小白创作中心

电机转速计算(基于码盘和IO外部中断)

引用
CSDN
1.
https://blog.csdn.net/mftang/article/details/139172089

本文主要介绍使用STM32微控制器通过外部IO中断和定时器实现电机转速的测量。文章详细介绍了硬件结构、测速原理、软件框架设计以及具体的代码实现,适合对嵌入式系统和电机控制感兴趣的读者。

概述

本文主要介绍使用外部IO中断和内部定时器,实现电机转速的测试功能。基于码盘和光电测速传感器,使用STM32F103内部定时器的功能,完成测试功能设计。文章介绍其实现原理,设计方法,并基于STM32Cube软件配置参数和生成工程。完成所有的软硬件功能。

1 硬件介绍

1.1 整体硬件结构

光电测试器位置

测速码盘位置

1.2 模块功能介绍

1)测试传感器

工作原理:

当模块中的槽无遮挡时,接收管导通,DQ输出为低电平

当槽被遮挡时,DQ输出为高电平。

2)码盘

该码盘一周总共有20个孔,则其将一个圆分为20个等分,在测速的时候。只需记录其在1s时间内走过孔的个数,然后通过轮胎的周长与孔等分的关系,就能计算出速度。

3)轮胎参数

根据参数可得,轮胎的直径为:6.8cm

2 测速框架介绍

2.1 测速原理

1)IO EXIT: 输入性IO中断,当有脉冲发生时,会产生一个外部中断,在该中断的回调函数中实现计数功能,没进入一次中断,计数加1。

2)TIME6:实现1ms的定时功能,在其内部实现一个1s计数功能,当计数count=1000时,此时计时时间为1s,读取IO EXIT中的计数值。

3)根据计数值和轮胎的周长,就可以计算出转速值

2.2 软件框架结构

3 使用STM32Cube配置Project

3.1 准备环境

软件名称 版本信息

STM32Cube STM32CubeMX 6.11

STM32 HAL STM32Cube_FW_F1_V1.8.5

3.2 配置参数

1)配置外部IO中断,设置为上升沿触发模式

  1. 配置计数定时器,定时中断触发时间为1ms

3)PWM输出配置

输出端口配置

IO端口配置

PWM相关的参数

PWM CH1 ~ CH4端口参数,每个端口参数相同,以CH1为例,介绍参数配置

3.3 生成Project

配置完成参数后,点击GENERATE生成工程,打开文件如下:

4 功能实现

4.1 电机控制代码

使用PWM控制电机转速,CH1和CH2控制电机的转向,所以需要配置这两个输出端口的输出特性。其实现代码如下:


void pwm_ctrl_Init( void )
{
    HAL_TIM_Base_Start( &htim8 );
    HAL_TIM_PWM_Start( &htim8, TIM_CHANNEL_1);
    HAL_TIM_PWM_Start( &htim8, TIM_CHANNEL_2);
     
    HAL_TIM_SetPWM_Pulse( 0, TIM_CHANNEL_1);
    HAL_TIM_SetPWM_Pulse( 2000, TIM_CHANNEL_2);
}  

4.2 测试代码

在外部中断回调函数中实现计数功能。在定时器计数到1s的时刻,记录下该值,用于计算转速。


static uint32_t trg_cn = 0;
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
  if( GPIO_Pin == INPUT_TRIGGER_Pin){
        trg_cn++;
  }
}
void Calculate_Speeds( void )
{
    printf("run count: %d \r\n", trg_cn);
    trg_cn = 0;
}  

4.3 速度计算

已知参数如下:

轮胎直径(R): 6.8 cm

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

1s时间内的码盘间隔数目:CNT

转速v = (π*R)/20 * CNT ( cm )

代码实现:


 /* 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;
}  

打印数据函数


void Calculate_Speeds( void )
{
    float speeds;
    
    speeds = calculate_speeds( trg_cn );
    printf("run count: %d, speeds: %0.3f cm/s\r\n", trg_cn, speeds);
    trg_cn = 0;
}  

5 测试

5.1 编写测试代码

在定时器的回调函数中调用打印计数函数:void Calculate_Speeds( void )

5.2 运行代码

使用串口将测试出来的数据打印出来,在PC山使用串口终端接收数据。

测试硬件结构

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号