【AM32 电调学习–main()】

AM32 电调学习–main()

零、相关参数

  1. startup_max_duty_cycle 启动阶段最大占空比
          if (input >= 47 && (zero_crosses < (20 >> stall_protection))) {
                if (duty_cycle_setpoint < min_startup_duty) {
                    duty_cycle_setpoint = min_startup_duty;
                }
                if (duty_cycle_setpoint > startup_max_duty_cycle) {
                    duty_cycle_setpoint = startup_max_duty_cycle;
                }
            }
  1. throttle_max_at_low_rpm 400(2000)
  2. throttle_max_at_high_rpm
    throttle_max_at_low_rpm = throttle_max_at_low_rpm * TIMER1_MAX_ARR / 2000; // adjust to new pwm frequency
    throttle_max_at_high_rpm = TIMER1_MAX_ARR; // adjust to new pwm frequency
  1. char RC_CAR_REVERSE = 0; // have to set bidirectional, comp_pwm off and stall
    // protection off, no sinusoidal startup
 if (RC_CAR_REVERSE) { // overrides a whole lot of things!
        throttle_max_at_low_rpm = 1000;
        bi_direction = 1;
        use_sin_start = 0;
        low_rpm_throttle_limit = 1;
        VARIABLE_PWM = 0;
        // stall_protection = 1;
        comp_pwm = 0;
        stuck_rotor_protection = 0;
        minimum_duty_cycle = minimum_duty_cycle + 50;
        stall_protect_minimum_duty = stall_protect_minimum_duty + 50;
        min_startup_duty = min_startup_duty + 50;
    } 
  1. desync_check 每6step置1
  2. filter_level 判断过零的次数

一、初始化

1. 初始化外设

    initAfterJump();

    initCorePeripherals();

    enableCorePeripherals();

2.设置参数获取

    loadEEpromSettings();

    EEPROM_VERSION = *(uint8_t*)(0x08000FFC);
#ifdef USE_MAKE
    if (firmware_info.version_major != eepromBuffer[3] || firmware_info.version_minor != eepromBuffer[4]) {
        eepromBuffer[3] = firmware_info.version_major;
        eepromBuffer[4] = firmware_info.version_minor;
        for (int i = 0; i < 12; i++) {
            eepromBuffer[5 + i] = firmware_info.device_name[i];
        }
        saveEEpromSettings();
    }
#else
    if (VERSION_MAJOR != eepromBuffer[3] || VERSION_MINOR != eepromBuffer[4]) {
        eepromBuffer[3] = VERSION_MAJOR;
        eepromBuffer[4] = VERSION_MINOR;
        for (int i = 0; i < 12; i++) {
            eepromBuffer[5 + i] = (uint8_t)FIRMWARE_NAME[i];
        }
        saveEEpromSettings();
    }
#endif

3. 旋转方向设置

    if (dir_reversed == 1) {
        forward = 0;
    } else {
        forward = 1;
    }

4. 盲启动时pwm占空比设置

占空比100%时为2000,其真正的占空比TIMER1_MAX_ARR
startup_max_duty_cycle 300(200) 转化为pwm真正的值

    tim1_arr = TIMER1_MAX_ARR;
    startup_max_duty_cycle = startup_max_duty_cycle * TIMER1_MAX_ARR / 2000 + dead_time_override; // adjust for pwm frequency
    throttle_max_at_low_rpm = throttle_max_at_low_rpm * TIMER1_MAX_ARR / 2000; // adjust to new pwm frequency
    throttle_max_at_high_rpm = TIMER1_MAX_ARR; // adjust to new pwm frequency

5. 播放启动音乐

6. 开始接收dshot或pwm

二、主循环

1. 转速计算及pwm周期动态调整

        e_com_time = ((commutation_intervals[0] + commutation_intervals[1] + commutation_intervals[2] + commutation_intervals[3] + commutation_intervals[4] + commutation_intervals[5]) + 4) >> 1; // COMMUTATION INTERVAL IS 0.5US INCREMENTS
        if (VARIABLE_PWM) {
            tim1_arr = map(commutation_interval, 96, 200, TIMER1_MAX_ARR / 2,
                TIMER1_MAX_ARR);
            //      	pwm_frequency_conversion_factor = (tim1_arr << 10) /
            //      TIMER1_MAX_ARR; // multply by 1024
        }

2. 输入信号超时判断

        if (signaltimeout > (LOOP_FREQUENCY_HZ >> 1)) { // half second timeout when armed;
            if (armed) {
                allOff();
                armed = 0;
                input = 0;
                inputSet = 0;
                zero_input_count = 0;
                SET_DUTY_CYCLE_ALL(0);
                resetInputCaptureTimer();
                for (int i = 0; i < 64; i++) {
                    dma_buffer[i] = 0;
                }
                NVIC_SystemReset();
            }
            if (signaltimeout > LOOP_FREQUENCY_HZ << 1) { // 2 second when not armed
                allOff();
                armed = 0;
                input = 0;
                inputSet = 0;
                zero_input_count = 0;
                SET_DUTY_CYCLE_ALL(0);
                resetInputCaptureTimer();
                for (int i = 0; i < 64; i++) {
                    dma_buffer[i] = 0;
                }
                NVIC_SystemReset();
            }
        }

3. 1s钟dshot传输telemetry

            consumed_current = (float)actual_current / 360 + consumed_current;
            switch (dshot_extended_telemetry) {

            case 1:
                send_extended_dshot = 0b0010 << 8 | degrees_celsius;
                dshot_extended_telemetry = 2;
                break;
            case 2:
                send_extended_dshot = 0b0110 << 8 | (uint8_t)actual_current / 50;
                dshot_extended_telemetry = 3;
                break;
            case 3:
                send_extended_dshot = 0b0100 << 8 | (uint8_t)(battery_voltage / 25);
                dshot_extended_telemetry = 1;
                break;
            }
            tenkhzcounter = 0;
        }

4. 反向电动势超时计数基准设置

        if ((zero_crosses > 1000) || (adjusted_input == 0)) {
            bemf_timeout_happened = 0;
        }
        if (zero_crosses > 100 && adjusted_input < 200) {
            bemf_timeout_happened = 0;
        }
        if (use_sin_start && adjusted_input < 160) {
            bemf_timeout_happened = 0;
        }

        if (crawler_mode) {
            if (adjusted_input < 400) {
                bemf_timeout_happened = 0;
            }
        } else {
            if (adjusted_input < 150) { // startup duty cycle should be low enough to not burn motor
                bemf_timeout = 100;
            } else {
                bemf_timeout = 10;
            }
        }

5. 同步检查

        average_interval = e_com_time / 3;
        if (desync_check && zero_crosses > 10) {
            if ((getAbsDif(last_average_interval, average_interval) > average_interval >> 1) && (average_interval < 2000)) { // throttle resitricted before zc 20.
                zero_crosses = 0;
                desync_happened++;
                if ((!bi_direction && (input > 47)) || commutation_interval > 1000) {
                    running = 0;
                }
                old_routine = 1;
                if (zero_crosses > 100) {
                    average_interval = 5000;
                }
                last_duty_cycle = min_startup_duty / 2;
            }
            desync_check = 0;
            //	}
            last_average_interval = average_interval;
        }

6. Telemetry组包

        if (send_telemetry) {
#ifdef USE_SERIAL_TELEMETRY
            makeTelemPackage(degrees_celsius, battery_voltage, actual_current,
                (uint16_t)consumed_current, e_rpm);
            send_telem_DMA();
            send_telemetry = 0;
#endif
        }

7.电流。电压,温度采样及低电压关机处理

        adc_counter++;
        if (adc_counter > 200) { // for adc and telemetry
#if defined(MCU_F051) || defined(MCU_G071) || defined(MCU_F031)
            ADC_DMA_Callback();
            ADC_CCR = TIM1->CCR3 * 2 / 3 + 1; // sample current at quarter pwm on
            if (ADC_CCR > tim1_arr) {
                ADC_CCR = tim1_arr;
            }
            TIM1->CCR4 = ADC_CCR;

            LL_ADC_REG_StartConversion(ADC1);
            converted_degrees = __LL_ADC_CALC_TEMPERATURE(3300, ADC_raw_temp, LL_ADC_RESOLUTION_12B);
#endif
#ifdef MCU_GDE23
            ADC_DMA_Callback();
            converted_degrees = (1.43 - ADC_raw_temp * 3.3 / 4096) * 1000 / 4.3 + 25;
            adc_software_trigger_enable(ADC_REGULAR_CHANNEL);
#endif
#ifdef ARTERY
            ADC_DMA_Callback();
            adc_ordinary_software_trigger_enable(ADC1, TRUE);
            //  converted_degrees = (4000 - ADC_raw_temp) / 20;
            converted_degrees = getConvertedDegrees(ADC_raw_temp);
#endif
            degrees_celsius = converted_degrees;
            battery_voltage = ((7 * battery_voltage) + ((ADC_raw_volts * 3300 / 4095 * VOLTAGE_DIVIDER) / 100)) >> 3;
            smoothed_raw_current = getSmoothedCurrent();
            //        smoothed_raw_current = ((63*smoothed_raw_current +
            //        (ADC_raw_current) )>>6);
            actual_current = ((smoothed_raw_current * 3300 / 41) - (CURRENT_OFFSET * 100)) / (MILLIVOLT_PER_AMP);
            if (actual_current < 0) {
                actual_current = 0;
            }
            if (LOW_VOLTAGE_CUTOFF) {
                if (battery_voltage < (cell_count * low_cell_volt_cutoff)) {
                    low_voltage_count++;
                    if (low_voltage_count > (20000 - (stepper_sine * 900))) {
                        input = 0;
                        allOff();
                        maskPhaseInterrupts();
                        running = 0;
                        zero_input_count = 0;
                        armed = 0;
                    }
                } else {
                    low_voltage_count = 0;
                }
            }
            adc_counter = 0;
#ifdef USE_ADC_INPUT
            if (ADC_raw_input < 10) {
                zero_input_count++;
            } else {
                zero_input_count = 0;
            }
#endif
        }

8.处理低转速油门

stepper_sine == 0 8-12

            e_rpm = running * (600000 / e_com_time); // in tens of rpm
            k_erpm = e_rpm / 10; // ecom time is time for one electrical revolution in microseconds

            if (low_rpm_throttle_limit) { // some hardware doesn't need this, its on
                                          // by default to keep hardware / motors
                                          // protected but can slow down the response
                                          // in the very low end a little.
                duty_cycle_maximum = map(k_erpm, low_rpm_level, high_rpm_level, throttle_max_at_low_rpm,
                    throttle_max_at_high_rpm); // for more performance lower the
                                               // high_rpm_level, set to a
                                               // consvervative number in source.
            }

9. 处理过温处理

            if (degrees_celsius > TEMPERATURE_LIMIT) {
                duty_cycle_maximum = map(degrees_celsius, TEMPERATURE_LIMIT - 10, TEMPERATURE_LIMIT + 10,
                    throttle_max_at_high_rpm / 2, 1);
            }
``
### 10.过零点滤波参数设置
```C
            if (zero_crosses < 100 && commutation_interval > 500) {
#ifdef MCU_G071
                TIM1->CCR5 = 500; // comparator blanking
                filter_level = 8;
#else
                filter_level = 12;
#endif
            } else {
#ifdef MCU_G071
                TIM1->CCR5 = 100;
#endif
                filter_level = map(average_interval, 100, 500, 3, 12);
            }
            if (commutation_interval < 100) {
                filter_level = 2;
            }

            if (motor_kv < 500) {

                filter_level = filter_level * 2;
            }

11. 盲启时过零点判断及处理

#ifdef CUSTOM_RAMP
            if (old_routine && running) {
                maskPhaseInterrupts();
                getBemfState();
                if (!zcfound) {
                    if (rising) {
                        if (bemfcounter > min_bemf_counts_up) {
                            zcfound = 1;
                            zcfoundroutine();
                        }
                    } else {
                        if (bemfcounter > min_bemf_counts_down) {
                            zcfound = 1;
                            zcfoundroutine();
                        }
                    }
                }
            }
#endif

12. 停机检测

          if (INTERVAL_TIMER_COUNT > 45000 && running == 1) {
                bemf_timeout_happened++;

                maskPhaseInterrupts();
                old_routine = 1;
                if (input < 48) {
                    running = 0;
                    commutation_interval = 5000;
                }
                zero_crosses = 0;
                zcfoundroutine();
            }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值