STM32G4-DRV8301-FOC/FOC_Related/FOC/FOC.c

508 lines
15 KiB
C
Raw Normal View History

2024-07-22 13:55:29 +08:00
#include "FOC.h"
#include "math.h"
#include "as5600.h"
#include "main.h"
#include "control.h"
#include "tim.h"
#include "pid.h"
#include "adc.h"
#include "usart.h"
#include "string.h"
#include "stdio.h"
#include "adc.h"
#include "LowPass_Filter.h"
2024-07-27 22:33:57 +08:00
#include "ABZ.h"
2024-07-22 13:55:29 +08:00
extern int PP;
extern int DIR;
extern float voltage_limit;
extern float voltage_power_supply;
extern float zero_electric_angle;
extern float Ualpha, Ubeta;
extern float Ua, Ub, Uc;
extern float dc_a, dc_b, dc_c;
extern float Sensor_Angle;
extern float Sensor_Speed;
2024-07-27 22:33:57 +08:00
extern float ABZ_Sensor_Speed;
extern float ABZ_Sensor_Angle;
2024-07-22 13:55:29 +08:00
extern uint32_t adc1_Ia, adc1_Ib, adc1_Ic;
extern uint32_t adc2_Ia, adc2_Ib, adc2_Ic;
extern float current1_A;
extern float current1_B;
extern float current1_C;
extern float volts_to_amps_ratio;
extern float gain_a, gain_b, gain_c;
extern float offset_ia, offset_ib, offset_ic;
extern float i_alpha;
extern float i_beta;
extern float id;
extern float iq;
extern float id_ref;
extern float iq_ref;
extern float Ud;
extern float Uq_new;
uint16_t filtered_ADC1_Ia;
uint16_t filtered_ADC1_Ib;
uint16_t filtered_ADC1_Ic;
/*******************************************
SysTick<EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>(ģ<EFBFBD><EFBFBD>micros<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>)<EFBFBD><EFBFBD>
<EFBFBD><EFBFBD>ע<EFBFBD><EFBFBD>
1.<EFBFBD><EFBFBD>0xFFFFFF<EFBFBD><EFBFBD>0ѭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2.<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>޷<EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>delay<EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*******************************************/
void Systick_CountMode(void)
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵ<EFBFBD><CFB5><EFBFBD>϶<EFBFBD>ͨ<EFBFBD>õij<C3B5>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
SysTick->LOAD = 0xFFFFFF; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5>ʼ
SysTick->VAL = 0; // <20><><EFBFBD>յ<EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk; // ʹ<><CAB9> SysTick <20><>ʱ<EFBFBD><CAB1>
}
/*******************************************
<EFBFBD><EFBFBD><EFBFBD>Ƕ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD>ע<EFBFBD><EFBFBD>
1. <EFBFBD><EFBFBD><EFBFBD>Ƕ<EFBFBD> = <EFBFBD><EFBFBD>е<EFBFBD>Ƕ<EFBFBD> * <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2._electricalAngle = shaft_angle * pole_pairs
*******************************************/
float _electricalAngle()
{
return _normalizeAngle((float)(DIR * PP) * AS5600_GetAngle2PI() - zero_electric_angle);
}
2024-07-27 22:33:57 +08:00
//////debug ABZ Encoder//////
float ABZ_electricalAngle()
{
return _normalizeAngle((float)(DIR * PP) * ABZ_GetAngle2PI() - zero_electric_angle);
}
2024-07-22 13:55:29 +08:00
/*******************************************
<EFBFBD>Ƕȹ<EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:
<EFBFBD><EFBFBD>ע<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ù<EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD>ۼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*******************************************/
float _normalizeAngle(float angle)
{
float a = fmod(angle, 2 * PI);
return a >= 0 ? a : (a + 2 * PI);
// <20><>Ŀ<EFBFBD><C4BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD><CABD>condition ? expr1 : expr2
// <20><><EFBFBD><EFBFBD>,conditionʽҪ<CABD><D2AA>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<2C>򷵻<EFBFBD> expr1 <20><>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD>Խ<EFBFBD><D4BD><EFBFBD>Ŀ<EFBFBD><C4BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>if-else<73>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD>ʽ
}
/*******************************************
PWMռ<EFBFBD>ձ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:
*******************************************/
void setPWM(float Ua, float Ub, float Uc)
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѹ<EFBFBD>޷<EFBFBD>
Ua = _constrain(Ua, 0.0f, voltage_limit);
Ub = _constrain(Ub, 0.0f, voltage_limit);
Uc = _constrain(Uc, 0.0f, voltage_limit);
// ռ<>ձȼ<D5B1><C8BC><EFBFBD><E3A3AC><EFBFBD><EFBFBD><EFBFBD>޷<EFBFBD>
dc_a = _constrain(Ua / voltage_power_supply, 0.0f, 1.0f);
dc_b = _constrain(Ub / voltage_power_supply, 0.0f, 1.0f);
dc_c = _constrain(Uc / voltage_power_supply, 0.0f, 1.0f);
// <20><><EFBFBD><EFBFBD>1 6·PWMռ<4D>ձ<EFBFBD><D5B1><EFBFBD><EFBFBD><EFBFBD>
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, dc_a * 5500);
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_2, dc_b * 5500);
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_3, dc_c * 5500);
//__HAL_TIM_SET_COMPARE(&htim8, TIM_CHANNEL_1, dc_a * 5500);
//__HAL_TIM_SET_COMPARE(&htim8, TIM_CHANNEL_2, dc_b * 5500);
//__HAL_TIM_SET_COMPARE(&htim8, TIM_CHANNEL_3, dc_c * 5500);
}
/*******************************************
<EFBFBD><EFBFBD><EFBFBD>ؿ<EFBFBD><EFBFBD><EFBFBD>:
*******************************************/
void setTorque(float Uq, float angle_el)
{
// <20><><EFBFBD><EFBFBD><EFBFBD>޷<EFBFBD><DEB7><EFBFBD>
Uq = _constrain(Uq, -voltage_power_supply / 2, voltage_power_supply / 2);
// <20>Ƕȹ<C7B6>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
angle_el = _normalizeAngle(angle_el);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
Ualpha = -Uq * sin(angle_el);
Ubeta = Uq * cos(angle_el);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
Ua = Ualpha + voltage_power_supply / 2;
Ub = (sqrt(3) * Ubeta - Ualpha) / 2 + voltage_power_supply / 2;
Uc = (-Ualpha - sqrt(3) * Ubeta) / 2 + voltage_power_supply / 2;
// PWM<57><4D>ֵ
setPWM(Ua, Ub, Uc);
}
/*******************************************
FOC<EFBFBD><EFBFBD><EFBFBD>Ƴ<EFBFBD>ʼ<EFBFBD><EFBFBD>:
*******************************************/
void FOC_Init(float power_supply)
{
2024-07-27 22:33:57 +08:00
voltage_power_supply = power_supply; // <20><>Դ<EFBFBD><D4B4>ѹ<EFBFBD><D1B9><EFBFBD>Ρ<EFBFBD>
2024-07-22 13:55:29 +08:00
// <20>˴<EFBFBD><CBB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD>Ӳ<EFBFBD><D3B2><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>
2024-07-27 22:33:57 +08:00
PID_init(); // pid<69><64>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>
2024-07-22 13:55:29 +08:00
}
/*******************************************
FOC<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݳ<EFBFBD>ʼ<EFBFBD><EFBFBD>:
*******************************************/
void FOC_AS5600_Init(int _PP, int _DIR)
{
// ֵ<><D6B5><EFBFBD>ݡ<EFBFBD>
PP = _PP;
DIR = _DIR;
2024-07-26 14:51:23 +08:00
setTorque(3, _2PI);
HAL_Delay(3000);
2024-07-22 13:55:29 +08:00
setTorque(0, _2PI);
zero_electric_angle = _electricalAngle(); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƕȡ<C7B6>
Sensor_Speed = AS5600_Get_Speed(); // <20>ٶȳ<D9B6>ʼֵ<CABC><D6B5><EFBFBD>
}
2024-07-27 22:33:57 +08:00
/////ABZ Encoder debug/////
void FOC_ABZ_Init(int _PP, int _DIR)
{
// ֵ<><D6B5><EFBFBD>ݡ<EFBFBD>
PP = _PP;
DIR = _DIR;
2024-07-28 22:53:27 +08:00
setTorque(3, _2PI);
2024-07-27 22:33:57 +08:00
HAL_Delay(3000);
setTorque(0, _2PI);
zero_electric_angle = ABZ_electricalAngle(); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƕȡ<C7B6>
ABZ_Sensor_Speed = ABZ_Get_Speed(); // <20>ٶȳ<D9B6>ʼֵ<CABC><D6B5><EFBFBD>
}
2024-07-22 13:55:29 +08:00
/***********************************************
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƕȿ<EFBFBD><EFBFBD><EFBFBD>:(rad)
***********************************************/
2024-07-27 22:33:57 +08:00
// ABZ<42><5A><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void ABZ_Set_Angle(float Angle)
{
// ABZ<42><5A><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƕȶ<C7B6>ȡ<EFBFBD><C8A1>
ABZ_Sensor_Angle = ABZ_GetAngle();
// <20>Ƕȿ<C7B6><C8BF>ơ<EFBFBD>
Angle_Out = Angle_Control((Angle - DIR * ABZ_Sensor_Angle) * 180.0f / PI);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>޷<EFBFBD><DEB7><EFBFBD>
Moment_limiting();
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ء<EFBFBD>
setTorque(Angle_Out, ABZ_electricalAngle());
// <20>Ƕȴ<C7B6><C8B4>ڴ<EFBFBD>ӡ<EFBFBD><D3A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// printf("%.2f,%.2f\n",Sensor_Angle,Angle_target);
}
// AS5600<30><30><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2024-07-22 13:55:29 +08:00
void Set_Angle(float Angle)
{
// AS5600<30>Ƕȶ<C7B6>ȡ<EFBFBD><C8A1>
Sensor_Angle = AS5600_GetAngle();
// <20>Ƕȿ<C7B6><C8BF>ơ<EFBFBD>
Angle_Out = Angle_Control((Angle - DIR * Sensor_Angle) * 180.0f / PI);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>޷<EFBFBD><DEB7><EFBFBD>
Moment_limiting();
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ء<EFBFBD>
setTorque(Angle_Out, _electricalAngle());
// <20>Ƕȴ<C7B6><C8B4>ڴ<EFBFBD>ӡ<EFBFBD><D3A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// printf("%.2f,%.2f\n",Sensor_Angle,Angle_target);
}
/***********************************************
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ٶȿ<EFBFBD><EFBFBD><EFBFBD>:(rad/s)
***********************************************/
2024-07-27 22:33:57 +08:00
// ABZ<42><5A><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void ABZ_Set_Speed(float Speed)
{
// <20><>ȡABZ<42><5A><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݡ<EFBFBD>
ABZ_Sensor_Speed = ABZ_Get_Speed();
// <20>ٶ<EFBFBD>PID<49><44><EFBFBD><EFBFBD>
Speed_Out = Speed_Control(Speed - ABZ_Sensor_Speed);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>޷<EFBFBD>
Moment_limiting();
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ؿ<EFBFBD><D8BF><EFBFBD>
setTorque(Speed_Out, ABZ_electricalAngle());
// <20>ٶȴ<D9B6><C8B4>ڴ<EFBFBD>ӡ<EFBFBD><D3A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// printf("%.2f,%.2f\n",Sensor_Speed,Speed_target);
}
// AS5600<30><30><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2024-07-22 13:55:29 +08:00
void Set_Speed(float Speed)
{
// AS5600<30><30>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݡ<EFBFBD>
Sensor_Speed = AS5600_Get_Speed();
// <20>ٶ<EFBFBD>PID<49><44><EFBFBD><EFBFBD>
Speed_Out = Speed_Control(Speed - Sensor_Speed);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>޷<EFBFBD>
Moment_limiting();
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ؿ<EFBFBD><D8BF><EFBFBD>
setTorque(Speed_Out, _electricalAngle());
// <20>ٶȴ<D9B6><C8B4>ڴ<EFBFBD>ӡ<EFBFBD><D3A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// printf("%.2f,%.2f\n",Sensor_Speed,Speed_target);
}
2024-07-27 22:33:57 +08:00
2024-07-22 13:55:29 +08:00
/***********************************************
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ת:
***********************************************/
void Open_Loop_Control(float Uq, float speed)
{
// <20><>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD>յ<EFBFBD><D5B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5>
// char buffer[50]; // <20><><EFBFBD>ڴ洢ת<E6B4A2><D7AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>
// int length = 0;
float angle_el; // <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD>Ƕ<EFBFBD>
2024-07-28 22:53:27 +08:00
float circulation;
for (circulation=0;circulation<1000;circulation++)
2024-07-22 13:55:29 +08:00
{
// Read_ADC1_Values();
Send_ADC1_Values(&huart1); // <20><><EFBFBD><EFBFBD> ADC1 <20><>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>
// <20><><EFBFBD>µ<EFBFBD><C2B5>Ƕ<EFBFBD>
angle_el += speed;
angle_el = _normalizeAngle(angle_el);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
setTorque(Uq, angle_el);
// <20><>ȡ<EFBFBD><C8A1>ǰADCֵ
// <20><><EFBFBD>Դ<EFBFBD>ӡ<EFBFBD><D3A1>ȷ<EFBFBD><C8B7>ADCֵ<43>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD>ȷ<EFBFBD><C8B7>ȡ
// HAL_UART_Transmit(&huart1, "Toggle LED0!\r\n", sizeof("Toggle LED0!\r\n"),10000);
// HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart1, uint8_t *adc1_Ia, sizeof(adc1_Ia), 1);
// length = snprintf(buffer, sizeof(buffer), "ADC1_Ia: %lu\r\n", adc2_Ia);
// HAL_UART_Transmit(&huart1, (uint8_t *)buffer, length, HAL_MAX_DELAY);
// <20><>ʱ<EFBFBD><CAB1>ȷ<EFBFBD><C8B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD><C6B5>
2024-07-28 22:53:27 +08:00
HAL_Delay(1);//<2F>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD><EFBFBD>Ŀ<EFBFBD><C4BF><EFBFBD><EFBFBD>е<EFBFBD>Ƕ<EFBFBD>
2024-07-22 13:55:29 +08:00
}
2024-07-28 22:53:27 +08:00
HAL_Delay(2000); // <20><><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ
2024-07-22 13:55:29 +08:00
}
/***********************************************
<EFBFBD><EFBFBD><EFBFBD><EFBFBD> ADC <EFBFBD><EFBFBD>ƫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĺ<EFBFBD><EFBFBD><EFBFBD>:
***********************************************/
void calibrateOffsets()
{
const int calibration_rounds = 1000;
// <20><><EFBFBD><EFBFBD>0<EFBFBD><30><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD>ĵ<EFBFBD>ѹ
offset_ia = 0;
offset_ib = 0;
offset_ic = 0;
// <20><><EFBFBD><EFBFBD>1000<30><30>
for (int i = 0; i < calibration_rounds; i++)
{
offset_ia += adc1_Ia * (3.3f / 4095.0f); // <20><>ԭʼֵ<CABC><D6B5><EFBFBD><EFBFBD>ʵ<EFBFBD>ʵ<EFBFBD>ѹֵ<D1B9>ۼӽ<DBBC>offset_ia
offset_ib += adc1_Ib * (3.3f / 4095.0f);
offset_ic += adc1_Ic * (3.3f / 4095.0f);
}
// <20><>ƽ<EFBFBD><C6BD><EFBFBD><EFBFBD><EFBFBD>õ<EFBFBD><C3B5><EFBFBD><EFBFBD><EFBFBD>
offset_ia = offset_ia / calibration_rounds;
offset_ib = offset_ib / calibration_rounds;
offset_ic = offset_ic / calibration_rounds;
// ʵ<><CAB5>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>500mv<6D><76>Ӧ5A<35><41><EFBFBD><EFBFBD><EFBFBD><EFBFBD>x10<31><30><EFBFBD>ʹ<CDB4>˶<EFBFBD>Ӧ<EFBFBD>ĵ<EFBFBD><C4B5><EFBFBD><EFBFBD><EFBFBD>
volts_to_amps_ratio = 1.0f / 0.01f / 10; // 1/(0.01o+10) <20><><EFBFBD>ò<EFBFBD><C3B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŵ<EFBFBD><C5B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <20><><EFBFBD>õ<EFBFBD><C3B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5>
gain_a = volts_to_amps_ratio * -1;
gain_b = volts_to_amps_ratio * -1;
gain_c = volts_to_amps_ratio * -1;
}
/***********************************************
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
***********************************************/
void Feedback_Current()
{
// <20><><EFBFBD><EFBFBD><E3BBAC><EFBFBD>˲<EFBFBD><CBB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><C4B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD>ʵ<EFBFBD>ѹ<EFBFBD><D1B9>-ƫִ<C6AB><D6B4>ѹ<EFBFBD><D1B9>*<2A><><EFBFBD><EFBFBD>
current1_A = ((filtered_ADC1_Ia * (3.3f / 4095.0f)) - offset_ia) * gain_a;
current1_B = ((filtered_ADC1_Ib * (3.3f / 4095.0f)) - offset_ib) * gain_b;
current1_C = ((filtered_ADC1_Ic * (3.3f / 4095.0f)) - offset_ic) * gain_c;
}
/***********************************************
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ؿ<EFBFBD><EFBFBD><EFBFBD>:
***********************************************/
void Current_Speed(float Uq, float speed)
{
float angle_el = 0;
calibrateOffsets(); // У׼<D0A3><D7BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
while (1)
{
// uint8_t Senbuff[] = "Serial Output Message by DMA! \r\n"; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݷ<EFBFBD><DDB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
Send_ADC1_Values(&huart1); // <20><><EFBFBD><EFBFBD>1 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>DMA<4D><41><EFBFBD>ͺ<EFBFBD><CDBA><EFBFBD><EFBFBD><EFBFBD>
angle_el += speed; // <20><><EFBFBD><EFBFBD><EFBFBD>ۼӸ<DBBC><D3B8>µ<EFBFBD><C2B5>Ƕȡ<C7B6>
angle_el = _normalizeAngle(angle_el); // <20>Ƕȹ<C7B6>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
Current_Loop(Uq, angle_el); // <20><><EFBFBD>õ<EFBFBD><C3B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//HAL_Delay(1); // <20><>ʱ<EFBFBD><CAB1>
}
}
/***********************************************
<EFBFBD><EFBFBD><EFBFBD>ڷ<EFBFBD><EFBFBD><EFBFBD>ADC1ֵ
<EFBFBD><EFBFBD>ע<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
***********************************************/
void Send_ADC1_Values(UART_HandleTypeDef *huart)
{
char buffer[100];
int len;
Read_ADC1_Values(); // <20><><EFBFBD>ȶ<EFBFBD>ȡԭʼADC<44><43><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5>
// uint8_t Senbuff[] = " DMA OK! \r\n"; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݷ<EFBFBD><DDB7>Ͳ<EFBFBD><CDB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <20><>ȡ ADC1 <20><>ֵ<EFBFBD><D6B5>
uint16_t new_adc1_Ia = adc1_Ia;
uint16_t new_adc1_Ib = adc1_Ib;
uint16_t new_adc1_Ic = adc1_Ic;
// <20><><EFBFBD><EFBFBD><EFBFBD>˲<EFBFBD><CBB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD>˲<EFBFBD><CBB2><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5>
filtered_ADC1_Ia = ADC_Filter_Update(&adc1_filter_Ia, new_adc1_Ia);
filtered_ADC1_Ib = ADC_Filter_Update(&adc1_filter_Ib, new_adc1_Ib);
filtered_ADC1_Ic = ADC_Filter_Update(&adc1_filter_Ic, new_adc1_Ic);
Feedback_Current(); // <20><>ȡ<EFBFBD><C8A1><EFBFBD>õķ<C3B5><C4B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <20><>ʽ<EFBFBD><CABD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ADC1 <20><>ֵת<D6B5><D7AA>Ϊ<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӡ<EFBFBD>˲<EFBFBD><CBB2><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5>
len = snprintf(buffer, sizeof(buffer), "%u, %u, %u\n", filtered_ADC1_Ia, filtered_ADC1_Ib, filtered_ADC1_Ic);
// ͨ<><CDA8><EFBFBD><EFBFBD><EFBFBD>ڷ<EFBFBD><DAB7><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>
HAL_UART_Transmit(huart, (uint8_t *)buffer, len, 3); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӡ<EFBFBD>ٶ<EFBFBD><D9B6><EFBFBD><EFBFBD><EFBFBD>ȥ<EFBFBD><C8A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// HAL_UART_Transmit_DMA(&huart, (uint8_t *)Senbuff, sizeof(Senbuff));//DMA<4D><41><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// HAL_Delay(1);
}
/***********************************************
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
***********************************************/
void Current_Loop(float Uq, float angle_el)
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ת<EFBFBD><D7AA>Ϊ<EFBFBD><CEAA>-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵ<EFBFBD><CFB5>
// ʹ<><CAB9>Clarke<6B><EFBFBD><E4BBBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>abc<62><63>ת<EFBFBD><D7AA>Ϊ<EFBFBD><CEAA>-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵ<EFBFBD>ĵ<EFBFBD><C4B5><EFBFBD><EFBFBD><EFBFBD>i<EFBFBD><69>, i<>£<EFBFBD><C2A3><EFBFBD>
i_alpha = current1_A;
i_beta = (current1_A + 2 * current1_B) / sqrt(3.0f);
// <20><><EFBFBD><EFBFBD>-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵ<EFBFBD>ĵ<EFBFBD><C4B5><EFBFBD>ת<EFBFBD><D7AA>Ϊd-q<><71><EFBFBD><EFBFBD>ϵ<EFBFBD><CFB5>
// ʹ<><CAB9>Park<72><EFBFBD><E4BBBB><EFBFBD><EFBFBD>-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵ<EFBFBD>ĵ<EFBFBD><C4B5><EFBFBD><EFBFBD><EFBFBD>i<EFBFBD><69>, i<>£<EFBFBD>ת<EFBFBD><D7AA>Ϊd-q<><71><EFBFBD><EFBFBD>ϵ<EFBFBD>ĵ<EFBFBD><C4B5><EFBFBD><EFBFBD><EFBFBD>id, iq<69><71><EFBFBD><EFBFBD>
id = i_alpha * cos(angle_el) + i_beta * sin(angle_el);
iq = -i_alpha * sin(angle_el) + i_beta * cos(angle_el);
id_ref = 0.0f; // d<><64><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ο<EFBFBD>ֵΪ0
iq_ref = Uq; // q<><71><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ο<EFBFBD>ֵΪĿ<CEAA><C4BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// PID<49><44><EFBFBD>Ƽ<EFBFBD><C6BC><EFBFBD>
Ud = Current_Control(id_ref - id);
Uq_new = Current_Control(iq_ref - iq);
// ʹ<><CAB9><EFBFBD><EFBFBD>Park<72><EFBFBD><E4BBBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵ<EFBFBD>ĵ<EFBFBD>ѹ
Ualpha = Ud * cos(angle_el) - Uq_new * sin(angle_el);
Ubeta = Ud * sin(angle_el) + Uq_new * cos(angle_el);
// <20><><EFBFBD><EFBFBD>-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵ<EFBFBD>ĵ<EFBFBD>ѹת<D1B9><D7AA>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѹ<EFBFBD><D1B9>
// ʹ<><CAB9><EFBFBD><EFBFBD>Clarke<6B><EFBFBD><E4BBBB><EFBFBD><EFBFBD>-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵ<EFBFBD>ĵ<EFBFBD>ѹ<EFBFBD><D1B9>v<EFBFBD><76>, v<>£<EFBFBD>ת<EFBFBD><D7AA>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѹ<EFBFBD><D1B9>va, vb, vc<76><63><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E4BBBB>
Ua = Ualpha + voltage_power_supply / 2;
Ub = (sqrt(3) * Ubeta - Ualpha) / 2 + voltage_power_supply / 2;
Uc = (-Ualpha - sqrt(3) * Ubeta) / 2 + voltage_power_supply / 2;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѹӦ<D1B9><D3A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѹӦ<D1B9><D3A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>PWM<57>ź<EFBFBD><C5BA>ϡ<EFBFBD>
// PWM<57><4D>ֵ<EFBFBD><D6B5>
setPWM(Ua, Ub, Uc);
}
// ///////////////////////////////////////////////////////////////////////////
// /***********************************************
// <20><><EFBFBD><EFBFBD>(Ratchet_Wheel)ģʽ<C4A3><CABD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><50><D6B5><EFBFBD>ò<EFBFBD>ͬ<EFBFBD>ն<EFBFBD>(rigidity)
// DFOC_M0_setTorque(Kp*(target-DFOC_M0_Angle()));
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ã<EFBFBD>DFOC_M0_setTorque
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD>ϵ<EFBFBD><CFB5><EFBFBD><EFBFBD>Kp
// Ҫ<><D2AA><EFBFBD><EFBFBD>λ<EFBFBD>õ<EFBFBD>Ŀ<EFBFBD><C4BF><EFBFBD>Ƕȣ<C7B6>target
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><C4B5><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD>Ƕȣ<C7B6>DFOC_M0_Angle
// ***********************************************/
// /*arduino dengfoc
// float attractor_distance = 45*PI/180.0;
// float target = round(DFOC_M0_Angle() / attractor_distance) * attractor_distance;
// DFOC_M0_setTorque(Kp * (target - DFOC_M0_Angle()));
// */
// void Ratchet_Wheel(float Angle)
// {
// // 8<><38><EFBFBD>ٴ<EFBFBD><D9B4><EFBFBD>,<2C>Ƕ<EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD>ɻ<EFBFBD><C9BB><EFBFBD>ֵ<EFBFBD><D6B5>
// float attractor_distance = Angle * PI / 180.0f;
// // <20><><EFBFBD><EFBFBD>Pֵ,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӡ<EFBFBD>
// float P = 5;
// // <20><><EFBFBD><EFBFBD>Ŀ<EFBFBD><C4BF>ֵ<EFBFBD><D6B5>
// float target = round(AS5600_GetAngle() / attractor_distance) * attractor_distance;
// // <20>նȿ<D5B6><C8BF>ơ<EFBFBD>
// setTorque(P * (target - AS5600_GetAngle()), _electricalAngle());
// }
// /***********************************************
// <20>߽<EFBFBD><DFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(Boundary_Moment_limitation)ģʽ<C4A3><CABD>
// 1<><31><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD>Ƕ<EFBFBD>
// 2<><32><EFBFBD><EFBFBD><E8B6A8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ť<EFBFBD><C5A5>ת<EFBFBD><D7AA><EFBFBD><EFBFBD>Χ
// 3<><33><EFBFBD><EFBFBD><EFBFBD>Ƕ<EFBFBD><C7B6><EFBFBD>ת<EFBFBD><D7AA>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// ***********************************************/
// void Boundary_Moment_limitation(float angle_range)
// {
// float P = 5;
// // <20><EFBFBD><E8B6A8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ť<EFBFBD><C5A5>ת<EFBFBD><D7AA><EFBFBD><EFBFBD>Χ 90<39><30>
// // float angle_range = 90.0;
// // <20><EFBFBD><E8B6A8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ť<EFBFBD><C5A5>ת<EFBFBD><D7AA><EFBFBD><EFBFBD>Χ<EFBFBD>м<EFBFBD>ֵ 45<34><35>
// float angle_range2 = angle_range / 2;
// // <20>м<EFBFBD>ֵת<D6B5><D7AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// float limit_range = angle_range2 / 360.0f * _2PI;
// float L1 = zero_electric_angle + limit_range;
// float L2 = zero_electric_angle - limit_range;
// if (AS5600_GetAngle() > L2 && AS5600_GetAngle() < L1)
// {
// setTorque(0, _electricalAngle()); // <20>޶<EFBFBD><DEB6><EFBFBD>
// // 6<><36><EFBFBD>ٴ<EFBFBD><D9B4><EFBFBD>,<2C>Ƕ<EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD>ɻ<EFBFBD><C9BB><EFBFBD>ֵ
// // float attractor_distance = 15 * PI / 180.0;
// // <20><><EFBFBD><EFBFBD>
// // float P = 5;
// // float target = round(get_Angle()/attractor_distance)*attractor_distance;
// //<2F>նȿ<D5B6><C8BF><EFBFBD>
// setTorque(P*(target - get_Angle()),_electricalAngle());
// }
// else
// {
// if (AS5600_GetAngle() < L2)
// setTorque(P * (L2 - AS5600_GetAngle()), _electricalAngle());
// if (AS5600_GetAngle() > L1)
// setTorque(P * (L1 - AS5600_GetAngle()), _electricalAngle());
// }
// }
/***********************************************
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>(damping)ģʽ<EFBFBD><EFBFBD>
***********************************************/
/***********************************************
˳<EFBFBD><EFBFBD>(smooth)ģʽ<EFBFBD><EFBFBD>
***********************************************/
/***********************************************
ʧ<EFBFBD><EFBFBD>(weightlessness)ģʽ<EFBFBD><EFBFBD>
***********************************************/