diff --git a/Core/Inc/machine.h b/Core/Inc/machine.h index 06c1f64..8b50264 100644 --- a/Core/Inc/machine.h +++ b/Core/Inc/machine.h @@ -1,135 +1,153 @@ -/* 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_CW = 0, /* 向左移动 (Clockwise) */ - MOTOR_DIR_CCW = 1 /* 向右移动 (Counter 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_CW: 向左, MOTOR_DIR_CCW: 向右) - * @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 */ +/* 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_CW = 0, /* 向左移动 (Clockwise) */ + MOTOR_DIR_CCW = 1 /* 向右移动 (Counter 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 + +#define CYLINDER_PIN_PORT GPIOG +#define CYLINDER_PIN GPIO_PIN_8 + +/* 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_CW: 向左, MOTOR_DIR_CCW: 向右) + * @retval None + */ +void Machine_SetDirection(Motor_DirectionTypeDef dir); + +/** + * @brief 控制气缸状态 + * @param state: 状态 (0: 张开, 1: 闭合) + * @note PG8为0表示张开,1表示闭合 + * @retval None + */ +void Machine_SetCylinder(uint8_t state); + +/** + * @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 从中心点向左移动192.4mm到达1#料 + * @retval 0: 成功, 1: 失败(到达限位点) + */ +uint8_t Machine_MoveToMaterial1(void); + +/** + * @brief 步进电机从中心点移动到2#料位置 + * @note 从中心点向左移动65.4mm到达2#料 + * @retval 0: 成功, 1: 失败(到达限位点) + */ +uint8_t Machine_MoveToMaterial2(void); + +/** + * @brief 步进电机从中心点移动到3#料位置 + * @note 从中心点向右移动61.6mm到达3#料 + * @retval 0: 成功, 1: 失败(到达限位点) + */ +uint8_t Machine_MoveToMaterial3(void); + +/** + * @brief 步进电机从中心点移动到4#料位置 + * @note 从中心点向右移动188.6mm到达4#料 + * @retval 0: 成功, 1: 失败(到达限位点) + */ +uint8_t Machine_MoveToMaterial4(void); + +/** + * @brief 从中心点移动到1#料位置并取料,然后返回中心点放料 + * @note 完整的取料流程:移动到1#料 -> 闭合气缸 -> 返回中心点 -> 张开气缸 + * @retval 0: 成功, 1: 失败(移动失败) + */ +uint8_t Machine_PickMaterial1(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __MACHINE_H */ diff --git a/Core/Src/machine.c b/Core/Src/machine.c index ee38201..27dae17 100644 --- a/Core/Src/machine.c +++ b/Core/Src/machine.c @@ -1,331 +1,392 @@ -/* 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_CW (0): 向左移动 (CW - Clockwise) - * MOTOR_DIR_CCW (1): 向右移动 (CCW - Counter Clockwise) - * @note PD7为0表示向左,1表示向右 - * @retval None - */ -void Machine_SetDirection(Motor_DirectionTypeDef dir) -{ - GPIO_PinState pinState; - - /* 根据方向设置PD7引脚状态 */ - /* CW(0) = 向左 = GPIO_PIN_RESET, CCW(1) = 向右 = GPIO_PIN_SET */ - pinState = (dir == MOTOR_DIR_CW) ? 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; - - /* 设置方向为向左(CW) */ - Machine_SetDirection(MOTOR_DIR_CW); - 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) -{ - uint32_t steps; - - /* 计算需要的步数:215.0mm */ - steps = Machine_MmToSteps(MOTOR_ORIGIN_DISTANCE); - - /* 向右移动 */ - return Machine_MoveSteps(MOTOR_DIR_CCW, steps); -} - -/** - * @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_CW, 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_CW, 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_CCW, 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_CCW, steps); -} - -/* USER CODE BEGIN 1 */ - -/* USER CODE END 1 */ +/* 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 192.4f /* 从中心点向左移动192.4mm */ +#define DISTANCE_TO_MATERIAL2 65.4f /* 从中心点向左移动65.4mm */ +#define DISTANCE_TO_MATERIAL3 61.6f /* 从中心点向右移动61.6mm */ +#define DISTANCE_TO_MATERIAL4 188.6f /* 从中心点向右移动188.6mm */ + +/* 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_CW (0): 向左移动 (CW - Clockwise) + * MOTOR_DIR_CCW (1): 向右移动 (CCW - Counter Clockwise) + * @note PD7为0表示向左,1表示向右 + * @retval None + */ +void Machine_SetDirection(Motor_DirectionTypeDef dir) +{ + GPIO_PinState pinState; + + /* 根据方向设置PD7引脚状态 */ + /* CW(0) = 向左 = GPIO_PIN_RESET, CCW(1) = 向右 = GPIO_PIN_SET */ + pinState = (dir == MOTOR_DIR_CW) ? GPIO_PIN_RESET : GPIO_PIN_SET; + + /* 设置方向引脚 */ + HAL_GPIO_WritePin(MOTOR_DIR_PIN_PORT, MOTOR_DIR_PIN, pinState); +} + +/** + * @brief 控制气缸状态 + * @param state: 状态 (0: 张开, 1: 闭合) + * @note PG8为0表示张开,1表示闭合 + * @retval None + */ +void Machine_SetCylinder(uint8_t state) +{ + GPIO_PinState pinState; + + /* 根据状态设置PG8引脚状态 */ + /* 0 = 张开 = GPIO_PIN_RESET, 1 = 闭合 = GPIO_PIN_SET */ + pinState = (state == 0) ? GPIO_PIN_RESET : GPIO_PIN_SET; + + /* 设置气缸控制引脚 */ + HAL_GPIO_WritePin(CYLINDER_PIN_PORT, CYLINDER_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; + + /* 设置方向为向左(CW) */ + Machine_SetDirection(MOTOR_DIR_CW); + 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) +{ + uint32_t steps; + + /* 计算需要的步数:215.0mm */ + steps = Machine_MmToSteps(MOTOR_ORIGIN_DISTANCE); + + /* 向右移动 */ + return Machine_MoveSteps(MOTOR_DIR_CCW, steps); +} + +/** + * @brief 步进电机从中心点移动到1#料位置 + * @note 从中心点向左移动192.4mm到达1#料 + * @retval 0: 成功, 1: 失败(到达限位点) + */ +uint8_t Machine_MoveToMaterial1(void) +{ + uint32_t steps; + + /* 计算需要的步数 */ + steps = Machine_MmToSteps(DISTANCE_TO_MATERIAL1); + + /* 向左移动 */ + return Machine_MoveSteps(MOTOR_DIR_CW, steps); +} + +/** + * @brief 步进电机从中心点移动到2#料位置 + * @note 从中心点向左移动65.4mm到达2#料 + * @retval 0: 成功, 1: 失败(到达限位点) + */ +uint8_t Machine_MoveToMaterial2(void) +{ + uint32_t steps; + + /* 计算需要的步数 */ + steps = Machine_MmToSteps(DISTANCE_TO_MATERIAL2); + + /* 向左移动 */ + return Machine_MoveSteps(MOTOR_DIR_CW, steps); +} + +/** + * @brief 步进电机从中心点移动到3#料位置 + * @note 从中心点向右移动61.6mm到达3#料 + * @retval 0: 成功, 1: 失败(到达限位点) + */ +uint8_t Machine_MoveToMaterial3(void) +{ + uint32_t steps; + + /* 计算需要的步数 */ + steps = Machine_MmToSteps(DISTANCE_TO_MATERIAL3); + + /* 向右移动 */ + return Machine_MoveSteps(MOTOR_DIR_CCW, steps); +} + +/** + * @brief 步进电机从中心点移动到4#料位置 + * @note 从中心点向右移动188.6mm到达4#料 + * @retval 0: 成功, 1: 失败(到达限位点) + */ +uint8_t Machine_MoveToMaterial4(void) +{ + uint32_t steps; + + /* 计算需要的步数 */ + steps = Machine_MmToSteps(DISTANCE_TO_MATERIAL4); + + /* 向右移动 */ + return Machine_MoveSteps(MOTOR_DIR_CCW, steps); +} + +/** + * @brief 从中心点移动到1#料位置并取料,然后返回中心点放料 + * @note 1. 从中心点移动到1#料位置 + * 2. 闭合气缸取料 + * 3. 返回中心点 + * 4. 张开气缸放料 + * @retval 0: 成功, 1: 失败(移动失败) + */ +uint8_t Machine_PickMaterial1(void) +{ + /* 从中心点移动到1#料位置 */ + if (Machine_MoveToMaterial1() != 0) + { + return 1; /* 移动失败 */ + } + + /* 延时,确保到位 */ + DelayUs(10000); /* 10ms延时 */ + + /* 闭合气缸取料 */ + Machine_SetCylinder(1); + DelayUs(100000); /* 100ms延时,确保气缸闭合完成 */ + + /* 从1#料位置返回中心点(向左移动192.4mm,返回需要向右移动) */ + { + uint32_t steps; + steps = Machine_MmToSteps(DISTANCE_TO_MATERIAL1); + if (Machine_MoveSteps(MOTOR_DIR_CCW, steps) != 0) + { + return 1; /* 返回失败 */ + } + } + + /* 延时,确保到位 */ + DelayUs(10000); /* 10ms延时 */ + + /* 张开气缸放料 */ + Machine_SetCylinder(0); + DelayUs(100000); /* 100ms延时,确保气缸张开完成 */ + + return 0; /* 成功 */ +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ diff --git a/Core/Src/main.c b/Core/Src/main.c index 77f492d..e2375dc 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -22,7 +22,7 @@ /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ - +#include "machine.h" /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ @@ -101,9 +101,14 @@ int main(void) /* 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(); + /* 成功到达原点,移动到中心点 */ + /* Successfully reached origin, move to center */ + if (Machine_MoveToCenter() == 0) + { + /* 成功到达中心点,执行1#料取料流程 */ + /* Successfully reached center, execute material 1 picking process */ + Machine_PickMaterial1(); + } } else { @@ -224,6 +229,9 @@ static void MX_GPIO_Init(void) /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(GPIOG, GPIO_PIN_9, GPIO_PIN_RESET); + /*Configure GPIO pin Output Level */ + HAL_GPIO_WritePin(GPIOG, GPIO_PIN_8, GPIO_PIN_RESET); + /*Configure GPIO pin : PD7 */ GPIO_InitStruct.Pin = GPIO_PIN_7; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; @@ -238,6 +246,13 @@ static void MX_GPIO_Init(void) GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOG, &GPIO_InitStruct); + /*Configure GPIO pin : PG8 */ + GPIO_InitStruct.Pin = GPIO_PIN_8; + 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;