Mini_croe_Sick/Core/Src/speed.c
2025-04-10 15:13:39 +08:00

144 lines
4.3 KiB
C
Raw 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.

#include "stm32f1xx_hal.h"
// 定义步进电机的步序
const uint8_t stepSequence[4] = {0x01, 0x02, 0x04, 0x08};
uint8_t currentStep = 0;
// 定义 PWM 和定时器句柄
TIM_HandleTypeDef htim1;
// 初始化 PWM
void PWM_Init(void) {
__HAL_RCC_TIM1_CLK_ENABLE();
TIM_OC_InitTypeDef sConfigOC = {0};
htim1.Instance = TIM1;
htim1.Init.Prescaler = 72 - 1; // 1 MHz 时钟
htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
htim1.Init.Period = 1000 - 1; // 1 kHz PWM
htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
HAL_TIM_PWM_Init(&htim1);
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 500; // 50% 占空比
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
}
// 初始化 GPIO用于控制栅极驱动器
void GPIO_Init(void) {
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
// 更新步进电机的步序
void StepMotor_Update(void) {
// 设置 GPIO 输出
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, (stepSequence[currentStep] & 0x01) ? GPIO_PIN_SET : GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, (stepSequence[currentStep] & 0x02) ? GPIO_PIN_SET : GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, (stepSequence[currentStep] & 0x04) ? GPIO_PIN_SET : GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, (stepSequence[currentStep] & 0x08) ? GPIO_PIN_SET : GPIO_PIN_RESET);
// 更新步序
currentStep = (currentStep + 1) % 4;
}
// 主函数
int main(void) {
HAL_Init();
SystemClock_Config(); // 配置系统时钟
GPIO_Init();
PWM_Init();
while (1) {
StepMotor_Update();
HAL_Delay(1); // 控制转速,调整延迟时间以改变转速
}
}
%
motor_inertia = 0.01; %
motor_damping = 0.1; %
% PID
pid_position = struct('kp', 0.5, 'ki', 0.1, 'kd', 0.01, 'out_limit', 100);
pid_speed = struct('kp', 0.1, 'ki', 0.01, 'kd', 0.05, 'out_limit', 100);
%
current_position = 0;
current_speed = 0;
target_position = 3600; %
dt = 0.01; % 仿
time = 0:dt:10; % 仿
%
position_data = zeros(size(time));
speed_data = zeros(size(time));
% PID
position_integral = 0;
position_prev_error = 0;
speed_integral = 0;
speed_prev_error = 0;
% 仿
for i = 1:length(time)
% PID
position_error = target_position - current_position;
position_integral = position_integral + position_error * dt;
position_derivative = (position_error - position_prev_error) / dt;
target_speed = pid_position.kp * position_error + ...
pid_position.ki * position_integral + ...
pid_position.kd * position_derivative;
target_speed = max(min(target_speed, pid_position.out_limit), -pid_position.out_limit);
position_prev_error = position_error;
% PID
speed_error = target_speed - current_speed;
speed_integral = speed_integral + speed_error * dt;
speed_derivative = (speed_error - speed_prev_error) / dt;
motor_pwm = pid_speed.kp * speed_error + ...
pid_speed.ki * speed_integral + ...
pid_speed.kd * speed_derivative;
motor_pwm = max(min(motor_pwm, pid_speed.out_limit), -pid_speed.out_limit);
speed_prev_error = speed_error;
%
motor_acceleration = motor_pwm / motor_inertia - motor_damping * current_speed;
current_speed = current_speed + motor_acceleration * dt;
current_position = current_position + current_speed * dt;
%
position_data(i) = current_position;
speed_data(i) = current_speed;
end
%
figure;
subplot(2, 1, 1);
plot(time, position_data);
title('');
xlabel(' (s)');
ylabel('');
subplot(2, 1, 2);
plot(time, speed_data);
title('');
xlabel(' (s)');
ylabel('');