步进电机控制 stm32 hal库版本

发布时间 2023-05-16 22:42:36作者: 辛河

步进电机工作原理简介(28BYJ-48)

https://www.bilibili.com/read/cv11379422?spm_id_from=333.999.0.0

 

驱动例程代码 

 1 #ifndef __MOTOR_H
 2 #define __MOTOR_H
 3 #include "main.h"
 4 
 5 ////位带操作,实现51类似的GPIO控制功能
 6 ////具体实现思想,参考<<CM3权威指南>>第五章(87页~92页).
 7 ////IO口操作宏定义
 8 //#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2)) 
 9 //#define MEM_ADDR(addr)  *((volatile unsigned long  *)(addr)) 
10 //#define BIT_ADDR(addr, bitnum)   MEM_ADDR(BITBAND(addr, bitnum)) 
11 ////IO口地址映射
12 //#define GPIOA_ODR_Addr    (GPIOA_BASE+12) //0x4001080C 
13 //#define GPIOB_ODR_Addr    (GPIOB_BASE+12) //0x40010C0C 
14 //#define GPIOC_ODR_Addr    (GPIOC_BASE+12) //0x4001100C 
15 //#define GPIOD_ODR_Addr    (GPIOD_BASE+12) //0x4001140C 
16 //#define GPIOE_ODR_Addr    (GPIOE_BASE+12) //0x4001180C 
17 //#define GPIOF_ODR_Addr    (GPIOF_BASE+12) //0x40011A0C    
18 //#define GPIOG_ODR_Addr    (GPIOG_BASE+12) //0x40011E0C    
19 
20 //#define GPIOA_IDR_Addr    (GPIOA_BASE+8) //0x40010808 
21 //#define GPIOB_IDR_Addr    (GPIOB_BASE+8) //0x40010C08 
22 //#define GPIOC_IDR_Addr    (GPIOC_BASE+8) //0x40011008 
23 //#define GPIOD_IDR_Addr    (GPIOD_BASE+8) //0x40011408 
24 //#define GPIOE_IDR_Addr    (GPIOE_BASE+8) //0x40011808 
25 //#define GPIOF_IDR_Addr    (GPIOF_BASE+8) //0x40011A08 
26 //#define GPIOG_IDR_Addr    (GPIOG_BASE+8) //0x40011E08 
27 // 
28 ////IO口操作,只对单一的IO口!
29 ////确保n的值小于16!
30 //#define PAout(n)   BIT_ADDR(GPIOA_ODR_Addr,n)  //输出 
31 //#define PAin(n)    BIT_ADDR(GPIOA_IDR_Addr,n)  //输入 
32 
33 //#define PBout(n)   BIT_ADDR(GPIOB_ODR_Addr,n)  //输出 
34 //#define PBin(n)    BIT_ADDR(GPIOB_IDR_Addr,n)  //输入 
35 
36 //#define PCout(n)   BIT_ADDR(GPIOC_ODR_Addr,n)  //输出 
37 //#define PCin(n)    BIT_ADDR(GPIOC_IDR_Addr,n)  //输入 
38 
39 //#define PDout(n)   BIT_ADDR(GPIOD_ODR_Addr,n)  //输出 
40 //#define PDin(n)    BIT_ADDR(GPIOD_IDR_Addr,n)  //输入 
41 
42 //#define PEout(n)   BIT_ADDR(GPIOE_ODR_Addr,n)  //输出 
43 //#define PEin(n)    BIT_ADDR(GPIOE_IDR_Addr,n)  //输入
44 
45 //#define PFout(n)   BIT_ADDR(GPIOF_ODR_Addr,n)  //输出 
46 //#define PFin(n)    BIT_ADDR(GPIOF_IDR_Addr,n)  //输入
47 
48 //#define PGout(n)   BIT_ADDR(GPIOG_ODR_Addr,n)  //输出 
49 //#define PGin(n)    BIT_ADDR(GPIOG_IDR_Addr,n)  //输入
50 
51 
52 void motor_init(void);// 初始化
53 void motor_single_four_beat(uint8_t direction);// 单四拍 控制电机
54 void motor_double_four_beat(uint8_t direction);// 双四拍 控制电机
55 void motor_four_phase_eight_beat(uint8_t direction);// 四相八拍 控制电机
56 
57 
58 void motor_stop(void);
59 
60 void motor_start_run(uint16_t angle, uint8_t direction, uint8_t mode) ; //电机角度
61 #endif
头文件

源文件

  1 #include "motor.h"
  2 
  3 void motor_init(void)// 初始化
  4 {
  5    GPIO_InitTypeDef GPIO_InitStruct = {0};
  6   __HAL_RCC_GPIOA_CLK_ENABLE (  );
  7      
  8     GPIO_InitStruct.Mode  = GPIO_MODE_OUTPUT_PP;
  9   GPIO_InitStruct.Pull  = GPIO_NOPULL;
 10   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
 11 
 12   GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
 13   HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 14 }
 15 
 16 /*****************************************************************/
 17 
 18 #define MOTOR_A_H PAout(4) = 1
 19 #define MOTOR_A_L PAout(4) = 0
 20 
 21 #define MOTOR_B_H PAout(5) = 1
 22 #define MOTOR_B_L PAout(5) = 0
 23 
 24 #define MOTOR_C_H PAout(6) = 1
 25 #define MOTOR_C_L PAout(6) = 0
 26 
 27 #define MOTOR_D_H PAout(7) = 1
 28 #define MOTOR_D_L PAout(7) = 0
 29 /*****************************************************************/
 30 void motor_start_run(uint16_t angle, uint8_t direction, uint8_t mode) //电机角度
 31 {
 32     int i = 0;
 33     // 查看28BYJ-48步进电机, 步距角=5.625°/64,其意思就是
 34     // 每64个脉冲步进电机集成的变速器输出轴就会转5.625度。
 35     int pulse = (int)((double)(angle/5.625)*64); 
 36         if( mode == 0x48)    
 37         {
 38             for(i=0; i<pulse; i++){
 39                 motor_four_phase_eight_beat(direction);
 40                 HAL_Delay(2);//延时2ms,修改延时可改变电机转动速度。即修改了脉冲频率
 41             }
 42         }
 43         if( mode == 0x14)    // 单四拍
 44         {
 45              pulse = pulse/2;// 脉冲数折半
 46             for(i=0; i<pulse; i++){
 47                 motor_single_four_beat(direction);
 48                 HAL_Delay(2);//延时2ms,修改延时可改变电机转动速度。即修改了脉冲频率
 49             }
 50         }
 51         if( mode == 0x24)    // 双四拍
 52         {             
 53             pulse = pulse/2;// 脉冲数折半
 54             for(i=0; i<pulse; i++){
 55                 motor_double_four_beat(direction);
 56                 HAL_Delay(2);//延时2ms,修改延时可改变电机转动速度。即修改了脉冲频率
 57            }    
 58       }            
 59 }
 60         
 61 /*****************************************************************/        
 62 void motor_four_phase_eight_beat(uint8_t direction)// 四相八拍 控制电机
 63 {
 64     static uint8_t step = 0;
 65     if(1 == direction){//反转
 66         if(0 == step) step = 8;
 67         step--;
 68     }
 69     if(0 == step){//步序1
 70         MOTOR_A_H;
 71         MOTOR_B_L;
 72         MOTOR_C_L;
 73         MOTOR_D_L;
 74     }else if(1 == step){//步序2
 75         MOTOR_A_H;
 76         MOTOR_B_H;
 77         MOTOR_C_L;
 78         MOTOR_D_L;
 79     }else if(2 == step){//步序3
 80         MOTOR_A_L;
 81         MOTOR_B_H;
 82         MOTOR_C_L;
 83         MOTOR_D_L;
 84     }else if(3 == step){//步序4
 85         MOTOR_A_L;
 86         MOTOR_B_H;
 87         MOTOR_C_H;
 88         MOTOR_D_L;
 89     }else if(4 == step){//步序5
 90         MOTOR_A_L;
 91         MOTOR_B_L;
 92         MOTOR_C_H;
 93         MOTOR_D_L;
 94     }else if(5 == step){//步序6
 95         MOTOR_A_L;
 96         MOTOR_B_L;
 97         MOTOR_C_H;
 98         MOTOR_D_H;
 99     }else if(6 == step){//步序7
100         MOTOR_A_L;
101         MOTOR_B_L;
102         MOTOR_C_L;
103         MOTOR_D_H;
104     }else if(7 == step){//步序8
105         MOTOR_A_H;
106         MOTOR_B_L;
107         MOTOR_C_L;
108         MOTOR_D_H;
109     }
110     if(0 == direction){//正转
111         step++; if(8 == step) step = 0;
112     }
113 }
114 
115 /*****************************************************************/
116 void motor_single_four_beat(uint8_t direction)// 单四拍 控制电机
117 {
118     static uint8_t step = 0;
119     if(1 == direction){//反转
120         if(0 == step) step = 4;
121         step--;
122     }
123     if(0 == step){//步序1
124         MOTOR_A_H;
125         MOTOR_B_L;
126         MOTOR_C_L;
127         MOTOR_D_L;
128     }else if(1 == step){//步序2
129         MOTOR_A_L;
130         MOTOR_B_H;
131         MOTOR_C_L;
132         MOTOR_D_L;
133     }else if(2 == step){//步序3
134         MOTOR_A_L;
135         MOTOR_B_L;
136         MOTOR_C_H;
137         MOTOR_D_L;
138     }else if(3 == step){//步序4
139         MOTOR_A_L;
140         MOTOR_B_L;
141         MOTOR_C_L;
142         MOTOR_D_H;
143     }
144     if(0 == direction){//正转
145         step++; if(4 == step) step = 0;
146     }
147 }
148 
149 /*****************************************************************/
150 void motor_double_four_beat(uint8_t direction)// 双四拍 控制电机
151 {
152     static uint8_t step = 0;
153     if(1 == direction){//反转
154         if(0 == step) step = 4;
155         step--;
156     }
157     if(0 == step){//步序1
158         MOTOR_A_H;
159         MOTOR_B_L;
160         MOTOR_C_L;
161         MOTOR_D_H;
162     }else if(1 == step){//步序2
163         MOTOR_A_H;
164         MOTOR_B_H;
165         MOTOR_C_L;
166         MOTOR_D_L;
167     }else if(2 == step){//步序3
168         MOTOR_A_L;
169         MOTOR_B_H;
170         MOTOR_C_H;
171         MOTOR_D_L;
172     }else if(3 == step){//步序4
173         MOTOR_A_L;
174         MOTOR_B_L;
175         MOTOR_C_H;
176         MOTOR_D_H;
177     }
178     if(0 == direction){//正转
179         step++; if(4 == step) step = 0;
180     }
181 }
182 
183 /*****************************************************************/
184 void motor_stop(void)
185 {
186     //四相输出都为低电平是,电机停止工作
187     MOTOR_A_L;
188     MOTOR_B_L;
189     MOTOR_C_L;
190     MOTOR_D_L;
191 }
源文件