AM32开源代码之代码分析 - EEprom
1. 源由
公共代码EEprom
部分研读,主要就是配置参数的保存。
- loadEEpromSettings
- saveEEpromSettings
2. 主要函数
2.1 loadEEpromSettings
eepromBuffer
数组对应的变量列表:
eepromBuffer[1]
:eeprom_layout_version
eepromBuffer[17]
:dir_reversed
eepromBuffer[18]
:bi_direction
eepromBuffer[19]
:use_sin_start
eepromBuffer[20]
:comp_pwm
eepromBuffer[21]
:VARIABLE_PWM
eepromBuffer[22]
:stuck_rotor_protection
eepromBuffer[23]
:advance_level
eepromBuffer[24]
:TIMER1_MAX_ARR
eepromBuffer[25]
:min_startup_duty
,minimum_duty_cycle
,stall_protect_minimum_duty
eepromBuffer[26]
:motor_kv
eepromBuffer[27]
:motor_poles
eepromBuffer[28]
:brake_on_stop
eepromBuffer[29]
:stall_protection
eepromBuffer[30]
:volume
eepromBuffer[31]
:TLM_ON_INTERVAL
eepromBuffer[32]
:servo_low_threshold
eepromBuffer[33]
:servo_high_threshold
eepromBuffer[34]
:servo_neutral
eepromBuffer[35]
:servo_dead_band
eepromBuffer[36]
:LOW_VOLTAGE_CUTOFF
eepromBuffer[37]
:low_cell_volt_cutoff
eepromBuffer[38]
:RC_CAR_REVERSE
eepromBuffer[39]
:auto_advance
,USE_HALL_SENSOR
eepromBuffer[40]
:sine_mode_changeover_thottle_level
eepromBuffer[41]
:drag_brake_strength
eepromBuffer[42]
:driving_brake_strength
,dead_time_override
eepromBuffer[43]
:TEMPERATURE_LIMIT
eepromBuffer[44]
:CURRENT_LIMIT
,use_current_limit
eepromBuffer[45]
:sine_mode_power
eepromBuffer[46]
:dshot
,servoPwm
,EDT_ARMED
,EDT_ARM_ENABLE
void loadEEpromSettings()
{
// 从EEPROM中读取176字节到eepromBuffer
read_flash_bin(eepromBuffer, eeprom_address, 176);
// 根据eepromBuffer第17字节的值设置dir_reversed
if (eepromBuffer[17] == 0x01) {
dir_reversed = 1;
} else {
dir_reversed = 0;
}
// 根据eepromBuffer第18字节的值设置bi_direction
if (eepromBuffer[18] == 0x01) {
bi_direction = 1;
} else {
bi_direction = 0;
}
// 根据eepromBuffer第19字节的值设置use_sin_start
if (eepromBuffer[19] == 0x01) {
use_sin_start = 1;
}
// 根据eepromBuffer第20字节的值设置comp_pwm
if (eepromBuffer[20] == 0x01) {
comp_pwm = 1;
} else {
comp_pwm = 0;
}
// 根据eepromBuffer第21字节的值设置VARIABLE_PWM
if (eepromBuffer[21] == 0x01) {
VARIABLE_PWM = 1;
} else {
VARIABLE_PWM = 0;
}
// 根据eepromBuffer第22字节的值设置stuck_rotor_protection
if (eepromBuffer[22] == 0x01) {
stuck_rotor_protection = 1;
} else {
stuck_rotor_protection = 0;
}
// 根据eepromBuffer第23字节的值设置advance_level
if (eepromBuffer[23] < 4) {
advance_level = eepromBuffer[23];
} else {
advance_level = 2; // 默认值为2
}
// 根据eepromBuffer第24字节的值设置TIMER1_MAX_ARR
if (eepromBuffer[24] < 49 && eepromBuffer[24] > 7) {
if (eepromBuffer[24] < 49 && eepromBuffer[24] > 23) {
TIMER1_MAX_ARR = map(eepromBuffer[24], 24, 48, TIM1_AUTORELOAD, TIM1_AUTORELOAD / 2);
}
if (eepromBuffer[24] < 24 && eepromBuffer[24] > 11) {
TIMER1_MAX_ARR = map(eepromBuffer[24], 12, 24, TIM1_AUTORELOAD * 2, TIM1_AUTORELOAD);
}
if (eepromBuffer[24] < 12 && eepromBuffer[24] > 7) {
TIMER1_MAX_ARR = map(eepromBuffer[24], 7, 16, TIM1_AUTORELOAD * 3, TIM1_AUTORELOAD / 2 * 3);
}
SET_AUTO_RELOAD_PWM(TIMER1_MAX_ARR);
} else {
tim1_arr = TIM1_AUTORELOAD;
SET_AUTO_RELOAD_PWM(tim1_arr);
}
// 根据eepromBuffer第25字节的值设置min_startup_duty, minimum_duty_cycle, 和stall_protect_minimum_duty
if (eepromBuffer[25] < 151 && eepromBuffer[25] > 49) {
min_startup_duty = eepromBuffer[25];
minimum_duty_cycle = eepromBuffer[25] / 3;
stall_protect_minimum_duty = minimum_duty_cycle + 10;
} else {
min_startup_duty = 150;
minimum_duty_cycle = (min_startup_duty / 2) + 10;
}
// 设置motor_kv
motor_kv = (eepromBuffer[26] * 40) + 20;
#ifdef THREE_CELL_MAX
motor_kv = motor_kv / 2;
#endif
// 设置motor_poles
motor_poles = eepromBuffer[27];
// 根据eepromBuffer第28字节的值设置brake_on_stop
if (eepromBuffer[28] == 0x01) {
brake_on_stop = 1;
} else {
brake_on_stop = 0;
}
// 根据eepromBuffer第29字节的值设置stall_protection
if (eepromBuffer[29] == 0x01) {
stall_protection = 1;
} else {
stall_protection = 0;
}
// 设置音量
setVolume(2);
if (eepromBuffer[1] > 0) { // 这些命令在eeprom版本1才引入
#ifdef CUSTOM_RAMP
#else
if (eepromBuffer[30] > 11) {
setVolume(5);
} else {
setVolume(eepromBuffer[30]);
}
#endif
// 根据eepromBuffer第31字节的值设置TLM_ON_INTERVAL
if (eepromBuffer[31] == 0x01) {
TLM_ON_INTERVAL = 1;
} else {
TLM_ON_INTERVAL = 0;
}
// 设置servo_low_threshold和servo_high_threshold
servo_low_threshold = (eepromBuffer[32] * 2) + 750;
servo_high_threshold = (eepromBuffer[33] * 2) + 1750;
servo_neutral = (eepromBuffer[34]) + 1374;
servo_dead_band = eepromBuffer[35];
// 根据eepromBuffer第36字节的值设置LOW_VOLTAGE_CUTOFF
if (eepromBuffer[36] == 0x01) {
LOW_VOLTAGE_CUTOFF = 1;
} else {
LOW_VOLTAGE_CUTOFF = 0;
}
// 设置low_cell_volt_cutoff
low_cell_volt_cutoff = eepromBuffer[37] + 250;
// 根据eepromBuffer第38字节的值设置RC_CAR_REVERSE
if (eepromBuffer[38] == 0x01) {
RC_CAR_REVERSE = 1;
} else {
RC_CAR_REVERSE = 0;
}
// 根据eepromBuffer第39字节的值设置USE_HALL_SENSOR和auto_advance
if (eepromBuffer[39] == 0x01) {
auto_advance = 1;
#ifdef HAS_HALL_SENSORS
USE_HALL_SENSOR = 1;
#else
USE_HALL_SENSOR = 0;
#endif
} else {
USE_HALL_SENSOR = 0;
}
// 设置sine_mode_changeover_thottle_level
if (eepromBuffer[40] > 4 && eepromBuffer[40] < 26) {
sine_mode_changeover_thottle_level = eepromBuffer[40];
}
// 设置drag_brake_strength
if (eepromBuffer[41] > 0 && eepromBuffer[41] < 11) {
drag_brake_strength = eepromBuffer[41];
}
// 设置driving_brake_strength和dead_time_override
if (eepromBuffer[42] > 0 && eepromBuffer[42] < 10) {
driving_brake_strength = eepromBuffer[42];
dead_time_override = DEAD_TIME + (150 - (driving_brake_strength * 10));
if (dead_time_override > 200) {
dead_time_override = 200;
}
min_startup_duty = eepromBuffer[25] + dead_time_override;
minimum_duty_cycle = eepromBuffer[25] / 2 + dead_time_override;
throttle_max_at_low_rpm = throttle_max_at_low_rpm + dead_time_override;
startup_max_duty_cycle = startup_max_duty_cycle + dead_time_override;
#ifdef STMICRO
TIM1->BDTR |= dead_time_override;
#endif
#ifdef ARTERY
TMR1->brk |= dead_time_override;
#endif
#ifdef GIGADEVICES
TIMER_CCHP(TIMER0) |= dead_time_override;
#endif
}
// 设置TEMPERATURE_LIMIT
if (eepromBuffer[43] >= 70 && eepromBuffer[43] <= 140) {
TEMPERATURE_LIMIT = eepromBuffer[43];
}
// 设置CURRENT_LIMIT和use_current_limit
if (eepromBuffer[44] > 0 && eepromBuffer[44] < 100) {
CURRENT_LIMIT = eepromBuffer[44] * 2;
use_current_limit = 1;
}
// 设置sine_mode_power
if (eepromBuffer[45] > 0 && eepromBuffer[45] < 11) {
sine_mode_power = eepromBuffer[45];
}
// 根据eepromBuffer第46字节的值设置dshot, servoPwm, 和EDT_ARMED
if (eepromBuffer[46] >= 0 && eepromBuffer[46] < 10) {
switch (eepromBuffer[46]) {
case AUTO_IN:
dshot = 0;
servoPwm = 0;
EDT_ARMED = 1;
break;
case DSHOT_IN:
dshot = 1;
EDT_ARMED = 1;
break;
case SERVO_IN:
servoPwm = 1;
break;
case SERIAL_IN:
break;
case EDTARM:
EDT_ARM_ENABLE = 1;
EDT_ARMED = 0;
dshot = 1;
break;
}
} else {
dshot = 0;
servoPwm = 0;
EDT_ARMED = 1;
}
// 设置low_rpm_throttle_limit和low_rpm_level
if (motor_kv < 300) {
low_rpm_throttle_limit = 0;
}
low_rpm_level = motor_kv / 100 / (32 / motor_poles);
// 设置high_rpm_level
high_rpm_level = motor_kv / 12 / (32 / motor_poles);
}
// 设置reverse_speed_threshold
reverse_speed_threshold = map(motor_kv, 300, 3000, 1000, 500);
}
2.2 saveEEpromSettings
eepromBuffer
数组索引及其对应的变量整理列表:
eepromBuffer[1]
:eeprom_layout_version
eepromBuffer[17]
:dir_reversed
(值为0x01
表示启用,0x00
表示禁用)eepromBuffer[18]
:bi_direction
(值为0x01
表示启用,0x00
表示禁用)eepromBuffer[19]
:use_sin_start
(值为0x01
表示启用,0x00
表示禁用)eepromBuffer[20]
:comp_pwm
(值为0x01
表示启用,0x00
表示禁用)eepromBuffer[21]
:VARIABLE_PWM
(值为0x01
表示启用,0x00
表示禁用)eepromBuffer[22]
:stuck_rotor_protection
(值为0x01
表示启用,0x00
表示禁用)eepromBuffer[23]
:advance_level
void saveEEpromSettings()
{
// 将当前EEPROM布局版本保存到eepromBuffer的第1字节
eepromBuffer[1] = eeprom_layout_version;
// 根据dir_reversed的值设置eepromBuffer的第17字节
if (dir_reversed == 1) {
eepromBuffer[17] = 0x01;
} else {
eepromBuffer[17] = 0x00;
}
// 根据bi_direction的值设置eepromBuffer的第18字节
if (bi_direction == 1) {
eepromBuffer[18] = 0x01;
} else {
eepromBuffer[18] = 0x00;
}
// 根据use_sin_start的值设置eepromBuffer的第19字节
if (use_sin_start == 1) {
eepromBuffer[19] = 0x01;
} else {
eepromBuffer[19] = 0x00;
}
// 根据comp_pwm的值设置eepromBuffer的第20字节
if (comp_pwm == 1) {
eepromBuffer[20] = 0x01;
} else {
eepromBuffer[20] = 0x00;
}
// 根据VARIABLE_PWM的值设置eepromBuffer的第21字节
if (VARIABLE_PWM == 1) {
eepromBuffer[21] = 0x01;
} else {
eepromBuffer[21] = 0x00;
}
// 根据stuck_rotor_protection的值设置eepromBuffer的第22字节
if (stuck_rotor_protection == 1) {
eepromBuffer[22] = 0x01;
} else {
eepromBuffer[22] = 0x00;
}
// 将advance_level保存到eepromBuffer的第23字节
eepromBuffer[23] = advance_level;
// 将eepromBuffer保存到EEPROM中
save_flash_nolib(eepromBuffer, 176, eeprom_address);
}
3. 总结
- 当前参数表共176个字符
uint8_t eepromBuffer[176] = { 0 };
- 默认位置起始于
0x08007C00
#define EEPROM_START_ADD (uint32_t)0x08007C00
- 当
main
启动时,0x08000FE0
值为0xf8
时,需要使用新地址参数表 //怀疑有部分备份参数(尚未找到出处)
if((*(uint32_t*)(0x08000FE0)) == 0xf8){
eeprom_address = (uint32_t)0x0800F800;
}
- 从第52字节开始的128字节,直至176为音律,详见:
playBlueJayTune
// read_flash_bin(blueJayTuneBuffer , eeprom_address + 48 , 128);
for (int i = 52; i < 176; i += 2) {
- 调用底层BSP驱动
EEprom
代码
`AM32\Mcu\f421\Src\eeprom.c`
├──> void read_flash_bin(uint8_t* data, uint32_t add, int out_buff_len)
└──> void save_flash_nolib(uint8_t* data, int length, uint32_t add)