主函数
使用STM32的通用定时器定时,控制步进电机正反转和启停。
学习目的:学习步进电机和步进电机驱动器的基本使用方法。步进电机驱动器:
ENA+ <---> 3V3
ENA- <---> PB12
DIR+ <---> 3V3
DIR- <---> PB14
PUL+ <---> 3V3
PUL- <---> PC6头文件
#ifndef __BSP_STEP_MOTOR_INIT_H #define __BSP_STEP_MOTOR_INIT_H #include "stm32f1xx.h" #include "stm32f1xx_hal.h" //引脚定义 /*******************************************************/ //Motor 使能 #define MOTOR_EN_PIN GPIO_PIN_12 #define MOTOR_EN_GPIO_PORT GPIOB #define MOTOR_EN_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE() //Motor 方向 #define MOTOR_DIR_PIN GPIO_PIN_14 #define MOTOR_DIR_GPIO_PORT GPIOB #define MOTOR_DIR_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE() //Motor 脉冲 #define MOTOR_PUL_PIN GPIO_PIN_6 #define MOTOR_PUL_GPIO_PORT GPIOC #define MOTOR_PUL_GPIO_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE() /************************************************************/ #define HIGH GPIO_PIN_SET //高电平 #define LOW GPIO_PIN_RESET //低电平 #define ON LOW //开 #define OFF HIGH //关 #define CW HIGH //顺时针 #define CCW LOW //逆时针 //控制使能引脚 /* 带参宏,可以像内联函数一样使用 */ #define MOTOR_EN(x) HAL_GPIO_WritePin(MOTOR_EN_GPIO_PORT,MOTOR_EN_PIN,x) #define MOTOR_PLU(x) HAL_GPIO_WritePin(MOTOR_PUL_GPIO_PORT,MOTOR_PUL_PIN,x) #define MOTOR_DIR(x) HAL_GPIO_WritePin(MOTOR_DIR_GPIO_PORT,MOTOR_DIR_PIN,x) extern void stepper_Init(void); extern void stepper_turn(int tim,float angle,float subdivide,uint8_t dir); #endif /* __STEP_MOTOR_INIT_H */
tim 方波周期 单位MS 周期越短频率越高,转速越快 细分为1时最少10ms
angle 需要转动的角度值
dir 选择正反转(取值范围:0,1)
subdivide 细分值
步距角1.8,细分数为1时,电机转一圈需要的脉冲数:n=360/1.8=200脉冲
根据细分数求得步距角被分成多少个方波
n=(int)(angle/(1.8/subdivide));
#include "./stepper/bsp_stepper_init.h" #include "./led/bsp_led.h" #include "./delay/core_delay.h" #include "stm32f1xx.h" /** * @brief 步进电机旋转 * @param tim 方波周期 单位MS 周期越短频率越高,转速越快 细分为1时最少10ms * @param angle 需要转动的角度值 * @param dir 选择正反转(取值范围:0,1) * @param subdivide 细分值 * @note 无 * @retval 无 */ void stepper_turn(int tim,float angle,float subdivide,uint8_t dir) { int n,i; /*根据细分数求得步距角被分成多少个方波*/ n=(int)(angle/(1.8/subdivide)); if(dir==CW) //顺时针 { MOTOR_DIR(CW); } else if(dir==CCW)//逆时针 { MOTOR_DIR(CCW); } /*开使能*/ MOTOR_EN(HIGH); /*模拟方波*/ for(i=0;i<n;i++) { MOTOR_PLU(HIGH); delay_us(tim/2); MOTOR_PLU(LOW); delay_us(tim/2); } /*关使能*/ MOTOR_EN(LOW); } /** * @brief 引脚初始化 * @retval 无 */ void stepper_Init() { /*定义一个GPIO_InitTypeDef类型的结构体*/ GPIO_InitTypeDef GPIO_InitStruct; /*开启Motor相关的GPIO外设时钟*/ MOTOR_DIR_GPIO_CLK_ENABLE(); MOTOR_PUL_GPIO_CLK_ENABLE(); MOTOR_EN_GPIO_CLK_ENABLE(); /*选择要控制的GPIO引脚*/ GPIO_InitStruct.Pin = MOTOR_DIR_PIN; /*设置引脚的输出类型为推挽输出*/ GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull =GPIO_PULLUP; /*设置引脚速率为高速 */ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; /*Motor 方向引脚 初始化*/ HAL_GPIO_Init(MOTOR_DIR_GPIO_PORT, &GPIO_InitStruct); /*Motor 脉冲引脚 初始化*/ GPIO_InitStruct.Pin = MOTOR_PUL_PIN; HAL_GPIO_Init(MOTOR_PUL_GPIO_PORT, &GPIO_InitStruct); /*Motor 使能引脚 初始化*/ GPIO_InitStruct.Pin = MOTOR_EN_PIN; HAL_GPIO_Init(MOTOR_EN_GPIO_PORT, &GPIO_InitStruct); /*关掉使能*/ MOTOR_EN(LOW); }
主函数
#include "main.h" #include <stdlib.h> #include "./stepper/bsp_stepper_init.h" #include "./usart/bsp_debug_usart.h" #include "./led/bsp_led.h" #include "./key/bsp_key.h" /** * @brief 主函数 * @param 无 * @retval 无 */ int main(void) { int key_val=0; int i=0; int dir_val=0; int angle_val=90; /* 初始化系统时钟为72MHz */ SystemClock_Config(); /*初始化USART 配置模式为 115200 8-N-1,中断接收*/ DEBUG_USART_Config(); printf("按下按键1可修改旋转方向、按下按键2可修改旋转角度\r\n"); /*按键初始化*/ Key_GPIO_Config(); /*步进电机初始化*/ stepper_Init(); /*开启步进电机使能*/ while(1) { if( Key_Scan(KEY1_GPIO_PORT,KEY1_PIN) == KEY_ON ) { /*改变方向*/ dir_val=(++i % 2) ? CW : CCW; MOTOR_DIR(dir_val); key_val = ON; } if( Key_Scan(KEY2_GPIO_PORT,KEY2_PIN) == KEY_ON ) { /*改变角度*/ angle_val=angle_val+90; key_val = ON; } if( key_val == ON ) { /*打印状态*/ if(dir_val) printf("顺时针旋转 %d 度,",angle_val); else printf("逆时针旋转 %d 度,",angle_val); printf("正在运行中......\r\n"); stepper_turn(100,angle_val,32,dir_val); key_val = OFF; } } } /** * @brief System Clock Configuration * The system Clock is configured as follow : * System Clock source = PLL (HSE) * SYSCLK(Hz) = 72000000 * HCLK(Hz) = 72000000 * AHB Prescaler = 1 * APB1 Prescaler = 2 * APB2 Prescaler = 1 * HSE Frequency(Hz) = 8000000 * HSE PREDIV1 = 2 * PLLMUL = 9 * Flash Latency(WS) = 0 * @param None * @retval None */ void SystemClock_Config(void) { RCC_ClkInitTypeDef clkinitstruct = {0}; RCC_OscInitTypeDef oscinitstruct = {0}; /* Enable HSE Oscillator and activate PLL with HSE as source */ oscinitstruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; oscinitstruct.HSEState = RCC_HSE_ON; oscinitstruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1; oscinitstruct.PLL.PLLState = RCC_PLL_ON; oscinitstruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; oscinitstruct.PLL.PLLMUL = RCC_PLL_MUL9; if (HAL_RCC_OscConfig(&oscinitstruct)!= HAL_OK) { /* Initialization Error */ while(1); } /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */ clkinitstruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); clkinitstruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; clkinitstruct.AHBCLKDivider = RCC_SYSCLK_DIV1; clkinitstruct.APB2CLKDivider = RCC_HCLK_DIV1; clkinitstruct.APB1CLKDivider = RCC_HCLK_DIV2; if (HAL_RCC_ClockConfig(&clkinitstruct, FLASH_LATENCY_2)!= HAL_OK) { /* Initialization Error */ while(1); } }
stm32利用GPIO延时模拟脉冲控制控制步进电机
最新推荐文章于 2025-03-14 10:10:14 发布