Готовая реализация
This commit is contained in:
@ -32,7 +32,7 @@ extern volatile int16_t gyro_x, gyro_y, gyro_z;
|
|||||||
// Коэффициенты фильтр
|
// Коэффициенты фильтр
|
||||||
#define GYRO_SCALE 65.5f // Для +-500: 32768/500
|
#define GYRO_SCALE 65.5f // Для +-500: 32768/500
|
||||||
#define RAD_TO_DEG 57.29578f // Преобразование радиан в градусы
|
#define RAD_TO_DEG 57.29578f // Преобразование радиан в градусы
|
||||||
#define DT 0.001f // Период дискретизации (10 мс)
|
#define DT 0.0001f // Период дискретизации (100 мкс)
|
||||||
|
|
||||||
// Настраиваемые коэффициенты фильтрации
|
// Настраиваемые коэффициенты фильтрации
|
||||||
extern volatile float accel_filter_coeff; // Коэффициент ФНЧ для акселерометра (0.1-0.5)
|
extern volatile float accel_filter_coeff; // Коэффициент ФНЧ для акселерометра (0.1-0.5)
|
||||||
|
@ -0,0 +1,71 @@
|
|||||||
|
#include <StepperMotorDriver.h>
|
||||||
|
|
||||||
|
int16_t speedStepper1 = 0;
|
||||||
|
int16_t setSpeed1 = 200;
|
||||||
|
int16_t speedStepper2 = 0;
|
||||||
|
int16_t setSpeed2 = 200;
|
||||||
|
|
||||||
|
#define minSpeed 10.0f
|
||||||
|
#define maxSpeed 400.0f
|
||||||
|
|
||||||
|
void SetStepper1RotateSpeed(int16_t* speedStepper1)
|
||||||
|
{
|
||||||
|
if (abs(*speedStepper1) <= minSpeed | abs(*speedStepper1) >= maxSpeed)
|
||||||
|
{
|
||||||
|
TIM2->CCR1 = 0;
|
||||||
|
TIM2->EGR |= TIM_EGR_UG;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Управление направлением
|
||||||
|
if (*speedStepper1 > 0)
|
||||||
|
GPIOA->BSRR = GPIO_BSRR_BR1; // DIR = 0 (LOW)
|
||||||
|
else
|
||||||
|
GPIOA->BSRR = GPIO_BSRR_BS1; // DIR = 1 (HIGH)
|
||||||
|
|
||||||
|
uint32_t absSpeed = (*speedStepper1 > 0) ? *speedStepper1 : -(*speedStepper1);
|
||||||
|
|
||||||
|
uint32_t F_set = (N_FULL_STEP * MICROSTEPPING * absSpeed) / 60;
|
||||||
|
if (F_set == 0) return;
|
||||||
|
|
||||||
|
uint32_t arr_set = F_CLK / (PWM_PSC * F_set);
|
||||||
|
uint32_t ccr_set = (uint32_t)(arr_set * Duty);
|
||||||
|
|
||||||
|
if (arr_set < 10) arr_set = 10;
|
||||||
|
if (ccr_set < 1) ccr_set = 1;
|
||||||
|
|
||||||
|
TIM2->ARR = arr_set - 1;
|
||||||
|
TIM2->CCR1 = ccr_set;
|
||||||
|
|
||||||
|
TIM2->EGR |= TIM_EGR_UG;
|
||||||
|
}
|
||||||
|
//---------------------------------------------------------------------------------------------------------------
|
||||||
|
void SetStepper2RotateSpeed(int16_t* speedStepper2)
|
||||||
|
{
|
||||||
|
if (abs(*speedStepper2) <= minSpeed & abs(*speedStepper2) >= maxSpeed)
|
||||||
|
{
|
||||||
|
TIM2->CCR1 = 0;
|
||||||
|
TIM2->EGR |= TIM_EGR_UG;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Управление направлением
|
||||||
|
if (*speedStepper2 > 0)
|
||||||
|
GPIOB->BSRR = GPIO_BSRR_BR1; // DIR = 0 (LOW)
|
||||||
|
else
|
||||||
|
GPIOB->BSRR = GPIO_BSRR_BS1; // DIR = 1 (HIGH)
|
||||||
|
|
||||||
|
uint32_t absSpeed = (*speedStepper2 > 0) ? *speedStepper2 : -(*speedStepper2);
|
||||||
|
|
||||||
|
uint32_t F_set = (N_FULL_STEP * MICROSTEPPING * absSpeed) / 60;
|
||||||
|
if (F_set == 0) return;
|
||||||
|
|
||||||
|
uint32_t arr_set = F_CLK / (PWM_PSC * F_set);
|
||||||
|
uint32_t ccr_set = (uint32_t)(arr_set * Duty);
|
||||||
|
|
||||||
|
if (arr_set < 10) arr_set = 10;
|
||||||
|
if (ccr_set < 1) ccr_set = 1;
|
||||||
|
|
||||||
|
TIM3->ARR = arr_set - 1;
|
||||||
|
TIM3->CCR3 = ccr_set;
|
||||||
|
|
||||||
|
TIM3->EGR |= TIM_EGR_UG;
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
#include "stm32g431xx.h"
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#define N_FULL_STEP 200
|
||||||
|
#define MICROSTEPPING 8
|
||||||
|
#define F_CLK 170000000
|
||||||
|
#define PWM_PSC 17
|
||||||
|
#define Duty 0.05f
|
||||||
|
|
||||||
|
extern int16_t speedStepper1;
|
||||||
|
extern int16_t setSpeed1;
|
||||||
|
extern int16_t speedStepper2;
|
||||||
|
extern int16_t setSpeed2;
|
||||||
|
|
||||||
|
void SetStepper1RotateSpeed(int16_t* speedStepper1);
|
||||||
|
void SetStepper2RotateSpeed(int16_t* speedStepper2);
|
@ -1,8 +1,8 @@
|
|||||||
#include "PID.h"
|
#include "PID.h"
|
||||||
|
|
||||||
float KP = 100;
|
float KP = 100;
|
||||||
float KI = 1;
|
float KI = 0;
|
||||||
float KD = 1;
|
float KD = 10;
|
||||||
float integral = 0;
|
float integral = 0;
|
||||||
float lastError = 0;
|
float lastError = 0;
|
||||||
float limit = 1000; //ограничение интегральной составляющей
|
float limit = 1000; //ограничение интегральной составляющей
|
||||||
@ -40,4 +40,16 @@ float pid_update(float target, float current, float dt)
|
|||||||
// }
|
// }
|
||||||
// float output = pPart + iPart + dPart;
|
// float output = pPart + iPart + dPart;
|
||||||
// return output; //Управляющее воздействие/крутящий момент
|
// return output; //Управляющее воздействие/крутящий момент
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
#define Mc 0.21f //момент сцепления
|
||||||
|
#define J 820.0f //инерция ротора
|
||||||
|
#define dt 0.0001f
|
||||||
|
|
||||||
|
float integral_perevod = 0;
|
||||||
|
|
||||||
|
float perevod (float M){
|
||||||
|
integral_perevod += (M - Mc)*dt;
|
||||||
|
int omega = (int)(1.0f/J*integral_perevod);
|
||||||
|
return omega * 60.0f / 9.5493f;
|
||||||
|
}
|
@ -1,3 +1,5 @@
|
|||||||
|
#include <math.h>
|
||||||
|
#include "StepperMotorDriver.h"
|
||||||
float pid_update(float target, float current, float dt);
|
float pid_update(float target, float current, float dt);
|
||||||
float perevod(float pid_result);
|
float perevod(float pid_result);
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include "LSM6DS3.h"
|
#include "LSM6DS3.h"
|
||||||
#include "PID.h"
|
#include "PID.h"
|
||||||
|
#include <StepperMotorDriver.h>
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
@ -10,75 +11,9 @@
|
|||||||
//
|
//
|
||||||
//---------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------
|
||||||
//---------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------
|
||||||
int16_t speedStepper1 = 0;
|
|
||||||
int16_t setSpeed1 = 200;
|
|
||||||
int16_t speedStepper2 = 0;
|
|
||||||
int16_t setSpeed2 = 200;
|
|
||||||
|
|
||||||
#define N_FULL_STEP 200
|
|
||||||
#define MICROSTEPPING 8
|
|
||||||
#define F_CLK 170000000
|
|
||||||
#define PWM_PSC 17
|
|
||||||
#define Duty 0.05f
|
|
||||||
//---------------------------------------------------------------------------------------------------------------
|
|
||||||
void SetStepper1RotateSpeed(int16_t* speedStepper1)
|
|
||||||
{
|
|
||||||
if (*speedStepper1 == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Управление направлением
|
|
||||||
if (*speedStepper1 > 0)
|
|
||||||
GPIOA->BSRR = GPIO_BSRR_BR1; // DIR = 0 (LOW)
|
|
||||||
else
|
|
||||||
GPIOA->BSRR = GPIO_BSRR_BS1; // DIR = 1 (HIGH)
|
|
||||||
|
|
||||||
uint32_t absSpeed = (*speedStepper1 > 0) ? *speedStepper1 : -(*speedStepper1);
|
|
||||||
|
|
||||||
uint32_t F_set = (N_FULL_STEP * MICROSTEPPING * absSpeed) / 60;
|
|
||||||
if (F_set == 0) return;
|
|
||||||
|
|
||||||
uint32_t arr_set = F_CLK / (PWM_PSC * F_set);
|
|
||||||
uint32_t ccr_set = (uint32_t)(arr_set * Duty);
|
|
||||||
|
|
||||||
if (arr_set < 10) arr_set = 10;
|
|
||||||
if (ccr_set < 1) ccr_set = 1;
|
|
||||||
|
|
||||||
TIM2->ARR = arr_set - 1;
|
|
||||||
TIM2->CCR1 = ccr_set;
|
|
||||||
|
|
||||||
TIM2->EGR |= TIM_EGR_UG;
|
|
||||||
}
|
|
||||||
//---------------------------------------------------------------------------------------------------------------
|
|
||||||
void SetStepper2RotateSpeed(int16_t* speedStepper2)
|
|
||||||
{
|
|
||||||
if (*speedStepper2 == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Управление направлением
|
|
||||||
if (*speedStepper2 > 0)
|
|
||||||
GPIOB->BSRR = GPIO_BSRR_BR1; // DIR = 0 (LOW)
|
|
||||||
else
|
|
||||||
GPIOB->BSRR = GPIO_BSRR_BS1; // DIR = 1 (HIGH)
|
|
||||||
|
|
||||||
uint32_t absSpeed = (*speedStepper2 > 0) ? *speedStepper2 : -(*speedStepper2);
|
|
||||||
|
|
||||||
uint32_t F_set = (N_FULL_STEP * MICROSTEPPING * absSpeed) / 60;
|
|
||||||
if (F_set == 0) return;
|
|
||||||
|
|
||||||
uint32_t arr_set = F_CLK / (PWM_PSC * F_set);
|
|
||||||
uint32_t ccr_set = (uint32_t)(arr_set * Duty);
|
|
||||||
|
|
||||||
if (arr_set < 10) arr_set = 10;
|
|
||||||
if (ccr_set < 1) ccr_set = 1;
|
|
||||||
|
|
||||||
TIM3->ARR = arr_set - 1;
|
|
||||||
TIM3->CCR3 = ccr_set;
|
|
||||||
|
|
||||||
TIM3->EGR |= TIM_EGR_UG;
|
|
||||||
}
|
|
||||||
//---------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------
|
||||||
volatile uint32_t counter = 0;
|
volatile uint32_t counter = 0;
|
||||||
float res;
|
int res;
|
||||||
float u;
|
float u;
|
||||||
extern "C" void TIM4_IRQHandler(void)
|
extern "C" void TIM4_IRQHandler(void)
|
||||||
{
|
{
|
||||||
@ -100,7 +35,7 @@ extern "C" void TIM4_IRQHandler(void)
|
|||||||
if (fabsf(u) < 0.001f){
|
if (fabsf(u) < 0.001f){
|
||||||
u = 0.001f;
|
u = 0.001f;
|
||||||
}
|
}
|
||||||
res = (48/u);
|
res = perevod(u);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//---------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------
|
||||||
@ -162,8 +97,8 @@ int main()
|
|||||||
GPIOA->AFR[0] |= (1 << GPIO_AFRL_AFSEL0_Pos);// установка бита режима альтернативной функции
|
GPIOA->AFR[0] |= (1 << GPIO_AFRL_AFSEL0_Pos);// установка бита режима альтернативной функции
|
||||||
GPIOB->AFR[0] |= (2 << GPIO_AFRL_AFSEL0_Pos);// установка бита режима альтернативной функции
|
GPIOB->AFR[0] |= (2 << GPIO_AFRL_AFSEL0_Pos);// установка бита режима альтернативной функции
|
||||||
//-----------------------------------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------------------------------
|
||||||
TIM4->PSC = 170 - 1; // Предделитель 170 МГц / 170 = 1000 кГц
|
TIM4->PSC = 17 - 1; // Предделитель 170 МГц / 17 = 10000 кГц
|
||||||
TIM4->ARR = 1000 - 1; // Автоматическая перезагрузка (0.001 секунда)
|
TIM4->ARR = 1000 - 1; // Автоматическая перезагрузка (0.0001 секунда)
|
||||||
TIM4->DIER |= TIM_DIER_UIE; // Разрешить прерывание по обновлению
|
TIM4->DIER |= TIM_DIER_UIE; // Разрешить прерывание по обновлению
|
||||||
TIM4->CR1 |= TIM_CR1_CEN; // Включить таймер
|
TIM4->CR1 |= TIM_CR1_CEN; // Включить таймер
|
||||||
NVIC_EnableIRQ(TIM4_IRQn); // Включение прерывания
|
NVIC_EnableIRQ(TIM4_IRQn); // Включение прерывания
|
||||||
|
Reference in New Issue
Block a user