Files

393 lines
10 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* 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 */