Motor paso a paso de control STM32: controlador ULN2003/controlador de motor paso a paso basado en interrupción del temporizador

Revisar

2023.04.24 Modificaciones: Se ha mejorado el siguiente programa y se ha agregado algo de contenido en el principio de funcionamiento.
Leí la pregunta señalada por un amigo en el área de comentarios y luego hice algunos pequeños cambios en el principio de funcionamiento y el programa en el artículo (las posiciones modificadas son: 1, 1 2; 3, 1; 5), para que mis amigos quienes lo hayan recopilado previamente pueden consultarlo, los archivos fuente del programa también se vuelven a cargar. Los pulsos necesarios para un círculo en este artículo se calculan como 4096 pulsos, pero de hecho, mi prueba personal es de 2048 pulsos y la salida del controlador es normal cuando se mide con un osciloscopio (1, 2). No está claro por qué . Para no engañar a otros amigos posteriores, déjame explicarte aquí primero. Si alguien sabe el motivo, las críticas son bienvenidas.

1. Controlador ULN2003

1. Principio de funcionamiento

La siguiente figura es el diagrama esquemático del controlador ULN2003.
inserte la descripción de la imagen aquí
El principio de este controlador es el principio de funcionamiento del motor paso a paso. Este artículo presenta: Motor paso a paso de control STM32: principio de funcionamiento y función de biblioteca (biblioteca estándar) / programa de control de biblioteca HAL (actualizado periódicamente)
uno tras otro. impulsa las 4 fases del motor para hacer girar el motor paso a paso. Cuando la entrada del controlador es de nivel bajo, el pin de salida correspondiente emite un nivel alto. Por el contrario, cuando la entrada es de nivel alto, la salida es de nivel bajo. Por lo tanto, cuando algunos pines salen en nivel alto, los pines correspondientes deben configurarse en nivel bajo y otros pines en nivel alto.

2. Cálculo del ángulo de paso y el número de pasos necesarios para un círculo.

El motor paso a paso de 4 fases y 5 cables utilizado en este artículo tiene un ángulo de paso de 5,625/64, por lo que el motor paso a paso debe realizar pasos de 360°/ángulo de paso por revolución, es decir, (360/5,625)*64 = 4096 pasos .
Aunque el cálculo es 4096 pulsos por círculo, de hecho, cuando lo uso, el motor gira con 2048 pulsos por círculo, así que usé un osciloscopio para probar si hay algún problema con el programa.
Indicado en círculos blancos como se muestra a continuación:
inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí

2. Conexión de hardware

Como se muestra en la imagen, recuerda compartir el terreno. Los 4 pines de control están definidos y referenciados en los archivos .h y .c del programa a continuación.
inserte la descripción de la imagen aquí

3. Programa de motor paso a paso de control de interrupción del temporizador STM32F103

El efecto de este programa es rotar hacia adelante durante 1 semana y luego retroceder 1 semana para regresar al origen. El procedimiento es el siguiente.

1. archivo .c

El siguiente es el archivo motor.c impulsado por el motor paso a paso :

#include "motor.h"

//num用于对引脚的索引,j用于计算步数,fx为电机旋转方向
unsigned short int num=0,j,fx;

void motor_GPIO_Init(void)
{
    
    
 
 GPIO_InitTypeDef  GPIO_InitStructure;
 	
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);	 //使能PB端口时钟
	
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8;
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //推挽输出
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		 //IO口速度为50MHz
 GPIO_Init(GPIOB, &GPIO_InitStructure);					 //根据设定参数初始化GPIOB
 GPIO_ResetBits(GPIOB,GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8);						 //PB.5/6/7/8 输出低电平
}

void TIM3_Int_Init(u16 arr,u16 psc)
{
    
    
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	NVIC_InitTypeDef NVIC_InitStructure;

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能

	TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 计数到5000为500ms
	TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为定时器时钟频率出书的预分频值 10KHZ的计数频率
	TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位

	TIM_ITConfig(  //使能或失能指定的TIM中断
		TIM3, //TIM
		TIM_IT_Update ,
		ENABLE  //使能
		);
	NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  //TIM3中断
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  //先占优先级1
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //从优先级3
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);  //初始化外设NVIC寄存器

	TIM_Cmd(TIM3, ENABLE);  //使能定时器外设
							 
}

static uint8_t GPIO_list[] = {
    
    0x01,0x02,0x04,0x08};     //对应驱动器4引脚,即电机4相

void TIM3_IRQHandler(void)   //TIM3中断(2ms)
{
    
    
	if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否,TIM中断源
		{
    
    
			TIM_ClearITPendingBit(TIM3, TIM_IT_Update);  //清除TIMx的中断处理位
			if(judge == 0)
			{
    
    
			  judge=0;
			}
			if(judge == 1)
			{
    
    
				 if(fx == 0)  //fx为电机旋转方向,fx=0时电机正转,fx=1时电机反转
		     {
    
    
					 motor_GPIO1 = ~(GPIO_list[num]&GPIO_list[0])>>0;  //判断是否为引脚1,然后将其数值向右移动0位至第1位,得到unsigned int类型时的1或0
					 motor_GPIO2 = ~(GPIO_list[num]&GPIO_list[1])>>1;  //判断是否为引脚2,然后将其数值向右移动1位至第1位,得到unsigned int类型时的1或0
					 motor_GPIO3 = ~(GPIO_list[num]&GPIO_list[2])>>2;  //判断是否为引脚3,然后将其数值向右移动1位至第1位,得到unsigned int类型时的1或0
					 motor_GPIO4 = ~(GPIO_list[num]&GPIO_list[3])>>3;  //判断是否为引脚4,然后将其数值向右移动1位至第1位,得到unsigned int类型时的1或0
			 	 }
				 if(fx == 1)
				 {
    
    
					 motor_GPIO4 = ~(GPIO_list[num]&GPIO_list[0])>>0;  //上述的反转
					 motor_GPIO3 = ~(GPIO_list[num]&GPIO_list[1])>>1;
					 motor_GPIO2 = ~(GPIO_list[num]&GPIO_list[2])>>2;
					 motor_GPIO1 = ~(GPIO_list[num]&GPIO_list[3])>>3;
				 }
				 num += 1;  //num用于对引脚的索引
				 j += 1;  //j用于计算步数
				 if(num == 4)  //到第4个GPIO后回到第1个GPIO
				 {
    
    
				   num = 0;
				 }
		     if(j == 2048&fx == 0)  //走完一圈同时是正转结束,对参数进行修改
		     {
    
    
					 j = 0;
					 fx = 1;
					 num = 0;
		     }
				 if(j == 2048&fx == 1)  //走完一圈同时是正反转结束,对参数进行修改
				 {
    
    
					 j = 0;
					 fx = 0;
					 start = 0;
					 num = 0;
				 }
			}
		}
}

2. archivo .h

El siguiente es el archivo motor.h impulsado por el motor paso a paso :

#ifndef __MOTOR_H
#define __MOTOR_H

#include "sys.h"
#include "delay.h"

void motor_GPIO_Init(void);//引脚初始化
void TIM3_Int_Init(u16 arr,u16 psc); //定时器初始化

#define motor_GPIO1 PBout(5)  //引脚定义
#define motor_GPIO2 PBout(6)  //引脚定义
#define motor_GPIO3 PBout(7)  //引脚定义
#define motor_GPIO4 PBout(8)  //引脚定义

extern u8 start;  //start为1时启动电机程序,为0时关闭
extern u8 judge;  //judge为1时电机开始旋转,为0时停止

#endif

3. Parte del programa main.c


u8 judge = 0;  //judge为1时电机开始旋转,为0时停止
u8 start = 0;  //start为1时启动电机程序,为0时关闭

void run(void)  //步进电机启动函数
{
    
    
	if(start == 1) {
    
    judge = 1;}
	else {
    
    judge = 0;}
}

//初始化后,只要给start赋值、把run()放进main里即可,也可在上述start里添加一些步进电机以外的程序

4. Demostración de efectos

Como se muestra en el vídeo a continuación:

El puerto serie SMT32 controla el controlador ULN2003 para accionar el motor paso a paso

5. Enlace del programa

El programa ha sido empaquetado y subido a los recursos de csdn.
CSDN: Función de biblioteca (biblioteca estándar) Controlador STM32F103C8T6 ULN2003/controlador de motor paso a paso basado en interrupción del temporizador
también se puede descargar a través del siguiente enlace:

Enlace: Enlace: https://pan.baidu.com/s/1rpUggpOruBFhwOHcfRon2w
Código de extracción: l70o

Soy estudiante y actualmente estoy estudiando. Este artículo puede considerarse como mis notas de estudio. Corríjame si me equivoco.

Supongo que te gusta

Origin blog.csdn.net/xztli/article/details/127158444
Recomendado
Clasificación