Пытаюсь написать подпрограмму десятичной считалки, и застрял. 0-99 считает, дальше не могу продолжить:
Код:
back: inc R1 cjne R1, #9, back mov R1, #0 inc R2 cjne R2, #9, back cjne R1, #9, back mov R2, #0
При переходе к третьему разряду надо проверить на 9-ку R1, R2, и переходить к R3 но в R1 всегда ноль. Но не обнулять нельзя, тогда он просто считает дальше 9-ки. Вот тут я застрял.
Потому что после 9-ки в регистре появляется 0x0A, с которым непонятно что делать, если выводить результат из счетного регистра, и отправлять его на индикацию. А хотелось бы что только 0-9.
можно еще конечно делать типа:
Код:
back: add A, #1 da A cjne A, #99, back ...
и все получается. Но, надо будет разбирать результат на тетрады (громоздко), и не представляю как осуществлять обратный счет, т.к DA A с вычитанием не работает.
А прямая табличная перекодировка? можно и через DPTR movc a,@a+dptr и через текущий РС movc a,@a+pc Счет ведем в бинарном формате, декодировка из бинарника в неупакованный двоично-десятичный (0x0N) в зависимости от того, что удобнее. Далее из тетрады в сегментный код по табличке.
Потому что после 9-ки в регистре появляется 0x0A, с которым непонятно что делать
именно когда в регистре появится 10, нужно обнулять регистр и делать перенос (инкремент) следующего разряда (регистра). а то по твоему коду счет идет только до 9, а не до 10 - считает до 8, а потом сразу появляется 10. число 09 у тебя отсутствует.
_________________ Мудрость приходит вместе с импотенцией... Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
именно когда в регистре появится 10, нужно обнулять регистр и делать перенос (инкремент) следующего разряда (регистра).
Кроме собственно, счета, надо забирать результат из счетного регистра. Если его забираю до сброса в ноль - у меня там десятка (x0A) оказывается, если после сброса в ноль - соответственно, там всегда ноль. Я уже уже прошагал это в симуляторе, это тоже не работает
Это уже вопрос организации цикла: действие до инкремента/декремента или действие после инкремента/декремента и в каком месте анализ на завершение цикла проводится. Поэтому для анализа и/или подсказки нужно видеть полную программу, а не только сам контрольный цикл. И второе... собственно анализ только отдельно взятого цикла вывода на индикацию без источника приращения не бывает. А там вероятно какой-то генератор на прерывании устроен. Либо есть возможность пресечения анализируемой прожки "сторонними подпрограммами"... В результате как вариант еще и хранение критичных регистров в стеке на время прерывания добавится.
Я меж тем главного не заметил, что считалка у меня не завершается никогда пока не досчитает до 9999. А она должна быть однопроходной, то есть может быть вызвана однократно.Оформил как подпрограмму, завел 4 ячейки памяти, которые вгружаю в счетные регистры в начале, и выгружаю из регистров при выходе. Как жаль, что CJNE не работает с адресами памяти, так бы удалось сэкономить 16 байт. Насчет какой-то программы в общем... пока не знаю. Я пару лет назад удачно написал динамическую индикацию без внешних микрух, и пытаюсь придумать ей какую-то полезную загрузку. Так все заработало, спасибо всем большое
Да я знаю набор инструкций 8051. Просто в CJNE нельзя указать как источник прямой адрес памяти, типа, CJNE 0x33, #direct, rel - вот что печалит. либо ACC, либо РОНы, либо @Ri - указатель на память
Это разве что для АТ89С2051 имеет некоторое значение. А для экономии в большинстве случаев удобнее подпрограммы использовать Второе... Не забываем, что как сравнение могут выступать и другие команды (а не только "неразрушающая" данные CJNE). К примеру та же XRL с последующим анализом на нуль в аккумуляторе. Да и много других приемов, не обязательно на основе математики - иногда логика удобнее или специфические особенности кодов используемых в программе данных. Правда в таком случае порой приходится полностью переделывать и схемотехнику и программу заново писать. Да и собственно по CJNE a,adr,rel одним операндом является содержимое аккумулятора а вторым содержимое ячейки ОЗУ, адрес которой указан в команде. Собственно от того, какой из операндов будет первым результат не меняется (в любом случае оценивается равенство или неравенство) как и данные что в АCC, что в ячейке adr после операции сравнения. В отличии от того же к примеру: XRL a,adr когда в аккумуляторе останется результат операции, т.е. "данные в АСС будут разрушены"
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения