// Реализует функцию УОЗ от оборотов для пуска двигателя // Возвращает значение угла опережения в целом виде * 32, 2 * 16 = 32. int16_t start_function(struct ecudata_t* d) { int16_t i, i1, rpm = d->sens.inst_frq; if (rpm < 200) rpm = 200; //200 - минимальное значение оборотов i = (rpm - 200) / 40; //40 - шаг по оборотам if (i >= 15) i = i1 = 15; else i1 = i + 1; return simple_interpolation(rpm, _GB(&d->fn_dat->f_str[i]), _GB(&d->fn_dat->f_str[i1]), (i * 40) + 200, 40); }
// Реализует функцию УОЗ от оборотов для холостого хода // Возвращает значение угла опережения в целом виде * 32. 2 * 16 = 32. int16_t idling_function(struct ecudata_t* d) { int8_t i; int16_t rpm = d->sens.inst_frq; //находим узлы интерполяции, вводим ограничение если обороты выходят за пределы for(i = 14; i >= 0; i--) if (d->sens.inst_frq >= PGM_GET_WORD(&f_slots_ranges[i])) break; if (i < 0) {i = 0; rpm = 600;} return simple_interpolation(rpm, _GB(&d->fn_dat->f_idl[i]), _GB(&d->fn_dat->f_idl[i+1]), PGM_GET_WORD(&f_slots_ranges[i]), PGM_GET_WORD(&f_slots_length[i])); }
// Реализует функцию УОЗ от оборотов(мин-1) и нагрузки(кПа) для рабочего режима двигателя // Возвращает значение угла опережения в целом виде * 32, 2 * 16 = 32. int16_t work_function(struct ecudata_t* d, uint8_t i_update_airflow_only) { int16_t gradient, discharge, rpm = d->sens.inst_frq, l; int8_t f, fp1, lp1; discharge = (d->param.map_upper_pressure - d->sens.map); if (discharge < 0) discharge = 0; //map_upper_pressure - верхнее значение давления //map_lower_pressure - нижнее значение давления gradient = (d->param.map_upper_pressure - d->param.map_lower_pressure) / 16; //делим на количество узлов интерполяции по оси давления if (gradient < 1) gradient = 1; //исключаем деление на ноль и отрицательное значение если верхнее давление меньше нижнего l = (discharge / gradient); if (l >= (F_WRK_POINTS_F - 1)) lp1 = l = F_WRK_POINTS_F - 1; else lp1 = l + 1; //обновляем переменную расхода воздуха d->airflow = 16 - l; if (i_update_airflow_only) return 0; //выходим если вызвавший указал что мы должны обновить только расход воздуха //находим узлы интерполяции, вводим ограничение если обороты выходят за пределы for(f = 14; f >= 0; f--) if (rpm >= PGM_GET_WORD(&f_slots_ranges[f])) break; //рабочая карта работает на 600-х оборотах и выше if (f < 0) {f = 0; rpm = 600;} fp1 = f + 1; return bilinear_interpolation(rpm, discharge, _GB(&d->fn_dat->f_wrk[l][f]), _GB(&d->fn_dat->f_wrk[lp1][f]), _GB(&d->fn_dat->f_wrk[lp1][fp1]), _GB(&d->fn_dat->f_wrk[l][fp1]), PGM_GET_WORD(&f_slots_ranges[f]), (gradient * l), PGM_GET_WORD(&f_slots_length[f]), gradient); }
uint8_t choke_closing_lookup(struct ecudata_t* d) { int16_t i, i1, t = d->sens.temperat; if (!d->param.tmp_use) return 0; //блок не укомплектован ДТОЖ-ом //-5 - минимальное значение температуры if (t < TEMPERATURE_MAGNITUDE(-5)) t = TEMPERATURE_MAGNITUDE(-5); //5 - шаг между узлами интерполяции по температуре i = (t - TEMPERATURE_MAGNITUDE(-5)) / TEMPERATURE_MAGNITUDE(5); if (i >= 15) i = i1 = 15; else i1 = i + 1; return simple_interpolation(t, _GB(&fw_data.exdata.choke_closing[i]), _GB(&fw_data.exdata.choke_closing[i1]), (i * TEMPERATURE_MAGNITUDE(5)) + TEMPERATURE_MAGNITUDE(-5), TEMPERATURE_MAGNITUDE(5)) >> 4; }
//Реализует функцию коррекции УОЗ по температуре(град. Цельсия) охлаждающей жидкости // Возвращает значение угла опережения в целом виде * 32, 2 * 16 = 32. int16_t coolant_function(struct ecudata_t* d) { int16_t i, i1, t = d->sens.temperat; if (!d->param.tmp_use) return 0; //нет коррекции, если блок неукомплектован ДТОЖ-ом //-30 - минимальное значение температуры if (t < TEMPERATURE_MAGNITUDE(-30)) t = TEMPERATURE_MAGNITUDE(-30); //10 - шаг между узлами интерполяции по температуре i = (t - TEMPERATURE_MAGNITUDE(-30)) / TEMPERATURE_MAGNITUDE(10); if (i >= 15) i = i1 = 15; else i1 = i + 1; return simple_interpolation(t, _GB(&d->fn_dat->f_tmp[i]), _GB(&d->fn_dat->f_tmp[i1]), (i * TEMPERATURE_MAGNITUDE(10)) + TEMPERATURE_MAGNITUDE(-30), TEMPERATURE_MAGNITUDE(10)); }
int uart_send(uint8_t byte) { while ( _GB(UCSR0A , _BV(UDRE0)) == 0 ); UDR0 = byte; return 0; }
int put_char(char byte, FILE *stream) { while ( _GB(UCSR0A , _BV(UDRE0)) == 0 ); UDR0 = byte; return 0; }