Главная › Форумы › Конструкторское бюро › Автоматизация › Автоматика LuckyBox › Управление мощностью ТЭНа
-
АвторСообщения
-
21.08.2019 в 21:15 #46495
Может быть тогда деление заменить на умножение, можно прилично по времени съэкономить)
Да! Я с виду шут, но в душе король, и ни кто как я не может...
21.08.2019 в 21:25 #4649821.08.2019 в 22:42 #46512Может быть тогда деление заменить на умножение, можно прилично по времени съэкономить)
Надо посмотреть набор команд на данный проц, возможно и стоит. Я просто в основном с PIC контроллерами работаю, там и умножение и деление на аппаратном уровне. Уходит 1 такт проца на умножение (16 бит * 16 бит) и 18 на деление (32 бита / 16 бит). А вот от переменных float постараюсь точно уйти в критичных местах. Я же просто торопился перед отпуском, оптимизацией еще не занимался. А так надо в живую на реальной нагрузке проверить, если будет “плясать” в пределах 1% мощности это думаю не критично.
Еще, как вариант, добиться деления кратному 2^n, тогда сдвигом битов можно делить, с умножением та же песня только сдвигаем в другую сторону. И это я кстати в коде использую, просто не везде.21.08.2019 в 23:04 #46514Порядка 5-6 мкс с каждой операции можно уменьшить.
Умножение и сложение где-то 0.7мкс деление и степень на порядок и ещё чуток больше.
Оптимально деление на умножение, степень тоже на умножение.
Ещё с float поиграться можно. Там где-то 10-11мкс на операции съэкономить можно.
По коду очень сложно от if избавиться. Но буду ещё смотреть.
Да! Я с виду шут, но в душе король, и ни кто как я не может...
21.08.2019 в 23:21 #46519Деление на 2 и на 4 переделаю на битовый сдвиг, чет только сейчас внимание обратил что ступил. Float тоже не проблема убрать. А там еще посмотрим.
21.08.2019 в 23:22 #46520Так кажется понял как предыдущий кусок кода на case перевести завтра на бросаю, а то с телефона сижу
Да! Я с виду шут, но в душе король, и ни кто как я не может...
22.08.2019 в 09:50 #46573Ну вот как то так конечно не море времени сокращается но все же.
Было:
frecuence = 1 / (tmpCalcTMR1 * 0.000001); // считаем герцы для отображения
if (frecuence > 48 && frecuence < 52) frecuence = 50;
else if (frecuence > 58 && frecuence < 62) frecuence = 60;Стало:
switch (frecuence) {
case 48:
case 49:
case 50:
case 51:
case 52:frecuence = 50;
break;
case 58:
case 59:
case 60:
case 61:
case 62:frecuence = 60;
break;
}
Тут если все нормально удастся сократить от 0.3 до 1.4 мксБыло:
// расчет мощности от заданных процентов
userPowerSet = ((uint32_t)powerMax * (uint32_t)triacPercentIn) / 100;
стало
// расчет мощности от заданных процентов
userPowerSet = ((uint32_t)powerMax * (uint32_t)triacPercentIn) * 0.01; // минус 5 мксБыло:
// Опрос энкодера
ISR (TIMER2_COMPA_vect) {
if (*portInputRegister(digitalPinToPort(11)) & 8) encoder_CLK = 1;
else encoder_CLK = 0;
if (*portInputRegister(digitalPinToPort(9)) & 2) encoder_DT = 1;
else encoder_DT = 0;if ((!encoder_CLK) && (encoder_CLK_prev)) {
if (encoder_DT) encoder_Data++;
else encoder_Data–;
}
encoder_CLK_prev = encoder_CLK;
if (dotRX < 255) dotRX++;
}Стало:
ISR (TIMER2_COMPA_vect) {
switch (*portInputRegister(digitalPinToPort(11)) & 8){
case 0: encoder_CLK = 1;
break;
case 1:encoder_CLK = 0;
break;
}
switch (*portInputRegister(digitalPinToPort(9)) & 2){
case 0: encoder_DT = 1;
break;
case 1:encoder_DT = 0;
break;
}
if ((!encoder_CLK) && (encoder_CLK_prev)) {
switch (encoder_DT) {
case0: encoder_Data++;
break;
case 1: encoder_Data–;
break;
}
}
encoder_CLK_prev = encoder_CLK;
if (dotRX < 255) dotRX++;
}
Тут если я прав, должны чуток сократить от 1.2 мкс и может чуть больше.
Было:
EEPROM.get(0, powerMax);
if (powerMax > 9000 && (powerMax % 50) != 0) powerMax = 3000;
stepOnePercent = powerMax / 100;
calcTMR1pr = 18500;
tmr1_pr = 18500;
Стало:
EEPROM.get(0, powerMax);
if (powerMax > 9000 && (powerMax % 50) != 0) powerMax = 3000;
stepOnePercent = powerMax * 0.01; //выиграли где-то 5 мкс.
calcTMR1pr = 18500;
tmr1_pr = 18500;
Тут спорный код
if (ADC_Done_U == 1) {
VoltageIn = (float)(sqrt(VoltageIn / countU)) * VoltageCoeff;
VoltageOnIn = (float)(sqrt(VoltageOnIn / countU)) * VoltageCoeff;
// сглаживание
Voltage = Voltage – (Voltage >> 2) + (VoltageIn >> 2);
VoltageOn = VoltageOn – (VoltageOn >> 2) + (VoltageOnIn >> 2);ADC_Done_U = 0;
VoltageIn = 0;
VoltageOnIn = 0;
countU = 0;
}
if (ADC_Done_I == 1) {
CurrentIn = (float)(sqrt(CurrentIn / countI)) * CurrentCoeff;
// сглаживание
if (CurrentIn >= 10) Current = Current – (Current >> 2) + (CurrentIn >> 2);
else Current = 0;CurrentOut = (float)Current / 100.0;
Power = ((uint32_t)Current * VoltageOn) / 100;ADC_Done_I = 0;
CurrentIn = 0;
countI = 0;// расчет коррекции угла открытия симистора
if (Power > userPowerSet) delta = (Power – userPowerSet) / stepOnePercent;
else delta = (userPowerSet – Power) / stepOnePercent;
delta <<= 4; // умножаем на 16
if (Power < userPowerSet) {
if (tmr1_pr >= (10 + delta)) tmr1_pr -= delta;
else if (tmr1_pr >= (10 + delta/2)) tmr1_pr -= delta/2;
else if (tmr1_pr >= (10 + delta/4)) tmr1_pr -= delta/4;
else if (tmr1_pr > 10) tmr1_pr–;
}
else if (Power > userPowerSet) {
if (tmr1_pr <= (calcTMR1pr + delta)) tmr1_pr += delta;
else if (tmr1_pr <= (calcTMR1pr + delta/2)) tmr1_pr += delta/2;
else if (tmr1_pr <= (calcTMR1pr + delta/4)) tmr1_pr += delta/4;
else if (tmr1_pr < calcTMR1pr) tmr1_pr++;
}U_I = 0;
}
я бы так:
if (ADC_Done_U == 1) {
VoltageIn = (float)(sqrt(VoltageIn / countU)) * VoltageCoeff;
VoltageOnIn = (float)(sqrt(VoltageOnIn / countU)) * VoltageCoeff;
// сглаживание
Voltage = Voltage – (Voltage >> 2) + (VoltageIn >> 2);
VoltageOn = VoltageOn – (VoltageOn >> 2) + (VoltageOnIn >> 2);ADC_Done_U = 0;
VoltageIn = 0;
VoltageOnIn = 0;
countU = 0;
}
if (ADC_Done_I == 1) {
CurrentIn = (float)(sqrt(CurrentIn / countI)) * CurrentCoeff;
// сглаживание
if (CurrentIn >= 10) Current = Current – (Current >> 2) + (CurrentIn >> 2);
else Current = 0;CurrentOut = (float)Current *0.01;
Power = ((uint32_t)Current * VoltageOn) * 0.01; //Суммарно сократили бы на 9-11 мксADC_Done_I = 0;
CurrentIn = 0;
countI = 0;// расчет коррекции угла открытия симистора
if (Power > userPowerSet) delta = (Power – userPowerSet) / stepOnePercent;
else delta = (userPowerSet – Power) / stepOnePercent;
delta <<= 4; // умножаем на 16
if (Power < userPowerSet) {
if (tmr1_pr >= (10 + delta)) tmr1_pr -= delta;
else if (tmr1_pr >= (10 + delta/2)) tmr1_pr -= delta/2;// Тут я бы заменил по простому на умножение и на всех операциях бы сократили где-то на 20-40 мкс
else if (tmr1_pr >= (10 + delta/4)) tmr1_pr -= delta/4;
else if (tmr1_pr > 10) tmr1_pr–;
}
else if (Power > userPowerSet) {// Думаю от этого if можно избавиться
if (tmr1_pr <= (calcTMR1pr + delta)) tmr1_pr += delta;
else if (tmr1_pr <= (calcTMR1pr + delta/2)) tmr1_pr += delta/2;
else if (tmr1_pr <= (calcTMR1pr + delta/4)) tmr1_pr += delta/4;
else if (tmr1_pr < calcTMR1pr) tmr1_pr++;
}U_I = 0;
}Ну как-то так
Да! Я с виду шут, но в душе король, и ни кто как я не может...
22.08.2019 в 11:23 #46578Это не критично, т.к. выполняем только один раз при старте:
frecuence = 1 / (tmpCalcTMR1 * 0.000001); // считаем герцы для отображения
if (frecuence > 48 && frecuence < 52) frecuence = 50;
else if (frecuence > 58 && frecuence < 62) frecuence = 60Эти места:
else if (tmr1_pr <= (calcTMR1pr + delta/2)) tmr1_pr += delta/2;
else if (tmr1_pr <= (calcTMR1pr + delta/4)) tmr1_pr += delta/4;
уже заменил так:
else if (tmr1_pr <= (calcTMR1pr + (delta>>1))) tmr1_pr += (delta>>1);
else if (tmr1_pr <= (calcTMR1pr + (delta>>2))) tmr1_pr += (delta>>2);Далее по расчетам с float, было:
CurrentIn = (float)(sqrt(CurrentIn / countI)) * CurrentCoeff;
Сделал:
CurrentIn = ((uint32_t)(sqrt(CurrentIn / countI)) * CurrentCoeff) >> 7; в данном случае просто множитель CurrentCoeff будет равен не 6.32 а целочисленный 809 которое сдвигом поделим на 128, т.е. 809/128=6.32С энкодером почти согласен, только вот это:
case 0: encoder_CLK = 1;
break;
case 1: encoder_CLK = 0;
break;
заменим на битовые операции вместо присвоения, еще скорость возрастет (по крайней мере = 1 точно вместо двух операций на asm будет одна, главное переменную при старте обнулить):
case 0: encoder_CLK | = 0x01;
break;
case 1: encoder_CLK &= ~0x01;
break;
с переменной encoder_DT аналогично.По поводу /100 или *0.01 не знаю, надо смотреть что там GCC генерит при этом.
22.08.2019 в 11:42 #46579Вот этот кусок
}
else if (Power > userPowerSet) {// Думаю от этого if можно избавиться
if (tmr1_pr <= (calcTMR1pr + delta)) tmr1_pr += delta;
else if (tmr1_pr <= (calcTMR1pr + delta/2)) tmr1_pr += delta/2;
else if (tmr1_pr <= (calcTMR1pr + delta/4)) tmr1_pr += delta/4;
else if (tmr1_pr < calcTMR1pr) tmr1_pr++;
}Думаю перед ним надо где-то поставить <= вместо < иначе при равенстве может быть глюк, хотя это я бы просто поставил чтобы застраховаться.Все понял, тяжело чужой код править. (Да! Я с виду шут, но в душе король, и ни кто как я не может...
22.08.2019 в 12:03 #46583Вот этот кусок
Я этот кусок уже переделал, выше пример привел, сдвиг вместо деления.
А так да, в чужом коде тяжко ковыряться )))
22.08.2019 в 13:17 #46587Вот этот кусок } else if (Power > userPowerSet) {// Думаю от этого if можно избавиться if (tmr1_pr <= (calcTMR1pr + delta)) tmr1_pr += delta; else if (tmr1_pr <= (calcTMR1pr + delta/2)) tmr1_pr += delta/2; else if (tmr1_pr <= (calcTMR1pr + delta/4)) tmr1_pr += delta/4; else if (tmr1_pr < calcTMR1pr) tmr1_pr++; }
Думаю перед ним надо где-то поставить <= вместо < иначе при равенстве может быть глюк, хотя это я бы просто поставил чтобы застраховаться.Все понял, тяжело чужой код править. (Этот кусок, мне спокойно спать не дает. По хорошему, расчет delta/2 и /4 за проверку в две переменные закинуть, но тут палка о двух концах двумя переменными большой кусок памяти оттяпать можем, но зато чуток в if-ах скорость увеличим.
Да! Я с виду шут, но в душе король, и ни кто как я не может...
22.08.2019 в 13:21 #46588Вот этот кусок
Я этот кусок уже переделал, выше пример привел, сдвиг вместо деления. А так да, в чужом коде тяжко ковыряться )))
Будем ждать нового кода, чтобы сказать свое радостное фи )
Да! Я с виду шут, но в душе король, и ни кто как я не может...
23.08.2019 в 00:18 #46634Будем ждать нового кода, чтобы сказать свое радостное фи )
Так твое “фи” всегда подстегивает дальше подумать, но это не страшно, говори )))
Завтра силовой блок окультурю в коробок, и в воскресенье испытаю в живую, и на старой прошивке, и на подправленной, с совместными идеями.23.08.2019 в 08:36 #46655Хотелось бы посмотреть на сколько скорость измениться. Датчик htwc004 кажется так на ac1050 заменить можно, а то монтаж разный получается
Да! Я с виду шут, но в душе король, и ни кто как я не может...
23.08.2019 в 08:51 #46657Ага только сегодня думал за чем он на проводах нужен.
modern distiller, разрушаем "каноны")
https://vk.com/club173629256
Я хочу синего джина, я хочу чёрного рома.... -
АвторСообщения
- Для ответа в этой теме необходимо авторизоваться.