Перейти к содержанию
    

суммирование в прерывании

Требуется в программе обработки прерывания от пина по фронту прибавлять 1 к переменной до тех пор пока не будет 255.  Прерывании возникает с частотой несколько десятков кгц.  сейчас такой код :

if(interruptcounter <254) interruptcounter++;

Из за проверки переменной есть ветвление, а без проверки счет иногда перескакивает через ноль. Есть способ выполнить быстрее эту операцию?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

9 минут назад, SergeyVas сказал:

Требуется в программе обработки прерывания от пина по фронту прибавлять 1 к переменной до тех пор пока не будет 255.  Прерывании возникает с частотой несколько десятков кгц.  сейчас такой код :


if(interruptcounter <254) interruptcounter++;

Из за проверки переменной есть ветвление, а без проверки счет иногда перескакивает через ноль. Есть способ выполнить быстрее эту операцию?

Какая задача решается? Зачем этот счёт? Почему не используется какой нибудь аппаратный счётчик для этих целей? Зачем ручной счёт?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Нужно в основном цикле программы обнулять переменную 

 interruptcounter

и через некоторое время (зависит от событий ) считывать значение переменной 

 interruptcounter

и отсылать через spi.  переменная должна увеличиваться с каждым прерыванием на 1 до 255. 

Ветвление время забирает думал может можно как то сделать битовыми операциями или может есть способы сделать это быстрее.  

__interrupt pbisr(void)
{
  ....
    if(interruptcounter <254) interruptcounter++;
    .....
  
}

 архитектура st7/

Схема уже собрана к этим портам не подключен аппаратный счетчик

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В ассемблерный листинг вы заглядывали? Почему не сравниваете с 255?

В прерывании еще что-то делается. Может, там экономить такты?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да там проверка перед инкрементом переменной через ветвление. Поменяю 254 на 255. просто в процессе отладки что бы быть уверенным что переменная не перескакивает через ноль сделал на один меньше. 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

57 минут назад, SergeyVas сказал:

Из за проверки переменной есть ветвление, а без проверки счет иногда перескакивает через ноль. Есть способ выполнить быстрее эту операцию?

Откуда идея про скорость? Перескакивание через ноль говорит о том что прерывание отрабатывает отлично. А вот программа которая вычитывает не успевает обрабатывать с той же скоростью. Т.е. основная программа видит например 254 потом приходит два прерывания и программа при очередном опросе видит уже 0. Т.е. вопрос уже скорее в обработке а не в прерывании.
По хорошему надо бы счётчик сделать более длинным а в основной программе проверять больше ли число 255 и если больше то отнимать 255 и считать дальше.

Опять же задача так и осталась не пояснённой. Ибо текущий костыль останавливает счёт. И дальше идёт потеря тактов. Если это допустимо то может и проблемы нет. 

Что является проблемой ради которой нужно поднять скорость ещё больше?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Основной цикл программы по времени не стабильный, опрос ацп датчиков, интерфейс и другие действия. Иногда нужно послать импульс и подсчитать количество прерываний на входе. то что будут пропуски не страшно, хуже когда в счетчике будет например 5 а на самом деле было 260 импульсов. Сильно расходует время два прерывания на двух портах частота  от 30 до 50кгц фаза независима обоих сигналов. микроконтроллер не высокой производительности. хотелось как можно быстрее выполнить эту процедуру. Что бы выделить больше времени на другие операции в основном цикле.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Без ветвления можно сделать так

volatile u8 cnt;

ISR()
{
  s16 i = (s16)(cnt - (u16)255) >> 15;
  cnt   = cnt - i;
}

Однако сначала надо проверить, что сдвиг вправо отрицательного числа компилятор делает арифметическим сдвигом (т.е. сохраняя знак).
Иначе конструкция не будет работать, т.к. вообще говоря, сдвиг отрицательного вправо, как гласит Стандарт Си, это implementation-defined behavior.

Но, ИМХО, на этой архитектуре этот код будет проигрывать обычному ветвлению типа if(cnt < 255) ++cnt.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Moжет стоит пойти другим путем - вычитать, пока не досчитаем до нуля? А если уже ноль - не вычитать. И отправлять 255 - interruptcounter. Я не знаю системы команд ST7, но обычно проверка на ноль более "дешевая" опрерация по сравнению со сравнением с константой.

Также стоит помнить, что interruptcounter - volatile-переменная, а значит в прерывании надо завести ее локальную копию, чтобы компилятор не лазал в каждой операции за ней в память.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, SergeyVas сказал:

Из за проверки переменной есть ветвление, а без проверки счет иногда перескакивает через ноль. Есть способ выполнить быстрее эту операцию?

interruptcounter = __USAT(interruptcounter + 1, 8);

Скомпилится всего в 4 команды (вместе с чтение/записью в память) и без ветвления.

Или:

uint i = interruptcounter + 1;
interruptcounter = i - (i >> 8);

те же 4 команды.

 

57 минут назад, SergeyVas сказал:

просто в процессе отладки что бы быть уверенным что переменная не перескакивает через ноль сделал на один меньше. 

:biggrin::biggrin::biggrin:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...