SergeyVas 0 31 марта, 2021 Опубликовано 31 марта, 2021 · Жалоба Требуется в программе обработки прерывания от пина по фронту прибавлять 1 к переменной до тех пор пока не будет 255. Прерывании возникает с частотой несколько десятков кгц. сейчас такой код : if(interruptcounter <254) interruptcounter++; Из за проверки переменной есть ветвление, а без проверки счет иногда перескакивает через ноль. Есть способ выполнить быстрее эту операцию? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 31 марта, 2021 Опубликовано 31 марта, 2021 · Жалоба < 255 должно быть Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VladimirG 0 31 марта, 2021 Опубликовано 31 марта, 2021 · Жалоба uint8_t counter = 1; ... int_handler(){ counter++;} ... while(1){ if(counter == 0) make some } а если так? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MegaVolt 25 31 марта, 2021 Опубликовано 31 марта, 2021 · Жалоба 9 минут назад, SergeyVas сказал: Требуется в программе обработки прерывания от пина по фронту прибавлять 1 к переменной до тех пор пока не будет 255. Прерывании возникает с частотой несколько десятков кгц. сейчас такой код : if(interruptcounter <254) interruptcounter++; Из за проверки переменной есть ветвление, а без проверки счет иногда перескакивает через ноль. Есть способ выполнить быстрее эту операцию? Какая задача решается? Зачем этот счёт? Почему не используется какой нибудь аппаратный счётчик для этих целей? Зачем ручной счёт? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 131 31 марта, 2021 Опубликовано 31 марта, 2021 · Жалоба А что не так с ветвлением? Какое ядро? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SergeyVas 0 31 марта, 2021 Опубликовано 31 марта, 2021 · Жалоба Нужно в основном цикле программы обнулять переменную interruptcounter и через некоторое время (зависит от событий ) считывать значение переменной interruptcounter и отсылать через spi. переменная должна увеличиваться с каждым прерыванием на 1 до 255. Ветвление время забирает думал может можно как то сделать битовыми операциями или может есть способы сделать это быстрее. __interrupt pbisr(void) { .... if(interruptcounter <254) interruptcounter++; ..... } архитектура st7/ Схема уже собрана к этим портам не подключен аппаратный счетчик Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 31 марта, 2021 Опубликовано 31 марта, 2021 · Жалоба В ассемблерный листинг вы заглядывали? Почему не сравниваете с 255? В прерывании еще что-то делается. Может, там экономить такты? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SergeyVas 0 31 марта, 2021 Опубликовано 31 марта, 2021 · Жалоба Да там проверка перед инкрементом переменной через ветвление. Поменяю 254 на 255. просто в процессе отладки что бы быть уверенным что переменная не перескакивает через ноль сделал на один меньше. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MegaVolt 25 31 марта, 2021 Опубликовано 31 марта, 2021 · Жалоба 57 минут назад, SergeyVas сказал: Из за проверки переменной есть ветвление, а без проверки счет иногда перескакивает через ноль. Есть способ выполнить быстрее эту операцию? Откуда идея про скорость? Перескакивание через ноль говорит о том что прерывание отрабатывает отлично. А вот программа которая вычитывает не успевает обрабатывать с той же скоростью. Т.е. основная программа видит например 254 потом приходит два прерывания и программа при очередном опросе видит уже 0. Т.е. вопрос уже скорее в обработке а не в прерывании. По хорошему надо бы счётчик сделать более длинным а в основной программе проверять больше ли число 255 и если больше то отнимать 255 и считать дальше. Опять же задача так и осталась не пояснённой. Ибо текущий костыль останавливает счёт. И дальше идёт потеря тактов. Если это допустимо то может и проблемы нет. Что является проблемой ради которой нужно поднять скорость ещё больше? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SergeyVas 0 31 марта, 2021 Опубликовано 31 марта, 2021 · Жалоба Основной цикл программы по времени не стабильный, опрос ацп датчиков, интерфейс и другие действия. Иногда нужно послать импульс и подсчитать количество прерываний на входе. то что будут пропуски не страшно, хуже когда в счетчике будет например 5 а на самом деле было 260 импульсов. Сильно расходует время два прерывания на двух портах частота от 30 до 50кгц фаза независима обоих сигналов. микроконтроллер не высокой производительности. хотелось как можно быстрее выполнить эту процедуру. Что бы выделить больше времени на другие операции в основном цикле. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MegaVolt 25 31 марта, 2021 Опубликовано 31 марта, 2021 · Жалоба Может всё же перекинуть выводы? Доработка проводками? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 131 31 марта, 2021 Опубликовано 31 марта, 2021 · Жалоба Без ветвления можно сделать так volatile u8 cnt; ISR() { s16 i = (s16)(cnt - (u16)255) >> 15; cnt = cnt - i; } Однако сначала надо проверить, что сдвиг вправо отрицательного числа компилятор делает арифметическим сдвигом (т.е. сохраняя знак). Иначе конструкция не будет работать, т.к. вообще говоря, сдвиг отрицательного вправо, как гласит Стандарт Си, это implementation-defined behavior. Но, ИМХО, на этой архитектуре этот код будет проигрывать обычному ветвлению типа if(cnt < 255) ++cnt. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 31 марта, 2021 Опубликовано 31 марта, 2021 · Жалоба cnt++; if(!cnt) cnt--; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 31 марта, 2021 Опубликовано 31 марта, 2021 · Жалоба Moжет стоит пойти другим путем - вычитать, пока не досчитаем до нуля? А если уже ноль - не вычитать. И отправлять 255 - interruptcounter. Я не знаю системы команд ST7, но обычно проверка на ноль более "дешевая" опрерация по сравнению со сравнением с константой. Также стоит помнить, что interruptcounter - volatile-переменная, а значит в прерывании надо завести ее локальную копию, чтобы компилятор не лазал в каждой операции за ней в память. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 183 31 марта, 2021 Опубликовано 31 марта, 2021 · Жалоба 1 час назад, SergeyVas сказал: Из за проверки переменной есть ветвление, а без проверки счет иногда перескакивает через ноль. Есть способ выполнить быстрее эту операцию? interruptcounter = __USAT(interruptcounter + 1, 8); Скомпилится всего в 4 команды (вместе с чтение/записью в память) и без ветвления. Или: uint i = interruptcounter + 1; interruptcounter = i - (i >> 8); те же 4 команды. 57 минут назад, SergeyVas сказал: просто в процессе отладки что бы быть уверенным что переменная не перескакивает через ноль сделал на один меньше. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться