STM32驱动步进电机(HAL库)

一、基础配置

首先完成cubemx的基础配置。如下图所示

二、定时器配置

这里采用定时器2通道1来产生PWM波,配置如下。

定时器PWM的计算方法如下。

为方便代码函数的封装先采用84-1的预分频,即84MHZ除以84得到1MHZ。自动重装载值先随便写一个20000-1后续代码会更改,然后占空比是不影响步进电机的速度的,我们默认百分之五十即可,即下方PWM选择自动重装载值的一半即可。我们还要打开定时器中断,方便后续计数控制圈数。

接着,步进电机需要一个使能引脚和一个方向引脚,这里选择两个GPIO口输出就行了。这里选择PA2和PC0,可以根据需要更改IO口,然后直接生成代码就行。

三、步进电机

步进电机需要驱动器来驱动,这里我选择的是ATK-2MD5050这种驱动器。这种驱动器右侧有拨码开关,我们可以通过拨码开关的不同来选择模式。上面的Microstep是细分步数,下面我将解释一下,我们的步进电机上面会有信息,我这里使用的1.8°四线两相的步进电机,电流为1.7A。1.8°的意思就是满足一些脉冲数其转动的角度,即步距角。

我们知道一圈的度数是360°,那么360°除以1.8°得到200,这个200就是我们转一圈所需要的脉冲数,就是需要200个高低电平的PWM。即200个周期的PWM。这里我选择了16细分,即200乘以16=3200,3200才是我所需要的脉冲个数,即3200个脉冲信号。后续代码我也是以16细分来编写的。即SW1 SW2 SW3 SW4 满足ON OFF ON ON

接着,电机额定电流是1.7A,将开关打成2A即可 就是SW5 SW6 SW7 SW8 满足ON OFF OFF OFF

然后是驱动器右侧一栏,我们看控制信号那一栏,其中ENA+ DIR+ PUL+我们接上5V的电压就行了,然后ENA-的意思就是使能引脚,我们选择上面配置的GPIO口,这里我选择的是PC0来控制,高电平使能,低电平失能。

那么同理,大家应该就知道DIR-就是控制方向的了,我选择的是PA2来控制,高电平和低电平分别控制正转和反转。

最下面的呢,A+ A- B+ B- 是接步进电机四根线的,其中一相就是两根线,如果电机上有信息直接接上就行了对应的线。如果没有,大家可以把其中的线两两接触,如果转不动,那么就是一相的,接上去就行了。

到这里驱动器和步进电机就介绍完了。

四、代码编写

代码这里只讲解主要部分。

如果我们想要写一个驱动去控制步进电机转动的速度,我们就要明白,控制步进电机速度的是PWM波形的频率,那么上面的公式我们已经知道如何计算频率和周期了,这里我写的是让步进电A机转一圈需要多少秒来控制步进电机的速度的。我们不改变预分频系数和驱动器的细分步长来控制变量,那么现在未知量就是用户输入的几秒钟,我们设为X变量,还有通过X得到需要改变的ARR即重装载值,设为Y,两个变量满足什么关系呢?不难得到PWM波形频率的倒数就是周期T,我们已知3200的脉冲数是固定的,那么就有以下的关系式,从而得到X与Y的关系,我们写成代码即可。其中的X是我们要输入的参数即多少秒转一圈,其中的Y就是我们需要更改的重装载值,从而去改变PWM输入的周期,从而改变转速。

上面,我们已经实现了如何控制速度,那么如何控制圈数呢?我们只需要在定时中断里面,进行计数就可以了,因为3200个脉冲转一圈是固定的数,我们只需要读取定时器中断里面的数值除以3200,就知道现在过去了几圈。再进行比较的if语句,就能实现控制了。这里我用KE1表示按键按下,大家知道即可。记得使能中断函数。

这里只介绍主要函数的由来,代码放在下面自取。

http://通过网盘分享的文件:Paper count.zip 链接: https://pan.baidu.com/s/1SJf5ogEy3rZhWaAnjx-uoQ?pwd=94y6 提取码: 94y6 --来自百度网盘超级会员v4的分享

#ifndef  __motor_H__
#define __motor_H__

#include "stm32f4xx_hal.h"
#include "tim.h"
#include "gpio.h"

extern int num;
extern float arr;
extern int key1;
	
void Motro1_PWM_Start(void);//初始化PWM
				
void Motor1_enable(void);//PC0使能

void Motor1_disable(void);//PC0失能

void Motor1_course(char course_mod);//PA2正转反转

void Motor1_Speed(float speed);//1圈所耗时间 使用16细分计算 占空比默认百分之五十

void Motro1_angle(int Angle,float TTIME);  //参数1为圈数 参数2为速度


#endif

#include "motor.h"
#include "tim.h"
int num=0;
int key1=1;//按键按下给标志位1 先默认为0 后续更改
float arr=0;
TIM_OC_InitTypeDef Motor_PWM_sConfigOC = {0};
//TIM_HandleTypeDef htim2;
//初始化步进电机PWM
void Motro1_PWM_Start(void)
{
	HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1); //串口2通道1 可修改其他串口
	
}

//步进电机使能 PC0
void Motor1_enable(void)
{
	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_SET); 
	
}
//步进电机失能 PC0
void Motor1_disable(void)
{
	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_RESET); 
	
}
//步进电机正转反转 PA2正转反转
void Motor1_course(char course_mod)
{
	if(course_mod == 1){HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_SET);}		// 正转
	else if(course_mod == 0){HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET);}			// 反转
}
//控制电机速度 1圈几秒
void Motor1_Speed(float time)
{
	arr = 312.5f*time;
	__HAL_TIM_SET_AUTORELOAD(&htim2, arr);
	__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, arr/2);
}
//参数1圈数 参数2速度
void Motro1_angle(int Angle,float TTIME)
{	
	if(key1==1)
	{
		Motor1_Speed(TTIME);
		if(Angle<=(num/3200))
		{
			HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_RESET); 
			num=0;
			key1=0;
		}
	}
}

//定时器中断函数 用于计算圈数
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if (htim == (&htim2))
    {
			if(key1==1)
			{
				num ++;
			}
    }
}

### STM32 HAL驱动DM420步进电机实现精确控制 #### GPIO引脚初始化 为了使STM32能够发送信号到DM420步进电机驱动器,首先需要配置GPIO引脚作为输出模式。这可以通过HAL中的`__HAL_RCC_GPIOA_CLK_ENABLE()`启用相应的GPIO时钟,并设置具体的引脚功能来完成[^1]。 ```c // 启用GPIOA时钟 __HAL_RCC_GPIOA_CLK_ENABLE(); // 配置GPIO引脚为推挽输出模式 GPIO_InitTypeDef GPIO_InitStruct = {0}; GPIO_InitStruct.Pin = GPIO_PIN_0; // 使用PA0作为示例 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); ``` #### 定时器PWM配置 利用定时器生成PWM波形可以有效控制步进电机的速度和方向。这里以TIM2为例展示如何配置定时器产生PWM信号[^2]: ```c // 初始化定时器结构体并配置参数 TIM_HandleTypeDef htim2; void MX_TIM2_Init(void) { TIM_ClockConfigTypeDef sClockSourceConfig = {0}; TIM_MasterConfigTypeDef sMasterConfig = {0}; htim2.Instance = TIM2; htim2.Init.Prescaler = 8399; // 设置预分频值 htim2.Init.CounterMode = TIM_COUNTERMODE_UP; htim2.Init.Period = 999; // 自动重装载寄存器周期值 htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; HAL_TIM_Base_Init(&htim2); sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig); sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig); } // 开启PWM通道 HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1); ``` #### 主程序逻辑设计 在主循环里加入必要的延时处理以及状态切换机制,从而达到精准操控的目的。例如改变占空比调整转速或者反转极性更改旋转方向等操作均可以在这一部分实现[^3]。 ```c int main(void) { HAL_Init(); SystemClock_Config(); // 系统时钟配置 MX_GPIO_Init(); // 初始化GPIO MX_TIM2_Init(); // 初始化TIM2 while (1) { HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET); // 输出高电平给步进电机前进指令 __HAL_TIM_SetCompare(&htim2,TIM_CHANNEL_1,500); // 调整比较匹配值影响速度 HAL_Delay(1000); // 延迟一秒 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET); // 切换至低电平让其停止或倒退 __HAL_TIM_SetCompare(&htim2,TIM_CHANNEL_1,700); // 修改数值再次测试不同效果 HAL_Delay(1000); } } ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值