Задумался я над одним вопросом, а ответ не приходит. Подскажите, кто в теме.
Есть два входа логических уровней. Задача кода сравнить эти входы: разные или одинаковые.
Как я это делаю: копирую в один регистр сигнал с одного порта, в другой - с другого. Дальше вариантов сравнить много, но суть не в этом.
Вопрос в следующем. Мне нужно сравнить два бита, а приходится использовать два полноценных РОН. Можно ли как-то оптимизировать сравнение без использования такого количества ресурсов?
Viper115 писал(а):Можно ли как-то оптимизировать сравнение без использования такого количества ресурсов?
это ужас, конечно - такой расход ресурсов! вы их, часом, не про запас солить собираетесь? с какой целью экономить-то?
откажитесь от копирования данных: порт - это уже регистр, и с ним можно работать напрямую, например, командами тестирования бита (этак команда не требует наличия еще одного РОН). что вы при этом сэкономите, а что перерасходуете - я не комментирую.
но моё частное мнение - не занимайтесь ерундой, т.е. экономией ресурсов. ресурсы надо рационально использовать, а не экономить.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Захват данных с входных портов в промежуточный буфер делать таки надо.
Ибо... ежли сигналы шустрые, то за время обращения могут и измениться успеть.
Это только весьма статичные можно напрямую на выводах проверять.
Гораздо неприятнее в таком случае, когда те сигналы еще и на разных портах находятся.
Посему работаем со схемотехникой "до устранения" подобной ситуации (сводим контролируемые сигналы в один порт).
Касательно самого алгоритма...
Буфер обязателен...
Поскольку могут сравниваться любые позиционные комбинации потребуется соответствующая маска (или две
в случае, когда остальные линии порта еще для чегось используются).
Ну и стек, если контролируемые выводы в разных портах.
Одначе там скорее всего без двух буферов захвата не обойтись (минимизация расхождения состояния линий на время исполнения второй команды ввода).
Viper115 писал(а):Мне нужно сравнить два бита, а приходится использовать два полноценных РОН.
РОН, в отличии от ОЗУ, используется произвольным образом в разных участках кода. Поэтому, если в текущем коде есть свободные РОНы, экономить их бессмысленно. Все равно следующий участок кода изменит их содержимое.
КРАМ писал(а):Все равно следующий участок кода изменит их содержимое.
Это как программу напишешь. А если проект не большой, то благодаря большому количеству РОН, все переменные могут лежать там. Само собой, как минимум один РОН должен быть в роли аккумулятора.
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
// 7 - первый бит на PORTA
// 5 - второй бит на PORTD
clr r16
sbic PORTA, 7
sbr r16, 0
sbic PORTD, 5
sbr r16, 1
// тут делайте с результатом что хотите.
cpi r16, 1<<0 | 1<<1 // К примеру.
Я это называю собрать в кучу входы на разных портах. Точно так же работаем с выходами. Пусть у нас выходы на разных портах. Делаем переменную в которой состояние выходов. Код пишем теперь навыворот. Распределяем выходы по портам.
Последний раз редактировалось Demiurg Пт янв 27, 2017 16:40:03, всего редактировалось 4 раза.
Z_h_e писал(а):А если проект не большой, то благодаря большому количеству РОН, все переменные могут лежать там. Само собой, как минимум один РОН должен быть в роли аккумулятора.
Да как не пиши, РОНы нельзя использовать иначе, чем локальные регистры (для локальных переменных). В Си это описано соглашением о передаче переменных в функцию, а в АСМе нужно придерживаться аналогичного правила, иначе запутаешься в конец. Особенно из-за ISR и косвенной адресации.
КРАМ писал(а):АСМе нужно придерживаться аналогичного правила,
Что Вам даст, если Вы назначите переменным область IRAM и будете использовать в проекте, например, только регистр R16, кроме увеличения кода? Не понимаю я как тут можно запутаться? По крайне мере чем путанее переменные в регистрах?
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Z_h_e писал(а):Не понимаю я как тут можно запутаться?
Если весь код представляет из себя ногодрыг, то запутаться очень сложно. Но если программа структурирована и представляет из себя набор функций с соответствующими уровнями абстракций, запутаться ЭЛЕМЕНТАРНО. Мало того, использование РОНов вместо ОЗУ приводит к ПОТЕРЕ производительности из-за недостатка РОНов в узких местах кода.
Все это зависит от СТИЛЯ программирования. Если всегда применять определенные правила, то любой код будет минимизирован по ошибкам, легко масштабируем и читаем. Беспорядочное использование РОНов это всегда тупик.
Тут изначально недоделано.
Имеем две асинхронно изменяемых лапки , размещенные в разных портах...
Помимо прочего это не 2, а 4 возможные комбинации из которых две лишние,
а вторые две подлежат проверке.
Чет мне та задачка энкодер напоминает...
(http://radiokot.ru/forum/viewtopic.php? ... 4#p2816604)
Добрался до студии, проверил выложенные коды. Свой, естественно, немного сократил. Самый короткий и быстрый код Z_h_e; самый долго исполняемый код от Viper115. Вариант Demiurg, ввиду его ошибочности, не рассматривался.
.equ port_a = PINA ; порт первого бита при условии, что PINA в области адресов рсф 0х00-0х3F
.equ port_b = PINB ; порт второго бита при условии, что PINB в области адресов рсф 0х00-0х3F
.equ bit0 = PINA.5 ; номер позиции и принадлежность к соответствующему порту первого бита
.equ bit1 = PINB.1 ; номер позиции и принадлежность к соответствующему порту второго бита
;---------------------------------------------------
test:
sbis port_a,bit0
rjmp zero2 ; переход в точку zero2
sbis port_b,bit1
rjmp b1_0 ; идем к обработчику ситуации bit0=1, bit1=0
error1_1:
ret ; error1_1 - ошибка bit0=1, bit1=1
zero2:
sbis port_b,bit1
ret ; error0_0 - ошибка bit0=0, bit1=0
b0_1:
nop ; обработчик ситуации bit0=0, bit1=1
rjmp b0_1 ; временная заглушка взамен реального обработчика
b1_0:
nop ; обработчик ситуации bit0=1, bit1=0
rjmp b1_0 ; временная заглушка взамен реального обработчика
Я ж набросок в IDE не гонял - воть и пропустил очепятку с "иного свинтаксиса" (кстати и на порт/пин А 5 матюкнутьбся может - не у всех млолапых МК имеется).
Это ж "набросок с фонаря" по принципу обработки.
поставь PINDn и PINBn (n=0-7) при добавке строчки хоша-бы .include tn2313def.inc и радуйси отсутствию матюков.
(
Спойлер
.equ port_a = PIND ; порт первого бита при условии, что PIND в области адресов рсф 0х00-0х3F
.equ port_b = PINB ; порт второго бита при условии, что PINB в области адресов рсф 0х00-0х3F
.equ bit0 = PIND5 ; номер позиции и принадлежность к соответствующему порту первого бита
.equ bit1 = PINB1 ; номер позиции и принадлежность к соответствующему порту второго бита
;---------------------------------------------------
.include "tn2313def.inc"
test:
sbis port_a,bit0
rjmp zero2 ; переход в точку zero2
sbis port_b,bit1
rjmp b1_0 ; идем к обработчику ситуации bit0=1, bit1=0
error1_1:
ret ; error1_1 - ошибка bit0=1, bit1=1
zero2:
sbis port_b,bit1
ret ; error0_0 - ошибка bit0=0, bit1=0
b0_1:
nop ; обработчик ситуации bit0=0, bit1=1
rjmp b0_1 ; временная заглушка взамен реального обработчика
b1_0:
nop ; обработчик ситуации bit0=1, bit1=0
rjmp b1_0 ; временная заглушка взамен реального обработчика
)
по синтаксису вроде верно...
хотя... без полной предварительной настройки портов прокрутка проверки пинов в симуляторе ахинею выдает.
Другое дело, ежли ставится проверка для portd / portb...
надо уточнить полным тестом, а не фрагмент-идеей - возможно напрямую (без предварительного захвата данных в буфер) контроль статуса входных выводов командами sbis/sbic симулятором (а возможно, и железом) не отрабатывается.
Это всего лишь предупреждение/напоминание программисту о том, что данные имена были уже ранее определены.
(переприсвоение ранее определенного имени)
На работу компилятора не влияют. Коды команд выставляются в стоответствии с объявлением.
А воть с регистровым файлом (R0-R31) такой вариант действительно не пройдет - там обязательное .undef требуется.