TMS320F28335: 关于lead angle问题

Part Number: TMS320F28335
Other Parts Discussed in Thread: CONTROLSUITE

Dear TI support:

     我在观看提视频教学《TI 高精度 实验室电机驱动器》中提到超前角(lead angle): 

我们驱动电机, 监测电机任一 相位的相电流和霍尔信号。

调节超前角,使相电流 与霍尔信号对齐。

在该超前角下, 电机将产生最大扭矩, 并且以最高效率运行。

我现在的疑问是霍尔信号通过中断检测到,通过软件虚拟一个霍尔换相,换相点是只能延迟。怎么会提前呢?

如何通过软件代码编写来调整lead angle这个问题?

在C:\ti\controlSUITE\development_kits\HVMotorCtrl+PfcKit_v2.1文件夹下的《HVBLDC_Sensored》例程中是否能能实现?如果不能,能否有个参考C代码的例程,谢谢!

以下是波形图片:紫色为相电流波形,是没有调整超前角。

.

  • 您好,

    已经收到了您的案例,调查需要些时间,感谢您的耐心等待。

  • 谢谢。我已知悉,用已知的这一个的霍尔信号去预测下一个霍尔信号的换相点。

    相当于模拟一个换相霍尔信号。

    原理我已清楚,目前在想实施代码方案。

  • 与延迟相比,提前HALL状态变化有一些风险,比如在两步之间电机减速。
    您可以尝试在HVBLDC_Sensored项目中更改以下功能。DebounceCount增加了一些延迟,就像你提到的,但你可以添加一些新代码来推进状态更改。
    您需要跟踪当前/实际的HALL状态,并且可以在HALL GPIO状态更改后使用另一个变量开始计数。当达到某个高级计数值时,您可以强制代码中的HALL状态更改。

    /*----------------------------------------------------------------------------------------------
    HALL3_READ Macro Definition
    ----------------------------------------------------------------------------------------------*/

    #define HALL3_READ_MACRO(v) \
    v.CmtnTrigHall = 0; /* Reset trigger, it only handshakes with calling program.*/ \
    if (v.EdgeDebounced==0) /* Debounce current position. */ \
    { \
    HALL3_DEBOUNCE_MACRO(v) \
    v.CmtnTrigHall = v.EdgeDebounced; /* Set Commutation trigger here*/ \
    } \
    else /* If current position is debounced, find match in table */ \
    HALL3_NEXT_STATE_MACRO(v) /* and return pointer to current state. Ptr to be incremented*/ \
    /* by MOD6CNT after RET.*/ \
    \
    v.EdgeDebounced = 0; /* Reset trigger*/

  • 我使用了AI,得到了以下建议。它实际上有一些好主意,但它是人工智能生成的,所以不会完美。
    为了在基于霍尔的无刷直流电机控制中实现电机角度提前(相位提前),有几种方法:

    1.Time-Based Advancement Method:
    
    typedef struct {
        uint8_t current_hall;
        uint32_t last_hall_time;
        float advance_angle;  // in degrees
        float motor_speed;    // in RPM
    } MotorState_t;
    
    uint8_t getAdvancedCommutation(MotorState_t* motor) {
        uint8_t hall_state = readHallState();
        uint32_t current_time = HAL_GetTick();
        
        // Calculate speed
        float time_diff = (current_time - motor->last_hall_time) / 1000.0f; // in seconds
        motor->motor_speed = (60.0f / 6.0f) / time_diff; // RPM (assuming 6 steps per revolution)
        
        // Calculate time to advance
        float advance_time = (motor->advance_angle / 360.0f) * (1.0f / (motor->motor_speed / 60.0f));
        
        // Predict next state based on current speed and desired advance
        uint8_t predicted_step = HALL_TO_STEP[hall_state];
        predicted_step = (predicted_step + 1) % 6;
        
        motor->last_hall_time = current_time;
        return predicted_step;
    }
    
    
    2.Look-up Table Based Advancement:
    
    // Advanced commutation tables for different advance angles
    const uint8_t BLDC_STEPS_0_DEG[] =   {0b101, 0b001, 0b011, 0b010, 0b110, 0b100};
    const uint8_t BLDC_STEPS_15_DEG[] =  {0b001, 0b011, 0b010, 0b110, 0b100, 0b101};
    const uint8_t BLDC_STEPS_30_DEG[] =  {0b011, 0b010, 0b110, 0b100, 0b101, 0b001};
    
    uint8_t getPhaseAdvancedPattern(uint8_t hall_state, float speed) {
        uint8_t base_step = HALL_TO_STEP[hall_state];
        
        // Select advance based on speed
        if(speed < 1000) {
            return BLDC_STEPS_0_DEG[base_step];
        } else if(speed < 2000) {
            return BLDC_STEPS_15_DEG[base_step];
        } else {
            return BLDC_STEPS_30_DEG[base_step];
        }
    }
    
    3. Dynamic Calculation Method:
    typedef struct {
        float electrical_angle;    // 0-360 degrees
        float advance_angle;       // advance angle in degrees
        float speed;              // current speed
    } AdvanceState_t;
    
    void calculateAdvancedAngle(AdvanceState_t* state) {
        // Base electrical angle from Hall sensors (60° segments)
        uint8_t hall_state = readHallState();
        float base_angle = HALL_TO_ANGLE[hall_state];
        
        // Calculate dynamic advance based on speed
        float speed_factor = state->speed / RATED_SPEED;
        float dynamic_advance = state->advance_angle * speed_factor;
        
        // Calculate final electrical angle
        state->electrical_angle = base_angle + dynamic_advance;
        if(state->electrical_angle >= 360.0f) {
            state->electrical_angle -= 360.0f;
        }
    }
    
    void applyAdvancedCommutation(AdvanceState_t* state) {
        // Convert electrical angle to PWM values
        float angle_rad = state->electrical_angle * (PI / 180.0f);
        
        // Generate sinusoidal PWM patterns
        uint16_t pwm_a = (uint16_t)(sinf(angle_rad) * PWM_PERIOD);
        uint16_t pwm_b = (uint16_t)(sinf(angle_rad - (2.0f * PI / 3.0f)) * PWM_PERIOD);
        uint16_t pwm_c = (uint16_t)(sinf(angle_rad + (2.0f * PI / 3.0f)) * PWM_PERIOD);
        
        // Apply PWM values
        updatePhasePWM(pwm_a, pwm_b, pwm_c);
    }
    
    
    4.Integrated Implementation:
    typedef struct {
        float advance_angle;
        float speed;
        uint8_t current_step;
        uint32_t last_update;
        AdvanceMode_t mode;
    } MotorControl_t;
    
    void updateMotorAdvance(MotorControl_t* motor) {
        uint8_t hall_state = readHallState();
        uint32_t current_time = HAL_GetTick();
        
        // Update speed
        updateSpeed(motor, current_time);
        
        // Calculate advance based on mode
        switch(motor->mode) {
            case ADVANCE_MODE_FIXED:
                // Fixed advance angle
                motor->current_step = getFixedAdvance(hall_state, motor->advance_angle);
                break;
                
            case ADVANCE_MODE_DYNAMIC:
                // Dynamic advance based on speed
                motor->current_step = getDynamicAdvance(hall_state, motor->speed);
                break;
                
            case ADVANCE_MODE_OPTIMAL:
                // Optimal advance calculation
                motor->current_step = getOptimalAdvance(hall_state, motor->speed, motor->load);
                break;
        }
        
        // Apply commutation
        applyCommutation(motor->current_step);
        motor->last_update = current_time;
    }
    
    // Helper function for optimal advance calculation
    float calculateOptimalAdvance(float speed, float load) {
        // Example of a simple optimal advance calculation
        float base_advance = 15.0f; // base advance angle
        float speed_factor = speed / RATED_SPEED;
        float load_factor = load / RATED_LOAD;
        
        return base_advance * speed_factor * (1.0f + 0.2f * load_factor);
    }
    
    
    Important considerations:
    
    1.Speed Limitations:
    Phase advance becomes more important at higher speeds
    Need to handle mechanical limitations
    Consider maximum safe operating speed
    
    2.Dynamic Response:
    
    // Smooth advance angle changes
    void smoothAdvanceTransition(MotorControl_t* motor, float target_advance) {
        float delta = target_advance - motor->advance_angle;
        float max_change = MAX_ADVANCE_CHANGE_PER_UPDATE;
        
        if(fabs(delta) > max_change) {
            delta = (delta > 0) ? max_change : -max_change;
        }
        
        motor->advance_angle += delta;
    }
    
    3.Protection:
    bool isAdvanceSafe(float advance_angle, float speed) {
        if(speed > MAX_SAFE_SPEED) return false;
        if(advance_angle > MAX_SAFE_ADVANCE) return false;
        return true;
    }
    
    Remember:
    
    Start with small advance angles
    Test thoroughly at each speed range
    Monitor motor temperature
    Consider efficiency vs. performance tradeoffs
    Implement proper error handling
    Use appropriate filtering for speed measurement
    Consider system dynamics and response time
    The optimal implementation depends on your specific requirements for:
    
    Speed range
    Efficiency requirements
    Dynamic response needs
    Processing capabilities
    Sensor resolution and accuracy