1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
#include "FOC.h" float max_power_supply_voltage = 12; // 供电电压 float limit_voltage = 5; // 供电电压 uint8_t pole_pairs = 7; // 极对数 void FOC_Init() { Timer2_PWM_Init(); Timer2_PWM_SetFreq(70); RTC_Time_Init(); OLED_Init(); } /** * @param uD 施加在D轴的电压 范围 [-max,+max] * @param uQ 施加在Q轴的电压 范围 [-max,+max] * @param angle 机械角度 单位:弧度制 因为标准库中的sin函数也是弧度制 */ void FOC_ControlUpdate( float uD, float uQ, float angle) { // 限制电压范围 uD = fixedRange(-max_power_supply_voltage, uD, max_power_supply_voltage); uQ = fixedRange(-max_power_supply_voltage, uQ, max_power_supply_voltage); // 通过机械角度计算电角度 angle = normalizeAngle(electricalAngle(angle)); // 帕克变换 float uAlpha = uD * cos (angle) - uQ * sin (angle); float uBata = uQ * cos (angle) + uD * sin (angle); // 克拉克逆变换(等幅值) float uA = uAlpha; float uB = ( sqrt (3) * uBata - uAlpha) / 2; float uC = (-uAlpha - sqrt (3) * uBata) / 2; // 设置相电压 FOC_setPhaseVoltage(uA, uB, uC); } /** * @param uA 施加在A相的电压 范围 [-max,+max] * @param uB 施加在B相的电压 范围 [-max,+max] * @param uC 施加在C相的电压 范围 [-max,+max] */ void FOC_setPhaseVoltage( float uA, float uB, float uC) { // 限制电压范围 uA = fixedRange(-limit_voltage, uA, limit_voltage); uB = fixedRange(-limit_voltage, uB, limit_voltage); uC = fixedRange(-limit_voltage, uC, limit_voltage); Timer2_PWM_SetDuty( // 重映射 [-max,+max] => [0,1] uA / 2 / max_power_supply_voltage + 0.5, uB / 2 / max_power_supply_voltage + 0.5, uC / 2 / max_power_supply_voltage + 0.5); } /** * 速度开环控制 * @param targetSpeed 目标速度 */ void FOC_SpeedOpenLoopControl( float targetSpeed) { float angle = 0; float dt_s; uint64_t prevTime_ms, curTime_ms; curTime_ms = prevTime_ms = RTC_Time_GetTime_MS(NULL); while (1) { curTime_ms = RTC_Time_GetTime_MS(NULL); dt_s = (curTime_ms - prevTime_ms) / 1000.0; angle += targetSpeed * dt_s; angle = normalizeAngle(angle); FOC_ControlUpdate(0, limit_voltage, angle); prevTime_ms = curTime_ms; } } /** * 范围限制 */ float fixedRange( float min, float val, float max) { return val <= min ? min : (val >= max ? max : val); } /** * 将角度限制在[0,2π] */ float normalizeAngle( float angle) { angle = fmod (angle, 2 * M_PI); if (angle < 0) angle += 2 * M_PI; return angle; } /** * 电角度=机械角度 x 极对数 */ float electricalAngle( float mechanical_angle) { return mechanical_angle * pole_pairs; } float rad( float deg) { return deg / 180 * M_PI; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
#ifndef __FOC_H__ #define __FOC_H__ #include "stm32f10x.h" #include "Timer2_PWM.h" #include "RTC_Time.h" #include "Delay.h" #include "OLED.h" #include "OLED_Printf.h" #include <math.h> #ifdef __cplusplus extern "C" { #endif void FOC_Init(); void FOC_ControlUpdate( float uD, float uQ, float angle); void FOC_setPhaseVoltage( float uA, float uB, float uC); void FOC_SpeedOpenLoopControl( float targetSpeed); float fixedRange( float min, float val, float max); float normalizeAngle( float angle); float electricalAngle( float mechanical_angle); float rad( float deg); #ifdef __cplusplus } #endif #endif |