【专题STM32F103】步进电机控制 stm32 hal库版本
步进电机工作原理简介(28BYJ-48)
https://www.bilibili.com/read/cv11379422?spm_id_from=333.999.0.0
内有详细介绍,要先看!!!

驱动例程代码
头文件
#ifndef __MOTOR_H #define __MOTOR_H #include "main.h" ////位带操作,实现51类似的GPIO控制功能 ////具体实现思想,参考<<CM3权威指南>>第五章(87页~92页). ////IO口操作宏定义 //#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2)) //#define MEM_ADDR(addr) *((volatile unsigned long *)(addr)) //#define BIT_ADDR(addr, bitnum) MEM_ADDR(BITBAND(addr, bitnum)) ////IO口地址映射 //#define GPIOA_ODR_Addr (GPIOA_BASE+12) //0x4001080C //#define GPIOB_ODR_Addr (GPIOB_BASE+12) //0x40010C0C //#define GPIOC_ODR_Addr (GPIOC_BASE+12) //0x4001100C //#define GPIOD_ODR_Addr (GPIOD_BASE+12) //0x4001140C //#define GPIOE_ODR_Addr (GPIOE_BASE+12) //0x4001180C //#define GPIOF_ODR_Addr (GPIOF_BASE+12) //0x40011A0C //#define GPIOG_ODR_Addr (GPIOG_BASE+12) //0x40011E0C //#define GPIOA_IDR_Addr (GPIOA_BASE+8) //0x40010808 //#define GPIOB_IDR_Addr (GPIOB_BASE+8) //0x40010C08 //#define GPIOC_IDR_Addr (GPIOC_BASE+8) //0x40011008 //#define GPIOD_IDR_Addr (GPIOD_BASE+8) //0x40011408 //#define GPIOE_IDR_Addr (GPIOE_BASE+8) //0x40011808 //#define GPIOF_IDR_Addr (GPIOF_BASE+8) //0x40011A08 //#define GPIOG_IDR_Addr (GPIOG_BASE+8) //0x40011E08 // ////IO口操作,只对单一的IO口! ////确保n的值小于16! //#define PAout(n) BIT_ADDR(GPIOA_ODR_Addr,n) //输出 //#define PAin(n) BIT_ADDR(GPIOA_IDR_Addr,n) //输入 //#define PBout(n) BIT_ADDR(GPIOB_ODR_Addr,n) //输出 //#define PBin(n) BIT_ADDR(GPIOB_IDR_Addr,n) //输入 //#define PCout(n) BIT_ADDR(GPIOC_ODR_Addr,n) //输出 //#define PCin(n) BIT_ADDR(GPIOC_IDR_Addr,n) //输入 //#define PDout(n) BIT_ADDR(GPIOD_ODR_Addr,n) //输出 //#define PDin(n) BIT_ADDR(GPIOD_IDR_Addr,n) //输入 //#define PEout(n) BIT_ADDR(GPIOE_ODR_Addr,n) //输出 //#define PEin(n) BIT_ADDR(GPIOE_IDR_Addr,n) //输入 //#define PFout(n) BIT_ADDR(GPIOF_ODR_Addr,n) //输出 //#define PFin(n) BIT_ADDR(GPIOF_IDR_Addr,n) //输入 //#define PGout(n) BIT_ADDR(GPIOG_ODR_Addr,n) //输出 //#define PGin(n) BIT_ADDR(GPIOG_IDR_Addr,n) //输入 void motor_init(void);// 初始化 void motor_single_four_beat(uint8_t direction);// 单四拍 控制电机 void motor_double_four_beat(uint8_t direction);// 双四拍 控制电机 void motor_four_phase_eight_beat(uint8_t direction);// 四相八拍 控制电机 void motor_stop(void); void motor_start_run(uint16_t angle, uint8_t direction, uint8_t mode) ; //电机角度,0顺时针,1逆时针,节拍模式 #endif
源文件
#include "motor.h" void motor_init(void)// 初始化 { GPIO_InitTypeDef GPIO_InitStruct = {0}; __HAL_RCC_GPIOA_CLK_ENABLE ( ); GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); } /*****************************************************************/ #define MOTOR_A_H PAout(4) = 1 #define MOTOR_A_L PAout(4) = 0 #define MOTOR_B_H PAout(5) = 1 #define MOTOR_B_L PAout(5) = 0 #define MOTOR_C_H PAout(6) = 1 #define MOTOR_C_L PAout(6) = 0 #define MOTOR_D_H PAout(7) = 1 #define MOTOR_D_L PAout(7) = 0 /*****************************************************************/ void motor_start_run(uint16_t angle, uint8_t direction, uint8_t mode) //电机角度 { int i = 0; // 查看28BYJ-48步进电机, 步距角=5.625°/64,其意思就是 // 每64个脉冲步进电机集成的变速器输出轴就会转5.625度。 int pulse = (int)((double)(angle/5.625)*64); if( mode == 0x48) // 四相八拍 { for(i=0; i<pulse; i++){ motor_four_phase_eight_beat(direction); HAL_Delay(2);//延时2ms,修改延时可改变电机转动速度。即修改了脉冲频率 } } if( mode == 0x14) // 单四拍 { pulse = pulse/2;// 脉冲数折半 for(i=0; i<pulse; i++){ motor_single_four_beat(direction); HAL_Delay(2);//延时2ms,修改延时可改变电机转动速度。即修改了脉冲频率 } } if( mode == 0x24) // 双四拍 { pulse = pulse/2;// 脉冲数折半 for(i=0; i<pulse; i++){ motor_double_four_beat(direction); HAL_Delay(2);//延时2ms,修改延时可改变电机转动速度。即修改了脉冲频率 } } } /*****************************************************************/ void motor_four_phase_eight_beat(uint8_t direction)// 四相八拍 控制电机 { static uint8_t step = 0; if(1 == direction){//反转,逆时针 if(0 == step) step = 8; step--; } if(0 == step){//步序1 MOTOR_A_H; MOTOR_B_L; MOTOR_C_L; MOTOR_D_L; }else if(1 == step){//步序2 MOTOR_A_H; MOTOR_B_H; MOTOR_C_L; MOTOR_D_L; }else if(2 == step){//步序3 MOTOR_A_L; MOTOR_B_H; MOTOR_C_L; MOTOR_D_L; }else if(3 == step){//步序4 MOTOR_A_L; MOTOR_B_H; MOTOR_C_H; MOTOR_D_L; }else if(4 == step){//步序5 MOTOR_A_L; MOTOR_B_L; MOTOR_C_H; MOTOR_D_L; }else if(5 == step){//步序6 MOTOR_A_L; MOTOR_B_L; MOTOR_C_H; MOTOR_D_H; }else if(6 == step){//步序7 MOTOR_A_L; MOTOR_B_L; MOTOR_C_L; MOTOR_D_H; }else if(7 == step){//步序8 MOTOR_A_H; MOTOR_B_L; MOTOR_C_L; MOTOR_D_H; } if(0 == direction){//正转,顺时针 step++; if(8 == step) step = 0; } } /*****************************************************************/ void motor_single_four_beat(uint8_t direction)// 单四拍 控制电机 { static uint8_t step = 0; if(1 == direction){//反转 if(0 == step) step = 4; step--; } if(0 == step){//步序1 MOTOR_A_H; MOTOR_B_L; MOTOR_C_L; MOTOR_D_L; }else if(1 == step){//步序2 MOTOR_A_L; MOTOR_B_H; MOTOR_C_L; MOTOR_D_L; }else if(2 == step){//步序3 MOTOR_A_L; MOTOR_B_L; MOTOR_C_H; MOTOR_D_L; }else if(3 == step){//步序4 MOTOR_A_L; MOTOR_B_L; MOTOR_C_L; MOTOR_D_H; } if(0 == direction){//正转 step++; if(4 == step) step = 0; } } /*****************************************************************/ void motor_double_four_beat(uint8_t direction)// 双四拍 控制电机 { static uint8_t step = 0; if(1 == direction){//反转 if(0 == step) step = 4; step--; } if(0 == step){//步序1 MOTOR_A_H; MOTOR_B_L; MOTOR_C_L; MOTOR_D_H; }else if(1 == step){//步序2 MOTOR_A_H; MOTOR_B_H; MOTOR_C_L; MOTOR_D_L; }else if(2 == step){//步序3 MOTOR_A_L; MOTOR_B_H; MOTOR_C_H; MOTOR_D_L; }else if(3 == step){//步序4 MOTOR_A_L; MOTOR_B_L; MOTOR_C_H; MOTOR_D_H; } if(0 == direction){//正转 step++; if(4 == step) step = 0; } } /*****************************************************************/ void motor_stop(void) { //四相输出都为低电平是,电机停止工作 MOTOR_A_L; MOTOR_B_L; MOTOR_C_L; MOTOR_D_L; }
测试代码
/**步进电机测试**/ motor_init();// 初始化 motor_start_run(90, 1, 0x14); //电机角度90,逆时针,单四拍 motor_start_run(90, 0, 0x48); //电机角度90,顺时针,四相八拍 motor_start_run(90, 1, 0x24); //电机角度90,逆时针,双四拍 motor_start_run(90, 0, 0x48); //电机角度90,顺时针,四相八拍 motor_stop(); /**END 步进电机测试**/

浙公网安备 33010602011771号