void Current_Sense_init() {
printf("ADC 开始初始化\r\n");
__HAL_TIM_SetCompare(&htim1,TIM_CHANNEL_4,2000);
HAL_ADCEx_InjectedStart_IT(&hadc1);
Voltage_to_Current = 1.0f / (sampling_resistor * Current_gain);
Gain_a = Voltage_to_Current * -1;
Gain_b = Voltage_to_Current;
}
void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef* hadc) {
if (hadc->Instance == ADC1) {
if(callback_counter <= 100) {
bias_voltage[0] += HAL_ADCEx_InjectedGetValue(&hadc1, ADC_INJECTED_RANK_1);
bias_voltage[1] += HAL_ADCEx_InjectedGetValue(&hadc1, ADC_INJECTED_RANK_2);
if(callback_counter == 100) {
My_adcData[0] = HAL_ADCEx_InjectedGetValue(&hadc1, ADC_INJECTED_RANK_1);
My_adcData[1] = HAL_ADCEx_InjectedGetValue(&hadc1, ADC_INJECTED_RANK_2);
bias_voltage_ia = (bias_voltage[0] / 100.0f);
bias_voltage_ib = (bias_voltage[1] / 100.0f);
differ_Ia = My_adcData[0] - bias_voltage_ia;
differ_Ib = My_adcData[1] - bias_voltage_ib;
adc_conversion_flag = 1;
My_adcData[0] = 0;
My_adcData[1] = 0;
HAL_ADCEx_InjectedStop_IT(&hadc1);
}
callback_counter++;
} else {
My_adcData[0] = (float)HAL_ADCEx_InjectedGetValue(&hadc1, ADC_INJECTED_RANK_1);
My_adcData[1] = (float)HAL_ADCEx_InjectedGetValue(&hadc1, ADC_INJECTED_RANK_2);
current.I_a = (My_adcData[0] - bias_voltage_ia ) * ADC_CONVERSION * Gain_a ;
current.I_b = (My_adcData[1] - bias_voltage_ib ) * ADC_CONVERSION * Gain_a ;
float I_alpha = 0;
float I_beta = 0;
arm_clarke_f32(current.I_a,current.I_b,&I_alpha,&I_beta);
rotor_angle_encoder = Get_Position_EncoderMode();
float sin_value = arm_sin_f32(rotor_angle_encoder);
float cos_value = arm_cos_f32(rotor_angle_encoder);
float _motor_Iq = 0;
float _motor_Id = 0;
arm_park_f32(I_alpha,I_beta,&_motor_Id,&_motor_Iq,sin_value,cos_value);
float filter_alpha_Id = 0.2;
float filter_alpha_Iq = 0.2;
motor_Id = low_pass_filter(_motor_Id,motor_Id,filter_alpha_Id);
motor_Iq = low_pass_filter(_motor_Iq,motor_Iq,filter_alpha_Iq);
}
}
}
void find_zeropoint() {
set_pwm_duty(0.4, 0, 0);
HAL_Delay(800);
set_pwm_duty(0, 0, 0);
HAL_Delay(800);
}
void set_pwm_duty(float d_u, float d_v, float d_w) {
d_u = min(d_u, 0.9f);
d_v = min(d_v, 0.9f);
d_w = min(d_w, 0.9f);
compare_1 = d_u * htim1.Instance->ARR;
compare_2 = d_v * htim1.Instance->ARR;
compare_3 = d_w * htim1.Instance->ARR;
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, d_u * htim1.Instance->ARR);
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_2, d_v * htim1.Instance->ARR);
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_3, d_w * htim1.Instance->ARR);
}
float PID_Calc_Current(PID_t *pid,float target,float actual) {
float error = target - actual / MAX_CURRENT;
pid->e = error;
pid->I += pid->Ki * pid->e;
if (pid->I > pid->I_max) pid->I = pid->I_max;
else if (pid->I < pid->I_min) pid->I = pid->I_min;
float u = pid->Kp * pid->e + pid->I + pid->Kd * (pid->e - pid->e_last);
pid->e_last = pid->e;
if (u > pid->out_max) u = pid->out_max;
else if (u < pid->out_min) u = pid->out_min;
return u;
}
typedef struct {
float Kp;
float Ki;
float Kd;
float e;
float e_last;
float I;
float out_min;
float out_max;
float I_min;
float I_max;
} PID_t;
void Torque_control(float torque_d , float torque_q) {
float d = PID_Calc_Current(&pid_torque_d,torque_d,motor_Id);
float q = PID_Calc_Current(&pid_torque_q,torque_q,motor_Iq);
foc_forward(d, q, rotor_angle_encoder);
}
void foc_forward(float d, float q, float rotor_rad) {
float d_u = 0;
float d_v = 0;
float d_w = 0;
svpwm(rotor_rad, d, q, &d_u, &d_v, &d_w);
set_pwm_duty(d_u, d_v, d_w);
}
static void svpwm(float phi, float d, float q, float *d_u, float *d_v, float *d_w) {
d = min(d, 1);
d = max(d, -1);
q = min(q, 1);
q = max(q, -1);
const int v[6][3] = {{1, 0, 0}, {1, 1, 0}, {0, 1, 0}, {0, 1, 1}, {0, 0, 1}, {1, 0, 1}};
const int K_to_sector[] = {4, 6, 5, 5, 3, 1, 2, 2};
float sin_phi = arm_sin_f32(phi);
float cos_phi = arm_cos_f32(phi);
float alpha = 0;
float beta = 0;
arm_inv_park_f32(d, q, &alpha, &beta, sin_phi, cos_phi);
bool A = beta > 0;
bool B = fabs(beta) > SQRT3 * fabs(alpha);
bool C = alpha > 0;
int K = 4 * A + 2 * B + C;
int sector = K_to_sector[K];
float t_m = arm_sin_f32(sector * rad60) * alpha - arm_cos_f32(sector * rad60) * beta;
float t_n = beta * arm_cos_f32(sector * rad60 - rad60) - alpha * arm_sin_f32(sector * rad60 - rad60);
float t_0 = 1 - t_m - t_n;
*d_u = t_m * v[sector - 1][0] + t_n * v[sector % 6][0] + t_0 / 2;
*d_v = t_m * v[sector - 1][1] + t_n * v[sector % 6][1] + t_0 / 2;
*d_w = t_m * v[sector - 1][2] + t_n * v[sector % 6][2] + t_0 / 2;
}