Moteur pas à pas de contrôle STM32 : pilote de moteur pas à pas ULN2003 basé sur une interruption de minuterie
Réviser
2023.04.24 Modifications : Le programme suivant a été amélioré et du contenu dans le principe de fonctionnement a été ajouté.
J'ai lu la question signalée par un ami dans la zone de commentaires, puis j'ai apporté quelques petites modifications au principe de fonctionnement et au programme dans l'article (les positions modifiées sont : 1, 1 2 ; 3, 1 ; 5), afin que les amis ceux qui l'ont déjà collecté peuvent s'y référer, les fichiers sources du programme sont également re-téléchargés. Les impulsions requises pour un cercle dans cet article sont calculées comme 4096 impulsions, mais en fait, mon test personnel est de 2048 impulsions, et la sortie du pilote est normale lorsqu'elle est mesurée avec un oscilloscope (1, 2). On ne sait pas pourquoi . Afin de ne pas induire en erreur d'autres amis ultérieurs, permettez-moi d'abord de vous expliquer ici. Si quelqu'un en connaît la raison, les critiques sont les bienvenues.
1. Pilote ULN2003
1. Principe de fonctionnement
La figure ci-dessous est le diagramme schématique du pilote ULN2003.
Le principe de ce pilote est le principe de fonctionnement du moteur pas à pas.Cet article présente: Moteur pas à pas de contrôle STM32: principe de fonctionnement et fonction de bibliothèque (bibliothèque standard) / programme de contrôle de bibliothèque HAL (mis à jour de temps en temps) l'
un après l'autre La broche entraîne les 4 phases du moteur pour faire tourner le moteur pas à pas. Lorsque l'entrée du pilote est de niveau bas, la broche de sortie correspondante produit un niveau haut. À l'inverse, lorsque l'entrée est de niveau haut, la sortie est de niveau bas. Par conséquent, lorsque certaines broches sont émises à un niveau élevé, les broches correspondantes doivent être définies comme un niveau bas et les autres broches comme un niveau élevé.
2. Calcul de l'angle de pas et du nombre de pas requis pour un cercle
Le moteur pas à pas quadriphasé à 5 fils utilisé dans cet article a un angle de pas de 5,625/64, le moteur pas à pas doit donc prendre des pas de 360°/angle de pas par tour, c'est-à-dire (360/5,625)*64 = 4096 étapes .
Bien que le calcul soit de 4096 impulsions par cercle, en fait, lorsque je l'utilise, le moteur tourne à 2048 impulsions par cercle, j'ai donc utilisé un oscilloscope pour tester s'il y avait un problème avec le programme.
Indiqué par des cercles blancs comme indiqué ci-dessous :
2. Connexion matérielle
Comme le montre la photo, pensez à partager le terrain. Les 4 broches de contrôle sont définies et référencées dans les fichiers .h et .c du programme ci-dessous.
3. Programme de moteur pas à pas de contrôle d'interruption de minuterie STM32F103
L'effet de ce programme est de tourner en avant pendant 1 semaine puis en arrière 1 semaine pour revenir à l'origine. La procédure est la suivante.
1. fichier .c
Voici le fichier motor.c piloté par le moteur pas à pas :
#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. fichier .h
Voici le fichier motor.h piloté par le moteur pas à pas :
#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. Une partie du programme 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. Démonstration d'effet
Comme le montre la vidéo ci-dessous :
Le port série SMT32 contrôle le pilote ULN2003 pour piloter le moteur pas à pas
5. Lien du programme
Le programme a été empaqueté et téléchargé sur les ressources de csdn.
CSDN : Fonction de bibliothèque (bibliothèque standard) Pilote STM32F103C8T6 ULN2003/pilote de moteur pas à pas basé sur l'interruption de minuterie
peut également être téléchargé via le lien suivant :
Lien : Lien : https://pan.baidu.com/s/1rpUggpOruBFhwOHcfRon2w
Code d'extraction : l70o
Je suis étudiant et j'étudie actuellement. Cet article peut être considéré comme mes notes d'étude. Veuillez me corriger si je me trompe.