STM32控制步进电机:基于HAL库定时器中断的闭环步进电机驱动+精准控制脉冲数

这篇具有很好参考价值的文章主要介绍了STM32控制步进电机:基于HAL库定时器中断的闭环步进电机驱动+精准控制脉冲数。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、步进电机闭环驱动器

该篇文章中用到的步进电机闭环驱动器为Emm42_V4.0步进电机闭环驱动器。该闭环驱动器自带FOC矢量闭环控制算法,能实现力矩、速度、位置三环控制。
如下图所示,该42步进闭环电机驱动器的A+、A-、B+、B-连接步进电机,通过右侧的使能、脉冲、方向端对步进电机进行驱动控制。
hal步进电机,STM32步进电机,stm32,单片机,arm,嵌入式硬件

二、CubeMx配置

首先要进行时钟配置。

1、Clock Configuration

hal步进电机,STM32步进电机,stm32,单片机,arm,嵌入式硬件
配置时钟前要先打开Pinout & Configuration中的RCC,选择Crystal/Ceramic Resonator开启外部晶振。
再根据自己单片机的外部晶振频率设定参数,如下图所示。
hal步进电机,STM32步进电机,stm32,单片机,arm,嵌入式硬件

2、脉冲端 定时器配置

再次回到Pinout & Configuration,在Timers中选择一个你想要的定时器,这里我选择的是定时器2,然后打开内部时钟(Clock Source:Intermal Clock)。
在配置通道功能为PWM输出(PWM Generation)。这里我使用了4个步进电机,因此选择了4个通道。(下文视频只演示了一个步进电机,其他步进电机也是一样的道理,接线再补充程序就ok了)
再打开NVIC Settings使能定时器中断。如下图所示。
hal步进电机,STM32步进电机,stm32,单片机,arm,嵌入式硬件
接着,要根据你上一步设置的时钟和你的驱动器所能承载的频率,来设置该定时器的频率。
如我使用的驱动器最大脉冲频率是120KHZ,最高转速是2200+转,即我想要达到最高转速,可以配置1.8°步距角的步进电机为16细分,也就是(360 ÷ 1.8) × 16 = 3200个脉冲转一圈(这个下文控制脉冲数会提到),再用120K ÷ 3200 = 37.5转/s,即每分钟2250转。而如下图所示,我的tim2属于APB1,时钟设置是84MHZ。
hal步进电机,STM32步进电机,stm32,单片机,arm,嵌入式硬件
我使用的单片机为STM32F407,因此此处APB1总线对应了通用定时器tim2 ~ 5,基本定时器tim6、tim7,通用定时器tim12~14。APB2总线对应了高级定时器tim1、tim8,通用定时器tim9 ~ 11。
所以这里千万千万要小心不要把APB1的定时器时钟频率错当用成APB2的时钟频率了。
因此,以我的配置为例,使用84M ÷ 120K = 700,再用这个700对预分频系数和计数周期进行分配,如下图所示。这里为了后面设置PWM占空比的方便,把计数周期定为100,那么PSC则为7。
公式:PWM输出频率 = 定时器时钟频率 ÷ ((psc+1) × (arr + 1))。
hal步进电机,STM32步进电机,stm32,单片机,arm,嵌入式硬件

来用示波器检查一下频率和波形有没有问题,这里用到的程序在下面会详细讲到,占空比50%,频率120KHZ。
hal步进电机,STM32步进电机,stm32,单片机,arm,嵌入式硬件

3、使能、方向端 引脚配置

如下图所示,左键你想要使用的引脚配置为输出即可,非常简单。这里我使用了PC0-4作为使能端,PG0-4作为方向端,可根据需求选择不会占用你所需功能的引脚作为单纯的高低电平输出引脚。
hal步进电机,STM32步进电机,stm32,单片机,arm,嵌入式硬件
然后再进入Project Manager配置工程名字和编译环境、生成.c、.h文件等就ok了。

三、STM32F407定时器中断控制步进电机程序

先上张引脚配置图,程序看起来更清晰一点。

0、引脚配置图

引脚配置如下所示。
hal步进电机,STM32步进电机,stm32,单片机,arm,嵌入式硬件

1、使用到的HAL库函数

这两个函数的功能下文会有解释。

HAL_TIM_PWM_Stop(&htimx,TIM_CHANNEL_x);
HAL_TIM_PWM_Start(&htimx,TIM_CHANNEL_x);

2、脉冲触发定时器初始化配置

在CubeMx生成的工程中,只需根据之前设置的定时器找到初始化程序,然后在程序最后加入以下程序即可,但是要根据自己配置的定时器和通道进行参数配置。如设置的为定时器2,则Ctrl F搜索MX_TIM2_Init即可。

// 添加程序
	HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1);
	HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_2);
	HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_3);
	HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_4);

HAL_TIM_PWM_Start函数是启动PWM输出的函数,如上所示对应定时器2的4个通道。如下所示是我根据HAL库生成的初始修改后的初始化函数,把sConfigOC提出来是为了方便下面编写PWM设置函数,这两步都是必要的。

/* ============================== 步进电机脉冲触发定时器初始化 ============================== */

TIM_HandleTypeDef htim2;
TIM_OC_InitTypeDef Motor_PWM_sConfigOC = {0};

/* TIM2 init function */
void Motor_PWM_MX_TIM2_Init(void)
{

  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};

  htim2.Instance = TIM2;
  htim2.Init.Prescaler = 7-1;
  htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim2.Init.Period = 100-1;
  htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
  {
    Error_Handler();
  }
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_TIM_PWM_Init(&htim2) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  Motor_PWM_sConfigOC.OCMode = TIM_OCMODE_PWM1;
  Motor_PWM_sConfigOC.Pulse = 0;
  Motor_PWM_sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  Motor_PWM_sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  if (HAL_TIM_PWM_ConfigChannel(&htim2, &Motor_PWM_sConfigOC, TIM_CHANNEL_1) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_TIM_PWM_ConfigChannel(&htim2, &Motor_PWM_sConfigOC, TIM_CHANNEL_2) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_TIM_PWM_ConfigChannel(&htim2, &Motor_PWM_sConfigOC, TIM_CHANNEL_3) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_TIM_PWM_ConfigChannel(&htim2, &Motor_PWM_sConfigOC, TIM_CHANNEL_4) != HAL_OK)
  {
    Error_Handler();
  }

  HAL_TIM_MspPostInit(&htim2);
	
  HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1);
  HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_2);
  HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_3);
  HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_4);

}

3、步进电机脉冲设置

如下所示,拿步进电机1举例,先停止定时器2通道1的PWM输出,然后设置占空比,配置通道后再次开启PWM即可。HAL_TIM_PWM_Stop为停止定时器x通道x的PWM输出的函数。

void Motor1_pwm_Set(int motor1_n)
{
   HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_1);
   Motor_PWM_sConfigOC.Pulse = motor1_n;
   HAL_TIM_PWM_ConfigChannel(&htim2, &Motor_PWM_sConfigOC, TIM_CHANNEL_1);
   HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
}

4、步进电机使能、失能、改变方向

如下所示,配置高低电平即可。

void Motor1_enable(void)			// 电机1使能
{
	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_SET);
}
void Motor1_disable(void)			// 电机1失能
{
	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_RESET);
}
void Motor1_course(char course_mod)			// 电机1改变方向
{
	if(course_mod == 1){HAL_GPIO_WritePin(GPIOG, GPIO_PIN_0, GPIO_PIN_SET);}		// 正转
	else if(course_mod == 0){HAL_GPIO_WritePin(GPIOG, GPIO_PIN_0, GPIO_PIN_RESET);}			// 反转
}

5、步进电机正转main.c程序

启动步进电机1,设置占空比为50%,正转。

int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  /* USER CODE BEGIN 2 */
	Motor_PWM_MX_TIM2_Init();
	Motor_PWM_MX_TIM2_Init();	// 定时器初始化

	Motor1_pwm_Set(50);		// 设置占空比为50%(50/100)
	Motor1_course(1);		// 正转
	Motor1_enable();		// 使能
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */

  }
  /* USER CODE END 3 */
}

6、视频效果演示

步进电机控制

四、闭环步进电机 精准控制脉冲数

1、使用到的HAL库函数

同样的,这三个函数的功能下文也会有解释。

HAL_TIM_PWM_Start_IT(&htimx, TIM_CHANNEL_x);
HAL_TIM_PWM_Stop_IT(&htimx, TIM_CHANNEL_x);
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim);

2、更改步进电机驱动脉冲频率

首先设置步进电机细分步数为16,如下图所示,此处使用的是步距角为1.8°的步进电机。在这种参数配置的情况下,发送16个脉冲可转动1.8°,因此转动一圈所需的脉冲为(360° ÷ 1.8°) × 16 = 3200个脉冲。
hal步进电机,STM32步进电机,stm32,单片机,arm,嵌入式硬件
基于上文的步进电机驱动程序,我想把转速改为大概5转/s这样子,所以我们应当更改一下脉冲频率120KHZ。利用上述的一转3200脉冲,那么5转就需要16000个脉冲,因此将120KHZ改为16KHZ即可。那再计算一次PSC就是(84M ÷ 16K) ÷100 = 52.5。
将上文步进电机脉冲触发定时器初始化Motor_PWM_MX_TIM2_Init中的PSC改为53:

  htim2.Instance = TIM2;
  htim2.Init.Prescaler = 53-1;

同时也要删去之前的HAL_TIM_PWM_Start()函数,即删去以下程序:

  HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1);
  HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_2);
  HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_3);
  HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_4);

3、更改步进电机脉冲设置程序

因为我们不再使用HAL_TIM_PWM_Start和HAL_TIM_PWM_Stop,因此改程序也要删去这两个函数。以步进电机1为例,改为以下程序:

void Motor1_pwm_Set(int motor1_n)
{
   Motor_PWM_sConfigOC.Pulse = motor1_n;
   HAL_TIM_PWM_ConfigChannel(&htim2, &Motor_PWM_sConfigOC, TIM_CHANNEL_1);
}

当然值得注意的一点是,我们定义的这个函数现在没有了停止PWM的程序,所以我们一定要记得在更改PWM前要调用 HAL_TIM_PWM_Stop_IT 关闭定时器输出PWM

4、定时器PWM中断回调函数

在使用定时器中断之前,要记得在你的程序里重定义定时器的回调函数。
可选择把以下程序添加到你的stm32f4xx_it.c里:

/* USER CODE BEGIN 1 */
int PWM_num = 0;	// 脉冲数
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
{
	if(htim->Instance == htim2.Instance)	// 确认是否为步进电机脉冲中断的回调
	{
		PWM_num ++;
		if(PWM_num >= 3200)		// 第3200次(一圈)
		{
			PWM_num = 0;
			HAL_TIM_PWM_Stop_IT(&htim2, TIM_CHANNEL_1);		// 停止输出PWM
			//HAL_GPIO_TogglePin(GPIOF, GPIO_PIN_10);		// 翻转led灯电平 
		}
	}
}
/* USER CODE END 1 */

上述程序中可以看到PWM_num正在累加,每调用一次回调函数就会累加一次,我们会在main函数中调用一次 HAL_TIM_PWM_Start_IT 函数,大概猜一猜就能知道,该函数的用途就是开启定时器输出PWM,并且每发送一个脉冲就调用一次回调函数
如下图所示,箭头所指的函数HAL库已经帮我们写好了,会调用我们上述的中断回调函数。
hal步进电机,STM32步进电机,stm32,单片机,arm,嵌入式硬件

5、步进电机正转一圈闭环main.c程序

以下为main函数程序:

int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  /* USER CODE BEGIN 2 */
	Motor_PWM_MX_TIM2_Init();
	
	Motor1_pwm_Set(50);
	HAL_TIM_PWM_Start_IT(&htim2, TIM_CHANNEL_1);
	Motor1_course(1);
	Motor1_enable();

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

6、视频效果演示

闭环步进电机——精准控制脉冲数

五、程序链接

程序已经打包好上传到csdn的资源里了。
CSDN:HAL库STM32F407定时器中断控制步进电机程序
CSDN:HAL库STM32F407定时器中断控制闭环步进电机精准控制脉冲数
也可以通过以下链接下载:

STM32F407定时器中断控制步进电机程序
链接:https://pan.baidu.com/s/1svRzVW_7elkHg7wwQ4AN5A
提取码:hpzq
STM32F407定时器中断控制闭环步进电机精准控制脉冲数
链接:https://pan.baidu.com/s/1QIyusKAbusqyMl_VTkjKxg
提取码:4rml

本人是一名学生,目前正在学习中,本篇文章也算是我的学习笔记,如有错误的话还请指正。文章来源地址https://www.toymoban.com/news/detail-791133.html

到了这里,关于STM32控制步进电机:基于HAL库定时器中断的闭环步进电机驱动+精准控制脉冲数的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 基于STM32闭环步进电机控制系统设计

    ** 单片机设计介绍,1654基于STM32闭环步进电机控制系统设计(仿真,程序,说明)   基于STM32的闭环步进电机控制系统设计是一种利用STM32微控制器开发的系统,用于实现对步进电机的精确控制。以下是该系统的一般设计概述: STM32微控制器:作为主控芯片,STM32具备高性能

    2024年02月08日
    浏览(35)
  • STM32基于CAN总线协议控制步进电机

    如上图所示,实现了以下功能: 1.两块stm32单片机通过CAN控制器与收发器进行半双工通信; 2.stm32主机通过检测按键,切换不同的模式,将不同模式的case值发送给stm32从机; 3.stm32从机根据收到的case值,控制步进电机进行不同的运动操作; 4.OLED用于显示收发内容与按键状态等

    2024年01月19日
    浏览(38)
  • 基于STM32CUBEMX驱动低压步进器电机驱动器STSPIN220(3)----定时器中断产生指定数量脉冲

    在步进电机控制过程中,为了实现精确的位置和速度控制,经常需要输出指定数量的脉冲。这就需要使用定时器功能来生成PWM脉冲信号。本文将详细介绍如何利用STM32CUBEMX配置定时器以输出指定数量的PWM脉冲。 定时器是STM32微控制器的一个重要功能模块,可用于生成各种定时

    2024年02月14日
    浏览(39)
  • 毕业设计——基于STM32的智能家具系统(语音识别控制、步进电机、舵机)

    智能家具系统分为两个不同版本系列: ①系列一:手机app远程控制、远程检测温湿度显示在app,(云平台)!!!!                   https://blog.csdn.net/m0_59113542/article/details/123737710 ②系列二:语音识别控制-------本文章 硬件采购链接: 步进电机及相关驱动 ULN2003步进电机驱动

    2024年02月05日
    浏览(39)
  • STM32+A4988拓展板+HAL实现简单42步进电机驱动

    1.A4988及其拓展板简介 2.接线 3.STM32_CUBEMX配置 4.代码详解 ——————————————————————————————————————————— 1.A4988及其拓展板简介 A4988 A4988拓展板     A4988是一款常用的步进电机驱动器,A4988驱动器采用了步进电机的微步技术,能

    2024年01月22日
    浏览(71)
  • STM32控制42步进电机

    首先采用TB6600驱动外接12VDC电源。 STM32选c8t6最小系统板 接线TB6600跟32接线有共阴级接法(把ENA-,DIR-,PUL-与32共地)也有共阳接法(把ENA+,DIR+,PUL+与32共地)。这里选共阴级接法。 判断42步进电机的4根线哪两根是A相(A-和A+),哪两根是B相(B-和B+),方法:将任意两根线短接起来

    2024年02月16日
    浏览(62)
  • STM32控制四个步进电机(包含运行程序)

    软件: keil 5(其他版本也ok) 硬件: 步进电机(我用的是42)×4;单片机开发板(本例使用STM32F407ZGT6);电机驱动器×4;外部按键;杜邦线。 实验效果: 四个步进电机对应四个外部按键,按下对应的外部按键选择需要控制的电机。 在开发板上按下KEYO,步进电机以500HZ的频率

    2024年04月29日
    浏览(30)
  • 基于STM32的步进电机驱动设计

    程序源码提取链接放置文章底部,自行提取即可。 采用STM32驱动28BYJ4步进电机,实现正转反转,完成角度调整。步进电机是一种将电脉冲转化为角位移的执行机构。当步进驱动器接收到一个脉冲信号,它就驱动步进电机按设定的方向转动------一个固定的角度(及步进角)。可以

    2024年02月02日
    浏览(49)
  • 【STM32】步进电机及其驱动(ULN2003驱动28BYJ-48丨按键控制电机旋转)

    参考文章与课程:   【视频课程】步进电机基础原理和应用——程子华主讲   【视频课程】电机系列教学视频(基于STM32硬件)——野火   【霄耀在努力】STM32驱动步进电机(原理、程序、解决电机只震动不转动问题)   步进控制系统由以下三个部分组成: 控制器

    2023年04月09日
    浏览(38)
  • AS5600步进电机编码器(原理图+pcb+stm32控制代码)

    AS5600是一个易于编程的磁性旋转位置传感器,具有高分辨率的12位模拟或PWM输出。这种非接触式系统测量一个直径磁化的轴上磁铁的绝对角度。 引脚如下图 他有两种供电模式:5V和3.3V 我们为了和stm32F103C8T6单片机的电压一致,也使用3.3V供电,然后开始画PCB。 使用嘉立创EDA画

    2024年02月03日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包