1-电机描述
28BYJ-48 是一种常见的小型 永磁式单极步进电机,因为价格低廉、易于驱动、扭矩适中,经常作为入门学习电机控制和单片机实践的首选。它的型号含义是:
28:定子直径约 28mm;
BYJ:表示永磁单极步进电机系列;
48:该系列中的具体型号编号,表示四拍和八拍都可以运行。
2-控制时序描述
(1)是否可以细分?
常见的双极性步进电机,如42步进电机,可以支持细分;
但是28BYJ-48不支持;
细分的原理是控制线圈上的电流大小和方向实现旋转磁场,
而28BYJ-48是单极性的电机,不能通过改电流实现完整的260度连续变化的旋转磁场。
(2)使用ULN2003控制28BYJ-48步进电机支持哪些控制方式?
单四拍(每次只有1相通电)
扭矩小(只有一相产生磁力)
功耗低(只有一相通电)
振动大(步距角大,5.625°)
双四拍
扭矩大(两相合力)
功耗高(两相通电)
运行平稳(比单四拍好)
8拍(半步驱动)
三、代码实现单四拍、双四拍、八拍驱动
单四拍
运动效果
单极性5线4相步进电机 单四拍驱动
代码:
main.c
intmain(void){/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();init_28BYJ48_io_output();MX_DMA_Init();MX_USART3_UART_Init();/* USER CODE BEGIN 2 */__HAL_UART_ENABLE_IT(&huart3,UART_IT_IDLE);//使能IDLE中断HAL_UART_Receive_DMA(&huart3,rx3_buffer,BUFFER_SIZE);//开启DMA接收/*============================================== * 单四拍测试代码(上电后执行一次) * 单四拍:每次只有一相通电,转一圈 = 2048 步 *==============================================*//* 顺时针转一圈:2048步,每步1ms → 约14.6 RPM */BYJ48_SingleRotate(2048,1);HAL_Delay(1000);/* 暂停1秒 *//* 逆时针转一圈 */BYJ48_SingleRotate(-2048,1);HAL_Delay(1000);/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while(1){/* USER CODE END WHILE */// if(rec3_end_flag) //判断是否接收到1帧数据// {// Usart3_Handle(); //前往数据处理函数处理接收到的数据。// }// SEND_DEV_DATA_TO_PC(); //发送数据到PC端/* USER CODE BEGIN 3 *//* 持续顺时针旋转,每步1ms */// BYJ48_SingleRotate_Continuous(0, 1);BYJ48_SingleRotate(2048,1);HAL_Delay(1000);/* 暂停1秒 *//* 逆时针转一圈 */BYJ48_SingleRotate(-2048,1);HAL_Delay(1000);}/* USER CODE END 3 */}motor.h
#ifndef_28BYJ48_H#define_28BYJ48_H#include"stdint.h"//IO接口封装//PA8、PA15、PB3、PB4//A、B、C、D四相//PA8-->A相//PA15-->B相//PB3-->C相//PB4-->D相#define_28BYJ48_A_PINGPIO_PIN_8#define_28BYJ48_B_PINGPIO_PIN_15#define_28BYJ48_C_PINGPIO_PIN_3#define_28BYJ48_D_PINGPIO_PIN_4#define_28BYJ48_A_PORTGPIOA#define_28BYJ48_B_PORTGPIOA#define_28BYJ48_C_PORTGPIOB#define_28BYJ48_D_PORTGPIOB//A相输出高电平#define_28BYJ48_A_HIGH()HAL_GPIO_WritePin(_28BYJ48_A_PORT,_28BYJ48_A_PIN,GPIO_PIN_SET)//A相输出低电平#define_28BYJ48_A_LOW()HAL_GPIO_WritePin(_28BYJ48_A_PORT,_28BYJ48_A_PIN,GPIO_PIN_RESET)//B相输出高电平#define_28BYJ48_B_HIGH()HAL_GPIO_WritePin(_28BYJ48_B_PORT,_28BYJ48_B_PIN,GPIO_PIN_SET)//B相输出低电平#define_28BYJ48_B_LOW()HAL_GPIO_WritePin(_28BYJ48_B_PORT,_28BYJ48_B_PIN,GPIO_PIN_RESET)//C相输出高电平#define_28BYJ48_C_HIGH()HAL_GPIO_WritePin(_28BYJ48_C_PORT,_28BYJ48_C_PIN,GPIO_PIN_SET)//C相输出低电平#define_28BYJ48_C_LOW()HAL_GPIO_WritePin(_28BYJ48_C_PORT,_28BYJ48_C_PIN,GPIO_PIN_RESET)//D相输出高电平#define_28BYJ48_D_HIGH()HAL_GPIO_WritePin(_28BYJ48_D_PORT,_28BYJ48_D_PIN,GPIO_PIN_SET)//D相输出低电平#define_28BYJ48_D_LOW()HAL_GPIO_WritePin(_28BYJ48_D_PORT,_28BYJ48_D_PIN,GPIO_PIN_RESET)voidinit_28BYJ48_io_output(void);/* 单四拍步进函数 */voidBYJ48_SingleStep(uint8_tdirection);voidBYJ48_SingleRotate(int32_tsteps,uint32_tdelay_ms);uint8_tBYJ48_SingleRotate_Continuous(uint8_tdirection,uint32_tdelay_ms);voidBYJ48_Stop(void);#endifmotor,c
#include"28byj48_drv.h"#include"gpio.h"/* 单四拍步序索引(静态变量,记录当前位置) */// static uint8_t step_index = 0;uint8_tstep_index=0;/*---------------------------------------------------------- * 函数名:init_28BYJ48_io_output * 说明 :初始化A/B/C/D四相GPIO为推挽输出,并全部断电 *---------------------------------------------------------*/voidinit_28BYJ48_io_output(void){GPIO_InitTypeDef GPIO_InitStruct={0};/* A相(PA8) 和 B相(PA15) → GPIOA */GPIO_InitStruct.Pin=_28BYJ48_A_PIN|_28BYJ48_B_PIN;GPIO_InitStruct.Mode=GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Pull=GPIO_NOPULL;// 外部已接ULN2003,无需上拉GPIO_InitStruct.Speed=GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(GPIOA,&GPIO_InitStruct);/* C相(PB3) 和 D相(PB4) → GPIOB */GPIO_InitStruct.Pin=_28BYJ48_C_PIN|_28BYJ48_D_PIN;HAL_GPIO_Init(GPIOB,&GPIO_InitStruct);/* 初始化后全部断电(GPIO输出LOW → ULN2003输入LOW → 相断电) */BYJ48_Stop();}/*---------------------------------------------------------- * 函数名:BYJ48_SingleStep * 说明 :单四拍单步(每次只有一相通电) * 参数 :direction → 0:顺时针(CCW) 1:逆时针(CW) *---------------------------------------------------------*/voidBYJ48_SingleStep(uint8_tdirection){/* 1. 更新步序索引 */if(direction==0)step_index=(step_index+1)%4;// 顺时针:A→B→C→Delsestep_index=(step_index+3)%4;// 逆时针:A→D→C→B(+3 等价于 -1)/* 2. 全部相先断电(防止多相同时通电) */_28BYJ48_A_LOW();_28BYJ48_B_LOW();_28BYJ48_C_LOW();_28BYJ48_D_LOW();/* 3. 按当前步序给对应相通电 */voidDMA_Usart3_Send(uint8_t*buf,uint8_tlen);uint8_tdbg_buff[30]=0;sprintf(dbg_buff,"step_index:%d\r\n",step_index);DMA_Usart3_Send(dbg_buff,strlen(dbg_buff));switch(step_index){case0:_28BYJ48_A_HIGH();break;// A相通电case1:_28BYJ48_B_HIGH();break;// B相通电case2:_28BYJ48_C_HIGH();break;// C相通电case3:_28BYJ48_D_HIGH();break;// D相通电}}/*---------------------------------------------------------- * 函数名:BYJ48_SingleRotate * 说明 :单四拍连续旋转指定步数(阻塞式) * 参数 :steps → 步数,正=顺时针,负=逆时针 * delay_ms → 每步延时(毫秒),控制转速 * 注 :单四拍模式转一圈 = 2048 步 *---------------------------------------------------------*/voidBYJ48_SingleRotate(int32_tsteps,uint32_tdelay_ms){uint8_tdir;uint32_tcount;/* 判断方向 */if(steps>=0){dir=0;// 顺时针count=steps;}else{dir=1;// 逆时针count=-steps;}/* 逐步执行 */for(uint32_ti=0;i<count;i++){BYJ48_SingleStep(dir);HAL_Delay(delay_ms);}}/*---------------------------------------------------------- * 函数名:BYJ48_SingleRotate_Continuous * 说明 :单四拍持续旋转(用于main循环中连续调用) * 参数 :direction → 0:顺时针 1:逆时针 * delay_ms → 每步延时(毫秒) * 返回 :0=正常执行一步 * 注 :此函数不会重置step_index,适合连续调用 *---------------------------------------------------------*/uint8_tBYJ48_SingleRotate_Continuous(uint8_tdirection,uint32_tdelay_ms){BYJ48_SingleStep(direction);HAL_Delay(delay_ms);return0;}/*---------------------------------------------------------- * 函数名:BYJ48_Stop * 说明 :全部相断电(电机自由停止,无保持扭矩) *---------------------------------------------------------*/voidBYJ48_Stop(void){_28BYJ48_A_LOW();_28BYJ48_B_LOW();_28BYJ48_C_LOW();_28BYJ48_D_LOW();step_index=0;// 重置步序索引}四、双四拍 && 双四拍+梯形加速算法控制
双四拍核心代码
双四拍+梯形加速
待续
五、八拍+S形加速算法控制