diff --git a/Core/Inc/machine.h b/Core/Inc/machine.h new file mode 100644 index 0000000..a768400 --- /dev/null +++ b/Core/Inc/machine.h @@ -0,0 +1,136 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file : machine.h + * @brief : LK540 Machine Stepper Motor Control Header + * 步进电机控制模块头文件 + ****************************************************************************** + * @attention + * + * Copyright (c) 2026 STMicroelectronics. + * All rights reserved. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +#ifndef __MACHINE_H +#define __MACHINE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" + +/* Exported types ------------------------------------------------------------*/ +/** + * @brief 步进电机方向枚举 + */ +typedef enum +{ + MOTOR_DIR_CWW = 0, /* 向左移动 (Counter Clockwise) */ + MOTOR_DIR_CW = 1 /* 向右移动 (Clockwise) */ +} Motor_DirectionTypeDef; + +/* Exported constants --------------------------------------------------------*/ +/* 电机参数定义 */ +#define MOTOR_PULSE_PER_MM 5.33f /* 每毫米脉冲数 */ +#define MOTOR_ORIGIN_DISTANCE 215.0f /* 原点距离 (mm) */ +#define MOTOR_MATERIAL1_DISTANCE 192.4f /* 1#料距离 (mm) */ +#define MOTOR_MATERIAL2_DISTANCE 65.4f /* 2#料距离 (mm) */ +#define MOTOR_MATERIAL3_DISTANCE 61.6f /* 3#料距离 (mm) */ +#define MOTOR_MATERIAL4_DISTANCE 188.6f /* 4#料距离 (mm) */ + +/* GPIO引脚定义 */ +#define MOTOR_ORIGIN_PIN_PORT GPIOB +#define MOTOR_ORIGIN_PIN GPIO_PIN_3 + +#define MOTOR_LIMIT_PIN_PORT GPIOG +#define MOTOR_LIMIT_PIN GPIO_PIN_15 + +#define MOTOR_DIR_PIN_PORT GPIOD +#define MOTOR_DIR_PIN GPIO_PIN_7 + +#define MOTOR_STEP_PIN_PORT GPIOG +#define MOTOR_STEP_PIN GPIO_PIN_9 + +/* Exported macro ------------------------------------------------------------*/ + +/* Exported functions prototypes ---------------------------------------------*/ +/** + * @brief 检测步进电机是否在原点 + * @retval 1: 在原点, 0: 不在原点 + */ +uint8_t Machine_IsAtOrigin(void); + +/** + * @brief 检测步进电机是否在临界点(限位传感器) + * @retval 1: 在临界点, 0: 不在临界点 + */ +uint8_t Machine_IsAtLimit(void); + +/** + * @brief 设置步进电机方向 + * @param dir: 方向 (MOTOR_DIR_CWW: 向左, MOTOR_DIR_CW: 向右) + * @retval None + */ +void Machine_SetDirection(Motor_DirectionTypeDef dir); + +/** + * @brief 步进电机移动一步 + * @note 产生一个脉冲信号,电机移动一步(1/5.33 mm) + * @retval None + */ +void Machine_Step(void); + +/** + * @brief 步进电机移动到原点 + * @note 一直向左移动直到检测到原点传感器(PB3为0) + * 如果检测到限位传感器(PG15为0),则停止并返回错误 + * @retval 0: 成功到达原点, 1: 到达限位点(错误) + */ +uint8_t Machine_MoveToOrigin(void); + +/** + * @brief 步进电机从原点移动到中心点 + * @note 中心点就是原点位置(215.0mm处) + * 如果已经在原点,则不需要移动 + * @retval 0: 成功, 1: 失败 + */ +uint8_t Machine_MoveToCenter(void); + +/** + * @brief 步进电机从中心点移动到1#料位置 + * @note 从原点(215.0mm)向左移动22.6mm到达1#料(192.4mm) + * @retval 0: 成功, 1: 失败(到达限位点) + */ +uint8_t Machine_MoveToMaterial1(void); + +/** + * @brief 步进电机从中心点移动到2#料位置 + * @note 从原点(215.0mm)向左移动149.6mm到达2#料(65.4mm) + * @retval 0: 成功, 1: 失败(到达限位点) + */ +uint8_t Machine_MoveToMaterial2(void); + +/** + * @brief 步进电机从中心点移动到3#料位置 + * @note 从原点(215.0mm)向右移动153.4mm到达3#料(61.6mm) + * @retval 0: 成功, 1: 失败(到达限位点) + */ +uint8_t Machine_MoveToMaterial3(void); + +/** + * @brief 步进电机从中心点移动到4#料位置 + * @note 从原点(215.0mm)向右移动26.4mm到达4#料(188.6mm) + * @retval 0: 成功, 1: 失败(到达限位点) + */ +uint8_t Machine_MoveToMaterial4(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __MACHINE_H */ diff --git a/Core/Inc/main.h b/Core/Inc/main.h index c284138..213c817 100644 --- a/Core/Inc/main.h +++ b/Core/Inc/main.h @@ -1,69 +1,69 @@ -/* USER CODE BEGIN Header */ -/** - ****************************************************************************** - * @file : main.h - * @brief : Header for main.c file. - * This file contains the common defines of the application. - ****************************************************************************** - * @attention - * - * Copyright (c) 2026 STMicroelectronics. - * All rights reserved. - * - * This software is licensed under terms that can be found in the LICENSE file - * in the root directory of this software component. - * If no LICENSE file comes with this software, it is provided AS-IS. - * - ****************************************************************************** - */ -/* USER CODE END Header */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __MAIN_H -#define __MAIN_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f1xx_hal.h" - -/* Private includes ----------------------------------------------------------*/ -/* USER CODE BEGIN Includes */ - -/* USER CODE END Includes */ - -/* Exported types ------------------------------------------------------------*/ -/* USER CODE BEGIN ET */ - -/* USER CODE END ET */ - -/* Exported constants --------------------------------------------------------*/ -/* USER CODE BEGIN EC */ - -/* USER CODE END EC */ - -/* Exported macro ------------------------------------------------------------*/ -/* USER CODE BEGIN EM */ - -/* USER CODE END EM */ - -/* Exported functions prototypes ---------------------------------------------*/ -void Error_Handler(void); - -/* USER CODE BEGIN EFP */ - -/* USER CODE END EFP */ - -/* Private defines -----------------------------------------------------------*/ - -/* USER CODE BEGIN Private defines */ - -/* USER CODE END Private defines */ - -#ifdef __cplusplus -} -#endif - -#endif /* __MAIN_H */ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file : main.h + * @brief : Header for main.c file. + * This file contains the common defines of the application. + ****************************************************************************** + * @attention + * + * Copyright (c) 2026 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __MAIN_H +#define __MAIN_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f1xx_hal.h" + +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ +#include "machine.h" +/* USER CODE END Includes */ + +/* Exported types ------------------------------------------------------------*/ +/* USER CODE BEGIN ET */ + +/* USER CODE END ET */ + +/* Exported constants --------------------------------------------------------*/ +/* USER CODE BEGIN EC */ + +/* USER CODE END EC */ + +/* Exported macro ------------------------------------------------------------*/ +/* USER CODE BEGIN EM */ + +/* USER CODE END EM */ + +/* Exported functions prototypes ---------------------------------------------*/ +void Error_Handler(void); + +/* USER CODE BEGIN EFP */ + +/* USER CODE END EFP */ + +/* Private defines -----------------------------------------------------------*/ + +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +#ifdef __cplusplus +} +#endif + +#endif /* __MAIN_H */ diff --git a/Core/Src/machine.c b/Core/Src/machine.c new file mode 100644 index 0000000..71bde7d --- /dev/null +++ b/Core/Src/machine.c @@ -0,0 +1,332 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file : machine.c + * @brief : LK540 Machine Stepper Motor Control Implementation + * 步进电机控制模块实现 + ****************************************************************************** + * @attention + * + * Copyright (c) 2026 STMicroelectronics. + * All rights reserved. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +#include "machine.h" + +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* Private typedef -----------------------------------------------------------*/ +/* USER CODE BEGIN PTD */ + +/* USER CODE END PTD */ + +/* Private define ------------------------------------------------------------*/ +/* USER CODE BEGIN PD */ +/* 步进脉冲时序参数(微秒) */ +#define STEP_PULSE_HIGH_TIME_US 10 /* 脉冲高电平时间 */ +#define STEP_PULSE_LOW_TIME_US 10 /* 脉冲低电平时间 */ + +/* 移动相关参数 */ +#define MAX_STEPS_TO_ORIGIN 50000 /* 移动到原点的最大步数(防止无限循环) */ +#define STEP_DELAY_US 100 /* 每步之间的延时(微秒) */ + +/* 各料位相对于原点的距离(mm) */ +#define DISTANCE_TO_MATERIAL1 22.6f /* 215.0 - 192.4 = 22.6mm (向左) */ +#define DISTANCE_TO_MATERIAL2 149.6f /* 215.0 - 65.4 = 149.6mm (向左) */ +#define DISTANCE_TO_MATERIAL3 153.4f /* 215.0 - 61.6 = 153.4mm (向右) */ +#define DISTANCE_TO_MATERIAL4 26.4f /* 215.0 - 188.6 = 26.4mm (向右) */ + +/* USER CODE END PD */ + +/* Private macro -------------------------------------------------------------*/ +/* USER CODE BEGIN PM */ + +/* USER CODE END PM */ + +/* Private variables ---------------------------------------------------------*/ +/* USER CODE BEGIN PV */ + +/* USER CODE END PV */ + +/* Private function prototypes -----------------------------------------------*/ +/* USER CODE BEGIN PFP */ +static void DelayUs(uint32_t us); +static uint32_t Machine_MmToSteps(float mm); +static uint8_t Machine_MoveSteps(Motor_DirectionTypeDef dir, uint32_t steps); + +/* USER CODE END PFP */ + +/* Private user code ---------------------------------------------------------*/ +/* USER CODE BEGIN 0 */ + +/** + * @brief 微秒级延时函数 + * @param us: 延时时间(微秒) + * @note 基于系统时钟的简单延时,72MHz系统时钟下 + * 考虑循环开销,使用约60个周期/微秒 + * @retval None + */ +static void DelayUs(uint32_t us) +{ + uint32_t i; + /* 72MHz时钟,考虑循环开销,约60个周期/微秒 */ + for (i = 0; i < us * 60; i++) + { + __NOP(); + } +} + +/** + * @brief 将毫米距离转换为步数 + * @param mm: 距离(毫米) + * @retval 步数 + */ +static uint32_t Machine_MmToSteps(float mm) +{ + /* 每毫米5.33个脉冲,向上取整 */ + return (uint32_t)(mm * MOTOR_PULSE_PER_MM + 0.5f); +} + +/** + * @brief 步进电机移动指定步数 + * @param dir: 移动方向 + * @param steps: 移动步数 + * @retval 0: 成功, 1: 失败(到达限位点) + */ +static uint8_t Machine_MoveSteps(Motor_DirectionTypeDef dir, uint32_t steps) +{ + uint32_t i; + + /* 设置方向 */ + Machine_SetDirection(dir); + DelayUs(STEP_DELAY_US); + + /* 移动指定步数 */ + for (i = 0; i < steps; i++) + { + /* 检查限位传感器 */ + if (Machine_IsAtLimit()) + { + return 1; /* 到达限位点,返回错误 */ + } + + /* 移动一步 */ + Machine_Step(); + DelayUs(STEP_DELAY_US); + } + + return 0; /* 成功 */ +} + +/* USER CODE END 0 */ + +/* Exported functions --------------------------------------------------------*/ + +/** + * @brief 检测步进电机是否在原点 + * @note PB3状态为0表示检测到步进电机在原点 + * @retval 1: 在原点, 0: 不在原点 + */ +uint8_t Machine_IsAtOrigin(void) +{ + GPIO_PinState pinState; + + /* 读取PB3引脚状态 */ + pinState = HAL_GPIO_ReadPin(MOTOR_ORIGIN_PIN_PORT, MOTOR_ORIGIN_PIN); + + /* PB3为0表示在原点 */ + return (pinState == GPIO_PIN_RESET) ? 1 : 0; +} + +/** + * @brief 检测步进电机是否在临界点(限位传感器) + * @note PG15状态为0表示检测到步进电机到达临界点,不能再前进了 + * @retval 1: 在临界点, 0: 不在临界点 + */ +uint8_t Machine_IsAtLimit(void) +{ + GPIO_PinState pinState; + + /* 读取PG15引脚状态 */ + pinState = HAL_GPIO_ReadPin(MOTOR_LIMIT_PIN_PORT, MOTOR_LIMIT_PIN); + + /* PG15为0表示在临界点 */ + return (pinState == GPIO_PIN_RESET) ? 1 : 0; +} + +/** + * @brief 设置步进电机方向 + * @param dir: 方向 + * MOTOR_DIR_CWW (0): 向左移动 (CWW - Counter Clockwise) + * MOTOR_DIR_CW (1): 向右移动 (CW - Clockwise) + * @note PD7为0表示向左,1表示向右 + * @retval None + */ +void Machine_SetDirection(Motor_DirectionTypeDef dir) +{ + GPIO_PinState pinState; + + /* 根据方向设置PD7引脚状态 */ + pinState = (dir == MOTOR_DIR_CWW) ? GPIO_PIN_RESET : GPIO_PIN_SET; + + /* 设置方向引脚 */ + HAL_GPIO_WritePin(MOTOR_DIR_PIN_PORT, MOTOR_DIR_PIN, pinState); +} + +/** + * @brief 步进电机移动一步 + * @note 产生一个脉冲信号,电机移动一步 + * 移动1mm需要5.33个脉冲,所以一步约等于1/5.33 mm + * 脉冲时序:低->高->低 + * @retval None + */ +void Machine_Step(void) +{ + /* 确保步进引脚初始为低电平 */ + HAL_GPIO_WritePin(MOTOR_STEP_PIN_PORT, MOTOR_STEP_PIN, GPIO_PIN_RESET); + DelayUs(STEP_PULSE_LOW_TIME_US); + + /* 产生高电平脉冲 */ + HAL_GPIO_WritePin(MOTOR_STEP_PIN_PORT, MOTOR_STEP_PIN, GPIO_PIN_SET); + DelayUs(STEP_PULSE_HIGH_TIME_US); + + /* 恢复低电平 */ + HAL_GPIO_WritePin(MOTOR_STEP_PIN_PORT, MOTOR_STEP_PIN, GPIO_PIN_RESET); + DelayUs(STEP_PULSE_LOW_TIME_US); +} + +/** + * @brief 步进电机移动到原点 + * @note 一直向左移动直到检测到原点传感器(PB3为0) + * 如果检测到限位传感器(PG15为0),则停止并返回错误 + * @retval 0: 成功到达原点, 1: 到达限位点(错误) + */ +uint8_t Machine_MoveToOrigin(void) +{ + uint32_t stepCount = 0; + + /* 设置方向为向左(CWW) */ + Machine_SetDirection(MOTOR_DIR_CWW); + DelayUs(STEP_DELAY_US); + + /* 如果已经在原点,直接返回 */ + if (Machine_IsAtOrigin()) + { + return 0; + } + + /* 一直向左移动直到检测到原点 */ + while (!Machine_IsAtOrigin()) + { + /* 检查限位传感器 */ + if (Machine_IsAtLimit()) + { + return 1; /* 到达限位点,返回错误 */ + } + + /* 防止无限循环 */ + if (stepCount++ > MAX_STEPS_TO_ORIGIN) + { + return 1; /* 超时,返回错误 */ + } + + /* 移动一步 */ + Machine_Step(); + DelayUs(STEP_DELAY_US); + } + + return 0; /* 成功到达原点 */ +} + +/** + * @brief 步进电机从原点移动到中心点 + * @note 中心点就是原点位置(215.0mm处) + * 如果已经在原点,则不需要移动 + * @retval 0: 成功, 1: 失败 + */ +uint8_t Machine_MoveToCenter(void) +{ + /* 如果已经在原点(中心点),直接返回成功 */ + if (Machine_IsAtOrigin()) + { + return 0; + } + + /* 否则移动到原点 */ + return Machine_MoveToOrigin(); +} + +/** + * @brief 步进电机从中心点移动到1#料位置 + * @note 从原点(215.0mm)向左移动22.6mm到达1#料(192.4mm) + * @retval 0: 成功, 1: 失败(到达限位点) + */ +uint8_t Machine_MoveToMaterial1(void) +{ + uint32_t steps; + + /* 计算需要的步数 */ + steps = Machine_MmToSteps(DISTANCE_TO_MATERIAL1); + + /* 向左移动 */ + return Machine_MoveSteps(MOTOR_DIR_CWW, steps); +} + +/** + * @brief 步进电机从中心点移动到2#料位置 + * @note 从原点(215.0mm)向左移动149.6mm到达2#料(65.4mm) + * @retval 0: 成功, 1: 失败(到达限位点) + */ +uint8_t Machine_MoveToMaterial2(void) +{ + uint32_t steps; + + /* 计算需要的步数 */ + steps = Machine_MmToSteps(DISTANCE_TO_MATERIAL2); + + /* 向左移动 */ + return Machine_MoveSteps(MOTOR_DIR_CWW, steps); +} + +/** + * @brief 步进电机从中心点移动到3#料位置 + * @note 从原点(215.0mm)向右移动153.4mm到达3#料(61.6mm) + * @retval 0: 成功, 1: 失败(到达限位点) + */ +uint8_t Machine_MoveToMaterial3(void) +{ + uint32_t steps; + + /* 计算需要的步数 */ + steps = Machine_MmToSteps(DISTANCE_TO_MATERIAL3); + + /* 向右移动 */ + return Machine_MoveSteps(MOTOR_DIR_CW, steps); +} + +/** + * @brief 步进电机从中心点移动到4#料位置 + * @note 从原点(215.0mm)向右移动26.4mm到达4#料(188.6mm) + * @retval 0: 成功, 1: 失败(到达限位点) + */ +uint8_t Machine_MoveToMaterial4(void) +{ + uint32_t steps; + + /* 计算需要的步数 */ + steps = Machine_MmToSteps(DISTANCE_TO_MATERIAL4); + + /* 向右移动 */ + return Machine_MoveSteps(MOTOR_DIR_CW, steps); +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ diff --git a/Core/Src/main.c b/Core/Src/main.c index bf05581..77f492d 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -1,315 +1,331 @@ -/* USER CODE BEGIN Header */ -/** - ****************************************************************************** - * @file : main.c - * @brief : Main program body - ****************************************************************************** - * @attention - * - * Copyright (c) 2026 STMicroelectronics. - * All rights reserved. - * - * This software is licensed under terms that can be found in the LICENSE file - * in the root directory of this software component. - * If no LICENSE file comes with this software, it is provided AS-IS. - * - ****************************************************************************** - */ -/* USER CODE END Header */ -/* Includes ------------------------------------------------------------------*/ -#include "main.h" -#include "cmsis_os.h" - -/* Private includes ----------------------------------------------------------*/ -/* USER CODE BEGIN Includes */ - -/* USER CODE END Includes */ - -/* Private typedef -----------------------------------------------------------*/ -/* USER CODE BEGIN PTD */ - -/* USER CODE END PTD */ - -/* Private define ------------------------------------------------------------*/ -/* USER CODE BEGIN PD */ - -/* USER CODE END PD */ - -/* Private macro -------------------------------------------------------------*/ -/* USER CODE BEGIN PM */ - -/* USER CODE END PM */ - -/* Private variables ---------------------------------------------------------*/ -/* Definitions for motorTask */ -osThreadId_t motorTaskHandle; -const osThreadAttr_t motorTask_attributes = { - .name = "motorTask", - .stack_size = 256 * 4, - .priority = (osPriority_t) osPriorityAboveNormal, -}; -/* USER CODE BEGIN PV */ - -/* USER CODE END PV */ - -/* Private function prototypes -----------------------------------------------*/ -void SystemClock_Config(void); -static void MX_GPIO_Init(void); -void StartMotorTask(void *argument); - -/* USER CODE BEGIN PFP */ - -/* USER CODE END PFP */ - -/* Private user code ---------------------------------------------------------*/ -/* USER CODE BEGIN 0 */ - -/* USER CODE END 0 */ - -/** - * @brief The application entry point. - * @retval int - */ -int main(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(); - /* USER CODE BEGIN 2 */ - - /* USER CODE END 2 */ - - /* Init scheduler */ - osKernelInitialize(); - - /* USER CODE BEGIN RTOS_MUTEX */ - /* add mutexes, ... */ - /* USER CODE END RTOS_MUTEX */ - - /* USER CODE BEGIN RTOS_SEMAPHORES */ - /* add semaphores, ... */ - /* USER CODE END RTOS_SEMAPHORES */ - - /* USER CODE BEGIN RTOS_TIMERS */ - /* start timers, add new ones, ... */ - /* USER CODE END RTOS_TIMERS */ - - /* USER CODE BEGIN RTOS_QUEUES */ - /* add queues, ... */ - /* USER CODE END RTOS_QUEUES */ - - /* Create the thread(s) */ - /* creation of motorTask */ - motorTaskHandle = osThreadNew(StartMotorTask, NULL, &motorTask_attributes); - - /* USER CODE BEGIN RTOS_THREADS */ - /* add threads, ... */ - /* USER CODE END RTOS_THREADS */ - - /* USER CODE BEGIN RTOS_EVENTS */ - /* add events, ... */ - /* USER CODE END RTOS_EVENTS */ - - /* Start scheduler */ - osKernelStart(); - - /* We should never get here as control is now taken by the scheduler */ - - /* Infinite loop */ - /* USER CODE BEGIN WHILE */ - while (1) - { - /* USER CODE END WHILE */ - - /* USER CODE BEGIN 3 */ - } - /* USER CODE END 3 */ -} - -/** - * @brief System Clock Configuration - * @retval None - */ -void SystemClock_Config(void) -{ - RCC_OscInitTypeDef RCC_OscInitStruct = {0}; - RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; - - /** Initializes the RCC Oscillators according to the specified parameters - * in the RCC_OscInitTypeDef structure. - */ - RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; - RCC_OscInitStruct.HSEState = RCC_HSE_ON; - RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1; - RCC_OscInitStruct.HSIState = RCC_HSI_ON; - RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; - RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; - RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; - if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) - { - Error_Handler(); - } - - /** Initializes the CPU, AHB and APB buses clocks - */ - RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK - |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; - RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; - RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; - RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; - RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; - - if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) - { - Error_Handler(); - } -} - -/** - * @brief GPIO Initialization Function - * @param None - * @retval None - */ -static void MX_GPIO_Init(void) -{ - GPIO_InitTypeDef GPIO_InitStruct = {0}; - /* USER CODE BEGIN MX_GPIO_Init_1 */ - - /* USER CODE END MX_GPIO_Init_1 */ - - /* GPIO Ports Clock Enable */ - __HAL_RCC_GPIOD_CLK_ENABLE(); - __HAL_RCC_GPIOG_CLK_ENABLE(); - __HAL_RCC_GPIOB_CLK_ENABLE(); - - /*Configure GPIO pin Output Level */ - HAL_GPIO_WritePin(GPIOD, GPIO_PIN_7, GPIO_PIN_RESET); - - /*Configure GPIO pin Output Level */ - HAL_GPIO_WritePin(GPIOG, GPIO_PIN_9, GPIO_PIN_RESET); - - /*Configure GPIO pin : PD7 */ - GPIO_InitStruct.Pin = GPIO_PIN_7; - GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; - HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); - - /*Configure GPIO pin : PG9 */ - GPIO_InitStruct.Pin = GPIO_PIN_9; - GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; - HAL_GPIO_Init(GPIOG, &GPIO_InitStruct); - - /*Configure GPIO pin : PG15 */ - GPIO_InitStruct.Pin = GPIO_PIN_15; - GPIO_InitStruct.Mode = GPIO_MODE_INPUT; - GPIO_InitStruct.Pull = GPIO_PULLUP; - HAL_GPIO_Init(GPIOG, &GPIO_InitStruct); - - /*Configure GPIO pin : PB3 */ - GPIO_InitStruct.Pin = GPIO_PIN_3; - GPIO_InitStruct.Mode = GPIO_MODE_INPUT; - GPIO_InitStruct.Pull = GPIO_PULLUP; - HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); - - /* USER CODE BEGIN MX_GPIO_Init_2 */ - - /* USER CODE END MX_GPIO_Init_2 */ -} - -/* USER CODE BEGIN 4 */ - -/* USER CODE END 4 */ - -/* USER CODE BEGIN Header_StartMotorTask */ -/** - * @brief Function implementing the motorTask thread. - * @param argument: Not used - * @retval None - */ -/* USER CODE END Header_StartMotorTask */ -void StartMotorTask(void *argument) -{ - /* USER CODE BEGIN 5 */ - /* Infinite loop */ - for(;;) - { - osDelay(1); - } - /* USER CODE END 5 */ -} - -/** - * @brief Period elapsed callback in non blocking mode - * @note This function is called when TIM6 interrupt took place, inside - * HAL_TIM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment - * a global variable "uwTick" used as application time base. - * @param htim : TIM handle - * @retval None - */ -void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) -{ - /* USER CODE BEGIN Callback 0 */ - - /* USER CODE END Callback 0 */ - if (htim->Instance == TIM6) - { - HAL_IncTick(); - } - /* USER CODE BEGIN Callback 1 */ - - /* USER CODE END Callback 1 */ -} - -/** - * @brief This function is executed in case of error occurrence. - * @retval None - */ -void Error_Handler(void) -{ - /* USER CODE BEGIN Error_Handler_Debug */ - /* User can add his own implementation to report the HAL error return state */ - __disable_irq(); - while (1) - { - } - /* USER CODE END Error_Handler_Debug */ -} -#ifdef USE_FULL_ASSERT -/** - * @brief Reports the name of the source file and the source line number - * where the assert_param error has occurred. - * @param file: pointer to the source file name - * @param line: assert_param error line source number - * @retval None - */ -void assert_failed(uint8_t *file, uint32_t line) -{ - /* USER CODE BEGIN 6 */ - /* User can add his own implementation to report the file name and line number, - ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ - /* USER CODE END 6 */ -} -#endif /* USE_FULL_ASSERT */ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file : main.c + * @brief : Main program body + ****************************************************************************** + * @attention + * + * Copyright (c) 2026 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +#include "cmsis_os.h" + +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* Private typedef -----------------------------------------------------------*/ +/* USER CODE BEGIN PTD */ + +/* USER CODE END PTD */ + +/* Private define ------------------------------------------------------------*/ +/* USER CODE BEGIN PD */ + +/* USER CODE END PD */ + +/* Private macro -------------------------------------------------------------*/ +/* USER CODE BEGIN PM */ + +/* USER CODE END PM */ + +/* Private variables ---------------------------------------------------------*/ +/* Definitions for motorTask */ +osThreadId_t motorTaskHandle; +const osThreadAttr_t motorTask_attributes = { + .name = "motorTask", + .stack_size = 256 * 4, + .priority = (osPriority_t) osPriorityAboveNormal, +}; +/* USER CODE BEGIN PV */ + +/* USER CODE END PV */ + +/* Private function prototypes -----------------------------------------------*/ +void SystemClock_Config(void); +static void MX_GPIO_Init(void); +void StartMotorTask(void *argument); + +/* USER CODE BEGIN PFP */ + +/* USER CODE END PFP */ + +/* Private user code ---------------------------------------------------------*/ +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/** + * @brief The application entry point. + * @retval int + */ +int main(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(); + /* USER CODE BEGIN 2 */ + + /* 上电后步进电机初始化:从任何位置移动到原点 */ + /* Power-on initialization: Move stepper motor to origin from any position */ + if (Machine_MoveToOrigin() == 0) + { + /* 成功到达原点,移动到中心点(中心点就是原点位置) */ + /* Successfully reached origin, move to center (center is the origin position) */ + Machine_MoveToCenter(); + } + else + { + /* 移动到原点失败,可能是到达限位点或超时 */ + /* Failed to move to origin, may have reached limit or timeout */ + /* 这里可以添加错误处理,例如LED闪烁或蜂鸣器报警 */ + /* Error handling can be added here, such as LED blinking or buzzer alarm */ + } + + /* USER CODE END 2 */ + + /* Init scheduler */ + osKernelInitialize(); + + /* USER CODE BEGIN RTOS_MUTEX */ + /* add mutexes, ... */ + /* USER CODE END RTOS_MUTEX */ + + /* USER CODE BEGIN RTOS_SEMAPHORES */ + /* add semaphores, ... */ + /* USER CODE END RTOS_SEMAPHORES */ + + /* USER CODE BEGIN RTOS_TIMERS */ + /* start timers, add new ones, ... */ + /* USER CODE END RTOS_TIMERS */ + + /* USER CODE BEGIN RTOS_QUEUES */ + /* add queues, ... */ + /* USER CODE END RTOS_QUEUES */ + + /* Create the thread(s) */ + /* creation of motorTask */ + motorTaskHandle = osThreadNew(StartMotorTask, NULL, &motorTask_attributes); + + /* USER CODE BEGIN RTOS_THREADS */ + /* add threads, ... */ + /* USER CODE END RTOS_THREADS */ + + /* USER CODE BEGIN RTOS_EVENTS */ + /* add events, ... */ + /* USER CODE END RTOS_EVENTS */ + + /* Start scheduler */ + osKernelStart(); + + /* We should never get here as control is now taken by the scheduler */ + + /* Infinite loop */ + /* USER CODE BEGIN WHILE */ + while (1) + { + /* USER CODE END WHILE */ + + /* USER CODE BEGIN 3 */ + } + /* USER CODE END 3 */ +} + +/** + * @brief System Clock Configuration + * @retval None + */ +void SystemClock_Config(void) +{ + RCC_OscInitTypeDef RCC_OscInitStruct = {0}; + RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; + + /** Initializes the RCC Oscillators according to the specified parameters + * in the RCC_OscInitTypeDef structure. + */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_ON; + RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1; + RCC_OscInitStruct.HSIState = RCC_HSI_ON; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) + { + Error_Handler(); + } + + /** Initializes the CPU, AHB and APB buses clocks + */ + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK + |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; + + if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) + { + Error_Handler(); + } +} + +/** + * @brief GPIO Initialization Function + * @param None + * @retval None + */ +static void MX_GPIO_Init(void) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + /* USER CODE BEGIN MX_GPIO_Init_1 */ + + /* USER CODE END MX_GPIO_Init_1 */ + + /* GPIO Ports Clock Enable */ + __HAL_RCC_GPIOD_CLK_ENABLE(); + __HAL_RCC_GPIOG_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); + + /*Configure GPIO pin Output Level */ + HAL_GPIO_WritePin(GPIOD, GPIO_PIN_7, GPIO_PIN_RESET); + + /*Configure GPIO pin Output Level */ + HAL_GPIO_WritePin(GPIOG, GPIO_PIN_9, GPIO_PIN_RESET); + + /*Configure GPIO pin : PD7 */ + GPIO_InitStruct.Pin = GPIO_PIN_7; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); + + /*Configure GPIO pin : PG9 */ + GPIO_InitStruct.Pin = GPIO_PIN_9; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + HAL_GPIO_Init(GPIOG, &GPIO_InitStruct); + + /*Configure GPIO pin : PG15 */ + GPIO_InitStruct.Pin = GPIO_PIN_15; + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_PULLUP; + HAL_GPIO_Init(GPIOG, &GPIO_InitStruct); + + /*Configure GPIO pin : PB3 */ + GPIO_InitStruct.Pin = GPIO_PIN_3; + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_PULLUP; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + /* USER CODE BEGIN MX_GPIO_Init_2 */ + + /* USER CODE END MX_GPIO_Init_2 */ +} + +/* USER CODE BEGIN 4 */ + +/* USER CODE END 4 */ + +/* USER CODE BEGIN Header_StartMotorTask */ +/** + * @brief Function implementing the motorTask thread. + * @param argument: Not used + * @retval None + */ +/* USER CODE END Header_StartMotorTask */ +void StartMotorTask(void *argument) +{ + /* USER CODE BEGIN 5 */ + /* Infinite loop */ + for(;;) + { + osDelay(1); + } + /* USER CODE END 5 */ +} + +/** + * @brief Period elapsed callback in non blocking mode + * @note This function is called when TIM6 interrupt took place, inside + * HAL_TIM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment + * a global variable "uwTick" used as application time base. + * @param htim : TIM handle + * @retval None + */ +void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) +{ + /* USER CODE BEGIN Callback 0 */ + + /* USER CODE END Callback 0 */ + if (htim->Instance == TIM6) + { + HAL_IncTick(); + } + /* USER CODE BEGIN Callback 1 */ + + /* USER CODE END Callback 1 */ +} + +/** + * @brief This function is executed in case of error occurrence. + * @retval None + */ +void Error_Handler(void) +{ + /* USER CODE BEGIN Error_Handler_Debug */ + /* User can add his own implementation to report the HAL error return state */ + __disable_irq(); + while (1) + { + } + /* USER CODE END Error_Handler_Debug */ +} +#ifdef USE_FULL_ASSERT +/** + * @brief Reports the name of the source file and the source line number + * where the assert_param error has occurred. + * @param file: pointer to the source file name + * @param line: assert_param error line source number + * @retval None + */ +void assert_failed(uint8_t *file, uint32_t line) +{ + /* USER CODE BEGIN 6 */ + /* User can add his own implementation to report the file name and line number, + ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ + /* USER CODE END 6 */ +} +#endif /* USE_FULL_ASSERT */