【专题STM32F103】步进电机控制 stm32 hal库版本
1.【专题STM32F103】FSMC+LCD+ ILI9341驱动程序+由标准库 修改为 HAL库+STM32F103霸道V2板2.【专题STM32F103】串口下载程序 +野火霸道开发板3.【专题STM32F103】HX711 测重传感器的采样值读取-HAL库版本4.【专题STM32F103】PB6接SCL,PB7接SDA,IIC通信访问 24C02, STM32F103的HAL版本5.【专题STM32F103】STM32+HAL库+SHT30温湿度传感器模块I2C通讯数字型
6.【专题STM32F103】步进电机控制 stm32 hal库版本
7.【专题STM32F103】四位阳数码管显示 stm32 HAL库8.【专题STM32F103】关于STM32Cube_FW_F1_V1.8.0内的example顶层程序设计逻辑 与 RTC_Calendar增补9.【专题STM32F103】移植STemWin5.44+ ILI9341显示无触摸屏 + cubemx+野火霸道V210.【专题STM32F03】FreeRTOS 队列queue传递结构体,野火例程代码简单修改。11.【专题STM32F03】 使用 STM32Cube\Repository\STM32Cube_FW_F1_V1.8.5 中例程由ST7735硬SPI串口屏修改驱动ST7789V硬SPI串口LCD屏步进电机工作原理简介(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 步进电机测试**/
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)