А вот сам алгоритм. Так, что бы понять на сколько все весело

Код:
[Выделить]void tuner_auto_start(void) //auto-tune
{
if (tu.tuning == NO) { return; }
if (!tu.yn) tunerYN(YES);
if (tu.autoJustStartedYN && tone.yn && !tu.autoGoingYN) cwtoneYN(NO);//вырубить тон если есть перед стартом
if (!tx.yn && !tu.autoGoingYN) {//включить передачу TX
txYN(YES);
needTxChange();
}
if (!dspMode.tuningYN) {
oldPower=po.powerBand[band.nowIsNumber]; //запомним какая была мощь
po.powerBand[band.nowIsNumber]=126;// -34 дб
powerAttSet();// обновляем мощьность
DSP_TX_MUTE_WHEN_TUNING_SET(YES); //mute mic line
dspMode.tuningYN = YES;
}
//рутина перед стартом и пропускаем если идет процесс настройки в цикле
if (tu.autoJustStartedYN && !tu.autoGoingYN) {
cwtoneYN(YES);//tone on
// pa_att_change_to((uint8_t) 0xf, 0); // att=15, ff-ssb 0-cw
// si5351aSetFrequency_2_IF500(freq.FREQ_IF3lsb + freq.FREQ_PITCH);
tu.autoJustStartedYN = NO;
tu.tuningStep = 0;//этапы тюнинга
tu.tempValueIdx = 0;//индекс прохода во время поиска куда подключить кондер
tu.cYN = 0xff;// 0-тюним L, ff-тюнем С
tu.badIterationCount = 5;//сколько перезапусков для поиска
tu.badCountLC = 0; // итерация по Л С оба плохие 2=плохо 0=сначала
// if ((tu.SWR_ch_value[0] - tu.SWR_ch_value[1]) / 18000 < 3) {
// tu.autoJustStartedYN = YES;
// //todo hi swr warning
// // warningOnDisplay((uint8_t *) " HI SWR >6. Check Ant ");
// goto back1;
// }
//
// if (v_to_dbW(SWR_ch_value[0]) < 0) {
// // tunerAutoStartYN = 0;
// warningOnDisplay((uint8_t *) " Need MORE power or Tone. ");
//
// }
if (v_to_dbW(tu.SWR_ch_value[0]) > 12) {
tu.autoJustStartedYN = YES;
//todo Hi Power! <15dbW need.
// warningOnDisplay((uint8_t *) " Hi Power! <15dbW need. ");
goto back1;
}
// warningOnDisplay((uint8_t *) " Tuning... ");
tu.more50 = 0;//итерации в 0 начнем все сначала
tu.circleC = 0;
///установка степа в зависимости от диапазона
if (band.nowIsNumber < 3) {
tu.circleL = 100;
tu.circleC = -100;
max = 60;
min = -60;
tu.stepC = 4; //стартовая емкость
}
if (band.nowIsNumber >= 3 && band.nowIsNumber < 5) {
tu.circleL = 1;
tu.circleC = 1;
max = 30;
min = -30;
tu.stepC = 2; //стартовая емкость
}
if (band.nowIsNumber >= 5 && band.nowIsNumber < 7) {
tu.circleL = 1;
tu.circleC = 1;
max = 15;
min = -15;
tu.stepC = 1; //стартовая емкость
}
if (band.nowIsNumber >= 7) {
tu.circleL = 1;
tu.circleC = 1;
max = 8;
min = -8;
tu.stepC = 1; //стартовая емкость
}
// tu.circleL = tu.stepL;
// tu.circleC = tu.minC;
//обнулим значения до старта (с учетом диапазона)
best.lastBestValueLC[band.nowIsNumber][0][ant.nowAntIs] = 0;
best.lastBestValueLC[band.nowIsNumber][1][ant.nowAntIs] = 0;//tu.minC;
best.lastBestValueLC[band.nowIsNumber][2][ant.nowAntIs] = 0;
//первое и текущее -лучшее значения
tu.lastBestPSR[0] = 0;//power
tu.lastBestPSR[1] = 0;//swr
tu.lastBestPSR[2] = 0;//RL
tu.lastBestPSR[3] = tu.more50;//кондер
//!!!!!!
// tuner_write(0, 0);
}//конец рутины
//analyse
//
//
// readSwrTuner();//read swr ADC
if (v_to_dbW(tu.SWR_ch_value[0]) > 13) {
//todo Need less 15dbW power.
tu.tuning = NO;
// warningOnDisplay((uint8_t *) " Need less 15dbW power. ");
goto back1; //exit
}
// tu.rl = tu.SWR_ch_value[0] - tu.SWR_ch_value[1];
// if ((tu.rl > tu.lastBestPSR[2] || (!tu.lastBestPSR[0] && !tu.lastBestPSR[1])) && !tu.autoGoingYN) {
// //если рл лучше тогда сохраним это результат (загрубили на ..) или начало
// tunerSaveBest();
// tu.badCountLC = 0; // итерация по Л С оба плохие 2=плохо 0=с начала
// tu.badIterationCount = 5;//сколько перезапусков для поиска
// //условие выхода из настройки
//
//
// }
//else { //если хуже вариант (только основной итерации)
// //анализ по 2 шагу.
// if (tu.tuningStep == 2) {
if (!tu.autoGoingYN) { //если не циклический проход тогда инциализация
tu.autoGoingYN = YES;
exitMain = 4; // выход из итерации в случаии уменьшения до 0
rlNew = 0;//tunerLastBestPSR[2];//RL uV;
rlBest = 0;//tunerLastBestPSR[2];//лучший рл в цикле uV
cNow = tu.circleC;// (uint8_t)tunerLastBestValueLC[nowBandIsNumber][1];
lNow = tu.circleL;// (uint8_t)tunerLastBestValueLC[nowBandIsNumber][0];;
cBest = 0;
lBest = 0;
//
// max = 60;// максимум до каторой будет итерация
// min = -60; // минимум с которой начнется итерация
orLC = 0xff; // 0-тюним L, ff-тюнем С, меняем местами
cLocal = 0; //локальный номер С (старт с рекомендованного номера tunerMaxC)
lLocal = 0;//локальный номер Л
}
//start
if (exitMain) {//0 exit while--------------------
if (!tu.localCircleYN) {//если мини цикл не начат то инициализация
lastFor = 0xff;//последний в цикле лучший
localBest = 0;
localBefore = 0;
localExit = 0;
i = min;
x = 0;
tu.localCircleYN = YES;
}
//старт мини- итераций --------------FOR
if (i <= max) {
if (!tu.tuning || !tx.yn) goto back1;//exit
dropcircle = NO;
if (orLC) {//--------C----------mini----
int cTemp = cNow - i;
if (cTemp <= 255 && cTemp >= -255) {
cLocal = cTemp;
} else { //пропустить этот цикл
if (cTemp < -255) {
if (cLocal == -255) dropcircle = YES;//дроп если повтор значения
else cLocal = -255;
}
if (cTemp > 255) {
if (cLocal == 255) dropcircle = YES;//дроп если повтор значения
else cLocal = 255;
}
}
///если надо то меняем емкость
if (cLocal >= 0 && tu.more50) { //меняем емкость
tu.more50 = NO;
}
if (cLocal < 0 && !tu.more50) { //меняем емкость
tu.more50 = YES;
}
} else {///---------L----------- mini----
int lTemp = lNow + i;
if (lTemp >= 0 && lTemp <= 0x7f) {
lLocal = lTemp;
} else {//пропустить этот цикл
if (lTemp < 0) {
if (lLocal == 0) dropcircle = YES;//дроп если повтор значения
else lLocal = 0;
}
if (lTemp > 0x7f) {
if (lLocal == 0x7f) dropcircle = YES;//дроп если повтор значения
else lLocal = 0x7f;
}
}
}
if (!dropcircle) { //если не надо цикл пропускать
tuner_write(tu.more50 ? //c50
(uint8_t) (lLocal | 0x80)
://подставим бит кондера
(uint8_t) (lLocal & 0x7f),
cLocal);
//tunerDrawBar();
osDelay(30); //relay HF33F, 5msec на разряд емкости
readSwrTuner();//read swr ADC
tu.needDrawSwrBarYN = YES;
rlNew = tu.SWR_ch_value[0] - tu.SWR_ch_value[1];//RL
//поиск локального минимума в итерации
if (rlNew >= localBest) {
localExit = 0; //нашли , обнуляем счетчик плохих проходов
localBest = rlNew;
} else { //если это не локальный минимум
if (localBefore > rlNew) {
localExit++; //то увиличиваем счетчик плохих итераций
}
}
localBefore = rlNew; //запомним текущий рл для следующего использования
if (rlNew > rlBest) {// основной поиск глобального минимума ксв!!!!
rlBest = rlNew;
cBest = cLocal;
lBest = lLocal;
lastFor = x;
tu.circleC = cBest;
tu.circleL = (uint8_t) lBest;
tu.rl = rlBest;
exitMain = 4;
tunerSaveBest();
// sprintf((char *) bufSwr, "locBEST %03d %03d %01d ", cBest, lBest, tu.more50);
// BSP_LCD_DisplayHStringAt(61, 190, (uint8_t *) bufSwr, LEFT_MODE);
}
// если точно минимума больше не будет, но он был уже в этой итерации
// то жесткий выход из итерации
if ((lastFor != 0xff && lastFor + 3 * tu.stepC < x) ||
// выход если уже 4 мини-итерации небыло минимума (глобального)
localExit > 4)// выход из итерации если локальный показатель стал ухудшаться
goto dd;
}//end if dropCircle
i += tu.stepC;
x += tu.stepC;
} else { //end if for
dd://выход из итерации сюда в случаии ухудшения показаний
tu.localCircleYN = NO;
//если в данном цикле больше небыло хороших результатов
if (lastFor == 0xff) {
cNow = cBest;
lNow = lBest;
exitMain--;//выход из настройки в случаии уменьшения до 0
orLC = ~orLC;//меняем Л С местами
} else {//если мин был то..
//адаптивный поиск откуда стартовать при следующей итерации
if (orLC) {//-------------C-----------WHILE------
if (!lastFor) {//если итерация является лучшим последним значением, то с нее и начнем
cNow = cBest;
} else {//либо
int cTemp = cBest + max / 2;
if (cTemp >= -255) {
cNow = cTemp;
} else {
if (cTemp < -255)cNow = -255;
if (cTemp > 255) cNow = 255;
}
}
} else {//-------------L----------WHILE-------
if (!lastFor) {//если итерация является лучшим последним значением, то с нее и начнем
lNow = lBest;
} else {
int lTemp = lBest - max / 2;
if (lTemp <= 0x7f && lTemp >= 0) {
lBest = lTemp;
} else {
if (lTemp < 0) lNow = 0;
if (lTemp > 0x7f) lNow = 0x7f;
}
}
}
}
//если максимум был в внутри цикла
if (lastFor > min && lastFor < max) {
orLC = ~orLC;//меняем Л С местами
}
}
} else {
//Дочистка по Л и по С перебором
lNow = lBest;
cNow = cBest;
tunerSaveBest();
for (int l = -1; l <= 1; l++) {
for (int ii = -4; ii <= 4; ii++) {
uint8_t drop = YES;
if (lNow + l >= 0 && lNow + l <= 0x7f) lLocal = lNow + l;
// else drop = YES;
if (cNow + ii >= -255 && cNow + ii <= 255) cLocal = cNow + ii;
//else drop = YES;
if (cLocal >= 0 && tu.more50) tu.more50 = NO; //меняем емкость
if (cLocal < 0 && !tu.more50) tu.more50 = YES; //меняем емкость
if (drop) {
tuner_write(tu.more50 ? //c50
(uint8_t) (lLocal | 0x80)
://подставим бит кондера
(uint8_t) (lLocal & 0x7f),
cLocal);
tu.needDrawSwrBarYN = YES;
osDelay(30);
readSwrTuner();//read swr ADC
rlNew = tu.SWR_ch_value[0] - tu.SWR_ch_value[1];//RL
if (rlNew > rlBest) {
rlBest = rlNew;
cBest = cLocal;
lBest = lLocal;
tu.circleC = cBest;
tu.circleL = (uint8_t) lBest;
tu.rl = rlBest;
tunerSaveBest();
}
}
}
}
//end дочистки
// //реальные Л и С
// uint16_t L_total = 0;
// uint16_t C_total = 0;
// for (uint8_t i = 0; i < 8; i++) {
// if (cBest & tunerCPF[i][0]) C_total += tunerCPF[i][1];
// if (i < 7)
// if (lBest & tunerLNH[i][0]) L_total += tunerLNH[i][1];
// }
// sprintf((char *) bufSwr, "Cp=%04d Ln=%04d ", tu.circleC, tu.circleL);
// BSP_LCD_DisplayHStringAt(61, 206, (uint8_t *) bufSwr, LEFT_MODE);
//выход с лучшими показателями
tuner_write(tu.more50 ?
(uint8_t) (lBest | 0x80)
://подставим бит кондера
(uint8_t) (lBest & 0x7f),
cBest);
saveTunerTableToFram(); //save to fram
back1: //выход без записи
cwtoneYN(NO); //off tone
tu.autoJustStartedYN = YES;
tu.localCircleYN = NO;
tu.autoGoingYN = NO;
tu.tuning = NO;
//dsp включаем назад мик или лайн
DSP_TX_MUTE_WHEN_TUNING_SET(NO); //mute mic line
dspMode.tuningYN = NO;
//power вернуть мощность какая была
po.powerBand[band.nowIsNumber]=oldPower; //вспомним какая была мощь
powerAttSet();// обновляем мощьность
// txYN(NO);//off tx
// needTxChange();////off tx
//todo вернуть АТТ назад
// pa_att_change_to((uint8_t) att.now[nowBandIsNumber], cwYN);
//}
return;
}
}