1.代码含矫正的void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef *hadc) { int32_t ADCDataReg[4]; HAL_GPIO_TogglePin(LED3_GPIO_Port, LED3_Pin); MOTOR_vars.ISRCount; ADCDataReg[0] hadc1.Instance-JDR1; //ia ADCDataReg[1] hadc2.Instance-JDR1; //ib ADCDataReg[2] hadc1.Instance-JDR2; //ic ADCDataReg[3] hadc2.Instance-JDR2; //ia /* Disable ADC trigger source */ /* LL_TIM_CC_DisableChannel(TIMx, LL_TIM_CHANNEL_CH4) */ LL_TIM_SetTriggerOutput(TIM1, LL_TIM_TRGO_RESET); RCM_Conv(); if(MOTOR_vars.offset_complete 0) { if(MOTOR_vars.offset_I_ad_cnt 0) { AdcData.offset_I_ad_sum.value[0] 0; AdcData.offset_I_ad_sum.value[1] 0; AdcData.offset_I_ad_sum.value[2] 0; } AdcData.offset_I_ad_sum.value[0] ADCDataReg[0]; AdcData.offset_I_ad_sum.value[1] ADCDataReg[1]; AdcData.offset_I_ad_sum.value[2] ADCDataReg[2]; MOTOR_vars.offset_I_ad_cnt ; if(MOTOR_vars.offset_I_ad_cnt 256) { MOTOR_vars.offset_I_ad_cnt 0; AdcData.offset_I_ad.value[0] AdcData.offset_I_ad_sum.value[0]8; AdcData.offset_I_ad.value[1] AdcData.offset_I_ad_sum.value[1]8; AdcData.offset_I_ad.value[2] AdcData.offset_I_ad_sum.value[2]8; AdcData.offset_I_ad_sum.value[0] 0; AdcData.offset_I_ad_sum.value[1] 0; AdcData.offset_I_ad_sum.value[2] 0; MOTOR_vars.offset_complete 1; } } else { AdcData.I_A.value[0] ((ADCDataReg[0]-AdcData.offset_I_ad.value[0])*USER_M1_ADC_FULL_SCALE_CURRENT_A) 15; AdcData.I_A.value[1] ((ADCDataReg[1]-AdcData.offset_I_ad.value[1])*USER_M1_ADC_FULL_SCALE_CURRENT_A) 15; AdcData.I_A.value[2] ((ADCDataReg[2]-AdcData.offset_I_ad.value[2])*USER_M1_ADC_FULL_SCALE_CURRENT_A) 15; //MOTOR_vars.speed_int_Hz 100; ANGLE_GEN_run(MOTOR_vars.speed_int_Hz); // Speed reference value, Hz MOTOR_vars.angleGen_rad MOTOR_vars.angle_rad; // the rotor angle from Generator modules // Trig_Components Local_Vector_Components; // 3 sinwave // Local_Vector_Components MCM_Trig_Functions(MOTOR_vars.angleGen_rad); // AdcData.I_A.value[0] Local_Vector_Components.hSin; // Local_Vector_Components MCM_Trig_Functions(MOTOR_vars.angleGen_rad-21845); //120degree // AdcData.I_A.value[1] Local_Vector_Components.hSin; // Local_Vector_Components MCM_Trig_Functions(MOTOR_vars.angleGen_rad21845); //240degree // AdcData.I_A.value[2] Local_Vector_Components.hSin; CLARKE_run(AdcData.I_A, MOTOR_vars.Iab_A); MOTOR_vars.counterTrajSpeed; if(MOTOR_vars.counterTrajSpeed 1) { // clear counter MOTOR_vars.counterTrajSpeed 0; MOTOR_vars.trajHandle_spd.targetValue MOTOR_vars.speedForce_Hz * MOTOR_vars.direction; // run a trajectory for speed reference, // so the reference changes with a ramp instead of a step TRAJ_run(MOTOR_vars.trajHandle_spd.targetValue); } MOTOR_vars.speed_int_Hz MOTOR_vars.trajHandle_spd.intValueq15 15; MOTOR_vars.oneOverDcBus_invq15 32767/ AdcData.VdcBus_V; //q15 MOTOR_vars.hElAngle MOTOR_vars.angleGen_rad; // MOTOR_vars.hElAngle 100; PARK_run(MOTOR_vars.Iab_A,MOTOR_vars.Idq_in_A,MOTOR_vars.hElAngle); // I/f Profile open-loop in build level 3 MOTOR_vars.IdqRef_A.value[0] MOTOR_vars.Idq_set_A.value[0]; MOTOR_vars.IdqRef_A.value[1] MOTOR_vars.Idq_set_A.value[1]; // Maximum voltage output //MOTOR_vars.VsMax_V MOTOR_vars.maxVsMag_pu * AdcData.VdcBus_V; MOTOR_vars.VsMax_V MOTOR_vars.maxVsMag_pu; MOTOR_vars.piHandle_Id.outMin -MOTOR_vars.VsMax_V; MOTOR_vars.piHandle_Id.outMax MOTOR_vars.VsMax_V; // MOTOR_vars.piHandle_Id.outMin -MOTOR_vars.VsFreqHandle.Vdq_gainq15.value[0]; // MOTOR_vars.piHandle_Id.outMax MOTOR_vars.VsFreqHandle.Vdq_gainq15.value[0]; // run the Id controller PI_run_series(MOTOR_vars.piHandle_Id,MOTOR_vars.IdqRef_A.value[0], MOTOR_vars.Idq_in_A.value[0],0,(int32_t*)MOTOR_vars.Vdq_out_V.value[0]); // calculate Iq controller limits int32_t outMax_V MCM_Sqrt(MOTOR_vars.VsMax_V * MOTOR_vars.VsMax_V-\ MOTOR_vars.Vdq_out_V.value[0] * MOTOR_vars.Vdq_out_V.value[0]); MOTOR_vars.piHandle_Iq.outMin -outMax_V; MOTOR_vars.piHandle_Iq.outMax outMax_V; // MOTOR_vars.piHandle_Iq.outMin -MOTOR_vars.VsFreqHandle.Vdq_gainq15.value[1]; // MOTOR_vars.piHandle_Iq.outMax MOTOR_vars.VsFreqHandle.Vdq_gainq15.value[1]; // run the Iq controller PI_run_series(MOTOR_vars.piHandle_Iq,MOTOR_vars.IdqRef_A.value[1], MOTOR_vars.Idq_in_A.value[1],0,(int32_t*)MOTOR_vars.Vdq_out_V.value[1]); MOTOR_vars.Vdq_out_V.value[0] (MOTOR_vars.Vdq_out_V.value[0]*AdcData.VdcBus_V)15; MOTOR_vars.Vdq_out_V.value[1] (MOTOR_vars.Vdq_out_V.value[1]*AdcData.VdcBus_V)15; // // V/f Profile open-loop in build level 2 // VS_FREQ_run(MOTOR_vars.speed_int_Hz); // MOTOR_vars.Vdq_out_V.value[0] MOTOR_vars.VsFreqHandle.Vdq_out.value[0]; // MOTOR_vars.Vdq_out_V.value[1] MOTOR_vars.VsFreqHandle.Vdq_out.value[1]; // run the inverse Park module IPARK_run(MOTOR_vars.Vdq_out_V, MOTOR_vars.Vab_out_V,MOTOR_vars.hElAngle); SVGEN_run(MOTOR_vars.Vab_out_V,PwmData.Vabc_pu); // output 50% // PwmData.Vabc_pu.value[0] 0; // PwmData.Vabc_pu.value[1] 0; // PwmData.Vabc_pu.value[2] 0; HAL_writePWMData(PwmData); }//end of if(MOTOR_vars.offset_complete 0) //---------------------------------------------------------------------- //Data_scope(MOTOR_vars.hElAngle,PwmData.cmpValue[0],PwmData.cmpValue[1],PwmData.cmpValue[2]); //Data_scope(MOTOR_vars.hElAngle,AdcData.I_A.value[0],AdcData.I_A.value[1],AdcData.I_A.value[2]); Data_scope(MOTOR_vars.Iab_A.value[0],MOTOR_vars.Iab_A.value[1],MOTOR_vars.Idq_in_A.value[1],MOTOR_vars.Idq_in_A.value[0]); }除去矫正的电流目标值MOTOR_vars.Idq_set_A.value[0] 0; MOTOR_vars.Idq_set_A.value[1] 20;函数定义else // 电流偏移校准已完成进入闭环控制模式I/f 电流闭环 { // 读取 ADC 三相电流采样值减去零漂偏移后乘以满量程系数右移 15 位得到实际电流 Q15 值 AdcData.I_A.value[0] ((ADCDataReg[0] - AdcData.offset_I_ad.value[0]) * USER_M1_ADC_FULL_SCALE_CURRENT_A) 15; AdcData.I_A.value[1] ((ADCDataReg[1] - AdcData.offset_I_ad.value[1]) * USER_M1_ADC_FULL_SCALE_CURRENT_A) 15; AdcData.I_A.value[2] ((ADCDataReg[2] - AdcData.offset_I_ad.value[2]) * USER_M1_ADC_FULL_SCALE_CURRENT_A) 15; // 运行角度发生器输出当前开环电角度用于定向 ANGLE_GEN_run(MOTOR_vars.speed_int_Hz); // 输入速度参考值(Hz) MOTOR_vars.angleGen_rad MOTOR_vars.angle_rad; // 获取生成的角度值 // Clarke 变换三相电流 - 两相静止坐标系 (Iα, Iβ) CLARKE_run(AdcData.I_A, MOTOR_vars.Iab_A); // 速度轨迹计数器用于降频更新速度参考此处 1 即每个中断周期均更新 MOTOR_vars.counterTrajSpeed; if(MOTOR_vars.counterTrajSpeed 1) { MOTOR_vars.counterTrajSpeed 0; // 设置目标速度带方向然后运行速度轨迹斜坡生成器 MOTOR_vars.trajHandle_spd.targetValue MOTOR_vars.speedForce_Hz * MOTOR_vars.direction; TRAJ_run(MOTOR_vars.trajHandle_spd.targetValue); } // 从轨迹生成器获取当前速度参考值Q15右移15位转换为 Hz MOTOR_vars.speed_int_Hz MOTOR_vars.trajHandle_spd.intValueq15 15; // 计算直流母线电压的倒数Q15 格式用于前馈或调制比计算 MOTOR_vars.oneOverDcBus_invq15 32767 / AdcData.VdcBus_V; // 设置当前电角度为角度发生器的输出开环定向 MOTOR_vars.hElAngle MOTOR_vars.angleGen_rad; // MOTOR_vars.hElAngle 100; // 可手动加相位偏移 // Park 变换静止坐标系电流 (Iα, Iβ) - 旋转坐标系电流 (Id, Iq) PARK_run(MOTOR_vars.Iab_A, MOTOR_vars.Idq_in_A, MOTOR_vars.hElAngle); // ---------- I/f 电流闭环控制 ---------- // 设置 d、q 轴电流参考值来自预设或上位机给定 MOTOR_vars.IdqRef_A.value[0] MOTOR_vars.Idq_set_A.value[0]; MOTOR_vars.IdqRef_A.value[1] MOTOR_vars.Idq_set_A.value[1]; // 计算电压矢量最大幅值限制 MOTOR_vars.VsMax_V MOTOR_vars.maxVsMag_pu; // 最大电压标幺值Q15 // 设置 d 轴 PI 控制器输出限幅为 ±VsMax_V MOTOR_vars.piHandle_Id.outMin -MOTOR_vars.VsMax_V; MOTOR_vars.piHandle_Id.outMax MOTOR_vars.VsMax_V; // 运行 d 轴 PI 控制器输出 d 轴电压 Vd PI_run_series(MOTOR_vars.piHandle_Id, MOTOR_vars.IdqRef_A.value[0], MOTOR_vars.Idq_in_A.value[0], 0, (int32_t*)MOTOR_vars.Vdq_out_V.value[0]); // 根据总电压限制和 d 轴电压计算 q 轴电压的最大允许值 (√(VsMax² - Vd²)) int32_t outMax_V MCM_Sqrt(MOTOR_vars.VsMax_V * MOTOR_vars.VsMax_V - MOTOR_vars.Vdq_out_V.value[0] * MOTOR_vars.Vdq_out_V.value[0]); // 设置 q 轴 PI 控制器的输出限幅 MOTOR_vars.piHandle_Iq.outMin -outMax_V; MOTOR_vars.piHandle_Iq.outMax outMax_V; // 运行 q 轴 PI 控制器输出 q 轴电压 Vq PI_run_series(MOTOR_vars.piHandle_Iq, MOTOR_vars.IdqRef_A.value[1], MOTOR_vars.Idq_in_A.value[1], 0, (int32_t*)MOTOR_vars.Vdq_out_V.value[1]); // 将 dq 电压标幺值乘以母线电压转换为实际电压值的 Q15 表示用于 PWM 调制 MOTOR_vars.Vdq_out_V.value[0] (MOTOR_vars.Vdq_out_V.value[0] * AdcData.VdcBus_V) 15; MOTOR_vars.Vdq_out_V.value[1] (MOTOR_vars.Vdq_out_V.value[1] * AdcData.VdcBus_V) 15; // 逆 Park 变换旋转坐标系电压 - 静止坐标系电压 (Vα, Vβ) IPARK_run(MOTOR_vars.Vdq_out_V, MOTOR_vars.Vab_out_V, MOTOR_vars.hElAngle); // SVPWM 生成静止坐标系电压 - 三相 PWM 占空比 (标幺值) SVGEN_run(MOTOR_vars.Vab_out_V, PwmData.Vabc_pu); // 将占空比写入定时器比较寄存器更新 PWM 输出 HAL_writePWMData(PwmData); } // end of if(MOTOR_vars.offset_complete 0)