- 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;
}
}
- throttle_max_at_low_rpm 400(2000)
- 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
- 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;
}
- desync_check 每6step置1
- filter_level 判断过零的次数
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();
}
语法说明
标题
文本样式
列表
图片
链接
目录
代码片
表格
注脚
注释
自定义列表
LaTeX 数学公式
插入甘特图
插入UML图
插入Mermaid流程图
插入Flowchart流程图
插入类图
快捷键
标题复制
# 一级标题
## 二级标题
### 三级标题
#### 四级标题
##### 五级标题
###### 六级标题
AM32 电调学习–main()零、相关参数一、初始化1. 初始化外设2.设置参数获取3. 旋转方向设置4. 盲启动时pwm占空比设置5. 播放启动音乐6. 开始接收dshot或pwm二、主循环1. 转速计算及pwm周期动态调整2. 输入信号超时判断3. 1s钟dshot传输telemetry4. 反向电动势超时计数基准设置5. 同步检查6. Telemetry组包7.电流。电压,温度采样及低电压关机处理8.处理低转速油门9. 处理过温处理11. 盲启时过零点判断及处理12. 停机检测
Markdown 7559 字数 360 行数 当前行 39, 当前列 0 文章已保存11:25:50
HTML 7304 字数 308 段落