Нужна помощь по написанию функции на АСМе

Обсуждаем контроллеры компании Atmel.
DrLithium
Открыл глаза
Сообщения: 79
Зарегистрирован: Вт фев 19, 2008 10:14:47
Откуда: SPb

Re: Нужна помощь по написанию функции на АСМе

Сообщение DrLithium »

Решил поискать реализацию на ассемблере Delay. Нашёл только на Хабре https://habr.com/ru/post/167319/ .
Вроде как попробовал и остался доволен. Но(1)...

Ясно, что таймеры ни кто не отменял и конкретные реализации протоколов можно успешно реализовать только на них. Но (2)...

...(2) Иногда все танцы (таймеры) расписаны и жаль делить под разные задачи и это не главные причины. Бывает нужно обеспечить именно простой работы МК для наружной периферии, при этом не соблюдая особой точности, типа ожидания поворота шестерни или обеспечение продолжительности мигания СДИ или пищалки. Да и просто удобно было бы скомандовать "DELAY 250" или "DELAY 1800".

...(1) Реализация Макросом таила подводные грабли: сумасшедший отжор программной памяти. Т.е. чем чаще использовал вызов макроса, тем толще оказывалась прошивка. После причёсывания проблемы, размер распухшей прошивки с 27К, уменьшился до 11К! И это ассемблер! Я и так где надо использовал PUSHF + POPF и даром это не проходило. Спасает от глюков, но платить приходится опять же программной памятью.

Для себя решил минимизировать поглощение программной памяти и пожертвовал 4-е верхних регистра навсегда. Но, если надо, то вставить в макроопределение PUSH + POP, ни кто не запрещает.

Переменные:
Спойлер; Объявления переменных для функций Delay
.def Delay1=r19 ; переменная функции Delay 1
.def Delay2=r20 ; переменная функции Delay 2
.def Delay3=r21 ; переменная функции Delay 3
.def Delay4=r22 ; переменная функции Delay 4


Макрос:
Спойлер.macro DELAY_MS ; Вызов: "DELAY_MS 10"
ldi Delay3, LOW(@0)
ldi Delay4, HIGH(@0)
rcall DELAY_M_S
.endm

; или для освобождения регистров, ценой программной памяти:

.macro DELAY_MS ; Вызов: "DELAY_MS 10"
PUSH Delay4
PUSH Delay3
PUSH Delay2
PUSH Delay1
ldi Delay3, LOW(@0)
ldi Delay4, HIGH(@0)
rcall DELAY_M_S
POP Delay1
POP Delay2
POP Delay3
POP Delay4
.endm


Функция:
Спойлер; Задержка в циклах
; Delay1 – параметр в диапазоне 4-255 (количество циклов)
DELAY_CL:
_delay_cl:
subi Delay1, 4
cpi Delay1, 4
brsh _delay_cl
cpi Delay1, 1
breq end_cl_1
cpi Delay1, 0
breq end_cl
cpi Delay1, 2
breq end_cl
rjmp end_cl
end_cl_1:
NOP
NOP
NOP
end_cl:
ret

; Задержка в циклах
; Delay1+Delay2 – параметр в диапазоне 15-65535 (количество циклов)
DELAY_C: ; добиться =1мСек, принимается аргумент XTAL/1000
cpi Delay1, 10
brsh fault
rjmp init_Delay2
fault: ; Delay1>=10
ldi Delay1, LOW(LOW(XTAL/1000))
rcall DELAY_CL ; LOW(@0-7)
; коррекция в тактах -28 для 4000 тактов 4МГц(нужно подумать...)
; коррекция в тактах +19 для 16000 тактов 16МГц
ldi Delay1,19
rcall DELAY_CL
init_Delay2: ; Delay1<10
cpi Delay2, 0
breq end_c
new_cycle:
subi Delay2, 1
ldi Delay1,239
rcall DELAY_CL
cpi Delay2, 0
brne new_cycle
NOP
end_c:
ret

; Задержка в милисекундах. Вызов: "DELAY_MS 2567" – параметр в диапазоне 1 – 65535 (количество миллисекунд)
; XTAL – Частота в Герцах
DELAY_M_S:
cpi Delay3, 0
breq re_init
_cicl_msl:
ldi Delay1, LOW(XTAL/1000)
ldi Delay2, HIGH(XTAL/1000)
rcall DELAY_C
subi Delay3, 1
cpi Delay3, 0
breq re_init
rjmp _cicl_msl
re_init:
cpi Delay4, 0
breq _end_c
subi Delay4, 1
ldi Delay3, 255
ldi Delay1, LOW((XTAL/1000)-255*5)
ldi Delay2, HIGH((XTAL/1000)-255*5)
rcall DELAY_C
rjmp _cicl_msl
_end_c:
ret


З.Ы. Пишу здесь, т.к. Хабр не позволяет после регистрации отвечать в старых темах.
З.З.Ы. И это естественно не мой код, только адаптация. И, если кому не сложно, то отполируйте его до приличия. У меня просто не хватает времени и думаю, что сам кому-то его сэкономлю, как и программную память. :))
Последний раз редактировалось DrLithium Ср июн 16, 2021 15:15:59, всего редактировалось 1 раз.
Если в голове каша, значит ваш котелок варит!
akl
Друг Кота
Сообщения: 4444
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Re: Нужна помощь по написанию функции на АСМе

Сообщение akl »

По мне, так гораздо проще

Код: Выделить всё

.equ   Fo=16345677

DELAY_MS:
;25MS
;   LDI   R19,BYTE4(25*Fo/1000/6)
;   LDI   R20,BYTE3(25*Fo/1000/6)
;   LDI   R21,BYTE2(25*Fo/1000/6)
;   LDI   R22,BYTE1(25*Fo/1000/6)   
;2567MS
   LDI   R19,BYTE4(2567*Fo/1000/6)
   LDI   R20,BYTE3(2567*Fo/1000/6)
   LDI   R21,BYTE2(2567*Fo/1000/6)
   LDI   R22,BYTE1(2567*Fo/1000/6)
GO_DEL:
   SUBI   R22,BYTE1(1)
   SBCI   R21,BYTE2(1)
   SBCI   R20,BYTE3(1)
   SBCI   R19,BYTE4(1)
   BRNE   GO_DEL

   RJMP   DELAY_MS

Кстати, выход из макроса правильный?

Код: Выделить всё

.
.
.
rcall DELAY_M_S
PUSH Delay1
PUSH Delay2
PUSH Delay3
PUSH Delay4
.endm
DrLithium
Открыл глаза
Сообщения: 79
Зарегистрирован: Вт фев 19, 2008 10:14:47
Откуда: SPb

Re: Нужна помощь по написанию функции на АСМе

Сообщение DrLithium »

По мне, так гораздо проще

М.б., но я не нашёл других приличных вариантов. М.б. искал мало, время поджимает...
Тут мне понравилось, что в одну строку задаётся задержка и достаточная по диапазону. Сам код естественно можно упростить.

Кстати, выход из макроса правильный?

Там же два варианта, с PUSH/POP-ами или выше без них. Ключевое слово "ИЛИ", в середине. А так всё работает, иначе б не давал. Можно было б сделать точный цикл на 1мСек и ещё цикл на чуть меньше, с подстройкой, по сути завершающий (исполняемый вместо основного, при счётчике =0) для учёта задержек на все входы-выходы. На ассме много места не займёт, а вот сервис повысится. :))
Если в голове каша, значит ваш котелок варит!
akl
Друг Кота
Сообщения: 4444
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Re: Нужна помощь по написанию функции на АСМе

Сообщение akl »

... А так всё работает...
Сомневаюсь. В указанном месте должны стоять POPы. :)
Аватара пользователя
pyzhman
Друг Кота
Сообщения: 7016
Зарегистрирован: Вс июл 12, 2009 19:15:29
Откуда: Ижевск
Контактная информация:

Re: Нужна помощь по написанию функции на АСМе

Сообщение pyzhman »

ТС и пишет:
...Вроде как ...

Ключевое слово - вроде.
Docendo discimus
dgrett
Вымогатель припоя
Сообщения: 615
Зарегистрирован: Вс дек 28, 2014 21:54:05

Re: Нужна помощь по написанию функции на АСМе

Сообщение dgrett »

Я вот не понимаю, 11к, 27к - столько занять может очень серьёзная программа. Ну, допустим, общение с датчиками требует точных таймингов, но это микросекунды. Но городить в серьёзных программах ТАКИЕ вещи - не понятно. Контроллеру некогда будет работать, он будет постоянно висеть в этих задержках.
Я всё-всё узнAю и стану профессором.
DrLithium
Открыл глаза
Сообщения: 79
Зарегистрирован: Вт фев 19, 2008 10:14:47
Откуда: SPb

Re: Нужна помощь по написанию функции на АСМе

Сообщение DrLithium »

В указанном месте должны стоять POPы.

А! Понял! Не оттуда скопипастил. POP вместо PUSH-ей надо писать... Правлю... Спс.

dgrett писал(а):Но городить в серьёзных программах ТАКИЕ вещи - не понятно. Контроллеру некогда будет работать, он будет постоянно висеть в этих задержках.

Дак писал же выше. В тот момент когда работает подобная задержка, периферии и не нужно ни чего ждать от МК. Это кассетная дека, а не самолёт. Нажал на кнопку - ждёшь реакции ЛПМ и более ничего делать не надо. ЛПМ созрел - работай дальше. Наверно у вас подобных примеров в практике не было :))

Ключевое слово - вроде.

Дак лично у меня без PUSH-POP-ов работает. А для всех: скопировал кусок - вставил. Скопировал второй, а он не скопировался. В итоге из буфера два раза PUSH-и вставились. Глаз замылился, проморгал, обещаю отслужить, но желательно в июле и желательно в Крыму! :)))
Если в голове каша, значит ваш котелок варит!
dgrett
Вымогатель припоя
Сообщения: 615
Зарегистрирован: Вс дек 28, 2014 21:54:05

Re: Нужна помощь по написанию функции на АСМе

Сообщение dgrett »

Реакцию лпм ждём в микросекундах? Такого у меня точно не было.
Я всё-всё узнAю и стану профессором.
DrLithium
Открыл глаза
Сообщения: 79
Зарегистрирован: Вт фев 19, 2008 10:14:47
Откуда: SPb

Re: Нужна помощь по написанию функции на АСМе

Сообщение DrLithium »

Реакцию лпм ждём в микросекундах? Такого у меня точно не было.

Не в микро, а в милли. Откуда вы взяли микро? Реально же тут:
Изображение
https://img.radiokot.ru/files/5105/2jlm4aikz6.jpg

Если не видно, то нижняя ссыль на полную картинку. И как вы могли заметить, местами нужно ждать и по 10 мСек! И да, это настоящая кассетная дека, правда Японская.

А если мне ИК-дистанцию подрубить надо будет, то тут будет заюзан таймер. На автостоп другой. Таймер на автоотключение по бездействию - третий. И т.п. ,т.ч. Delay актуален, для остальных работ.
Если в голове каша, значит ваш котелок варит!
dgrett
Вымогатель припоя
Сообщения: 615
Зарегистрирован: Вс дек 28, 2014 21:54:05

Re: Нужна помощь по написанию функции на АСМе

Сообщение dgrett »

{
...(2) Иногда все танцы (таймеры) расписаны}
Стесняюсь спросить, а чем у Вас заняты таймеры?
По картинке наименьшая задержка 10 МИЛЛИсекунд. То есть самый нулевой таймер, выдающий прерывание каждые 10 мС справится и с задержками и с тем, что Вы ещё повесили.

Таймер конфигим на 10 мС

Тело:
ldi delay, 47
sbrc flag, ready
rjmp rcall и тд обработка со сбросом флага
Bla bla

_int-Timer0:
cpi delay, FF
breq skip
dec delay
brne skip
sbi flag, ready
skip:
Дальше Ваша повешенная на таймер задача
reti
Здесь задержка не точная, но если настроить таймер на 2,5 или 1 мС, то будет точнее. Только тогда в байт не вместится секунда. Взять тогда 2 байта.
И не будет ни 11 ни 27 кБ. Может и в тиньку влезет:)
Я всё-всё узнAю и стану профессором.
DrLithium
Открыл глаза
Сообщения: 79
Зарегистрирован: Вт фев 19, 2008 10:14:47
Откуда: SPb

Re: Нужна помощь по написанию функции на АСМе

Сообщение DrLithium »

Стесняюсь спросить, а чем у Вас заняты таймеры?

Дак выше писал, что три таймера зарезервированы за конкретными задачами. Но далеко ещё не всё написано и таймеры берегу для более важных функций.

То есть самый нулевой таймер, выдающий прерывание каждые 10 мС справится и с задержками и с тем, что Вы ещё повесили.

А теперь посмотрите на диаграмме, на какое кол-во событий нужно повесить подобную процедуру и посчитайте кол-во потраченной программной памяти. Одна строчка "DELAY_MS 10", при этом не жрущая память не лучший ли выбор в данном случае? Самое не понятное, почему нужно ждать когда параллельно работающий таймер созреет и после возвращаться в обработчик, при этом крутить нопы в бесконечном цикле или проверять не актуальное в это время?

По проекту: я описал в нём только 5-ь состояний ЛПМ, а сожрано уже 11КБ! 23-и вызова "DELAY_MS" и это только в режимах, а есть и другие места где использовано, считать всё лень. Вы реально предлагаете 23-и раза перезадавать таймеру значения и с ростом числа использования подобного жеста, ещё больше отдавать программную память? Можно написать макрос для таймера, но зачем прыгать из-в с использование таймера, если актуальное место фокуса это обработчик текущего состояния ЛПМ?

Когда упёрся в 27КБ, понял что где-то проблема. Решил её и вот тут решил поделиться решением. А впереди ещё более 6-и режимов, но "хелперы" описаны и реализация алгоритмов состояний (и переходов из-в) не займёт много места.

И не будет ни 11 ни 27 кБ. Может и в тиньку влезет:)

Ни как не влезет. 8 Кб это основной код со всеми накладными расходами, а DELAY не жрёт лишнего. Это только кажется, что 4-КБ за глаза. Я и сам так думал когда писать начинал. 27 КБ был ударом по мозгам! В данном проекте замещается 42-х ногая микруха и 33 пина активны. Состояний и переходов между ними, оказалось многовато. М.б. где-то ещё можно скостить памяти, но в данном проекте я жертвую компактностью в угоду наглядности, универсальности и расширяемости. Будет добавлен USART, ИК-управление и возможно работой с периферией по I²C.

З.Ы. На СИ, я бы давно побежал покупать новый камушек. :))
Если в голове каша, значит ваш котелок варит!
dgrett
Вымогатель припоя
Сообщения: 615
Зарегистрирован: Вс дек 28, 2014 21:54:05

Re: Нужна помощь по написанию функции на АСМе

Сообщение dgrett »

Хоть 100, проверяется в том же прерывании. Ни одного nop’а
Я всё-всё узнAю и стану профессором.
DrLithium
Открыл глаза
Сообщения: 79
Зарегистрирован: Вт фев 19, 2008 10:14:47
Откуда: SPb

Re: Нужна помощь по написанию функции на АСМе

Сообщение DrLithium »

А зачем нам лезть в прерывание? Это в данном случае чем полезно?
Вот последовательность: состояние "Плей", нажата кнопка "перемотка вперёд". Нужно вернуться в состояние стоп: отключить СДИ, задать новое положение программной шестерне, отключить подмотку, а уже после активировать сам режим "перемотка вперёд", со всем жестами. Зачем мне прерывание, если у меня последовательность действий с перерывами (DELAY тут подходит на 100%) по времени и в это же самое время ни на что реагировать не надо?

А в самом прерывании тогда нужно будет проверять... 3X4=12 (и это только на текущий момент) вариантов сценариев. Т.е. обработчик будет не вне прерывания, а внутри? Для чего это?
Если в голове каша, значит ваш котелок варит!
dgrett
Вымогатель припоя
Сообщения: 615
Зарегистрирован: Вс дек 28, 2014 21:54:05

Re: Нужна помощь по написанию функции на АСМе

Сообщение dgrett »

Опять стесняюсь спросить, зачем там у Вас вообще мк нужен?
Я всё-всё узнAю и стану профессором.
Аватара пользователя
Jack_A
Друг Кота
Сообщения: 6307
Зарегистрирован: Вт апр 24, 2007 07:45:40
Откуда: Minsk

Re: Нужна помощь по написанию функции на АСМе

Сообщение Jack_A »

В одном аппаратном таймере несложно сделать несколько виртуальных. Закинул в определённый регистр заданную длительность задержки - и продолжаешь выполнять рабочую программу, периодически посматривая на флаг ЗАДЕРЖКА ОТРАБОТАНА.
Изображение
DrLithium
Открыл глаза
Сообщения: 79
Зарегистрирован: Вт фев 19, 2008 10:14:47
Откуда: SPb

Re: Нужна помощь по написанию функции на АСМе

Сообщение DrLithium »

Опять стесняюсь спросить, зачем там у Вас вообще мк нужен?

Серьёзно? Зачем? Вам юзер мануал скинуть? Набор функций имеющихся на борту, устанете на рассыпухе делать. А размер при этом какой будет? А надёжность? А потребление тока?

Изначально стоит LM6402A, потеря этого МК автоматом ставит крест на ремонте аппарата, т.к. просто их, с этой прошивкой, ни где не достанете, даже за огромные деньги! Не делают и уже очень давно. Реплика нужна в первую очередь, что б решить эту проблему.

В одном аппаратном таймере несложно сделать несколько виртуальных. Закинул в определённый регистр заданную длительность задержки - и продолжаешь выполнять рабочую программу, периодически посматривая на флаг ЗАДЕРЖКА ОТРАБОТАНА.

Вот об этом то и речь, что когда надо сидеть в бесконечном цикле - понято. А вот вопрос, когда не надо там сидеть, что делать? Любому школьнику ясно, что прерывания спасают. Но, если вам это спасение даром не нужно, то где реализация задержки на подобие СИ-шной?
Если в голове каша, значит ваш котелок варит!
dgrett
Вымогатель припоя
Сообщения: 615
Зарегистрирован: Вс дек 28, 2014 21:54:05

Re: Нужна помощь по написанию функции на АСМе

Сообщение dgrett »

{Вам юзер мануал скинуть? }
Может, programming?
{когда надо сидеть в бесконечном цикле}
Вы и так в бесконечном цикле сидите, мк по другому не может.
А вообще, я теперь понимаю, откуда 27кБ.
ПилИте, Шура (с)
Я всё-всё узнAю и стану профессором.
DrLithium
Открыл глаза
Сообщения: 79
Зарегистрирован: Вт фев 19, 2008 10:14:47
Откуда: SPb

Re: Нужна помощь по написанию функции на АСМе

Сообщение DrLithium »

Вы и так в бесконечном цикле сидите, мк по другому не может.
А вообще, я теперь понимаю, откуда 27кБ.

Ну вот началось хамство. Откуда 27КБ было объяснено доступным языком и почему так вышло тоже! Получается взял пример нуба, который ни один профи, вроде вас, причесать не соизволил.
И не сидит МК в бесконечном цикле постоянно - это только у нубов всё просто. У меня прерывается или процедурой или прерыванием! Учите азы, умничать после будете.

Не беспокойтесь, всё уже распилено до вас и без вашей помощи. Вам же давал скрин диаграммы, вы хоть его чуть посмотрели внимательно, что б писать после вот это:
Опять стесняюсь спросить, зачем там у Вас вообще мк нужен?


А вот в вашем кунг-фу я сильно сомневаюсь, особенно после совета запихнуть в прерывание обработчик всего и вся! :shock:
Я так понял вы способны только на умные фразы вроде:
ПилИте, Шура (с)
:facepalm:

Мне тоже цитатами начать крыть? Дельного с вас, как с козла молока. Вам всё объяснил и по полочкам разложил, а вы обиделись, что косяков не нашли. Не стыдно? :sleep:
Если в голове каша, значит ваш котелок варит!
dgrett
Вымогатель припоя
Сообщения: 615
Зарегистрирован: Вс дек 28, 2014 21:54:05

Re: Нужна помощь по написанию функции на АСМе

Сообщение dgrett »

Ах, прости, дядька, засранца. Если стану хамить, у Вас дар речи отнимет.
По делу. Я могу для Вас написать обработчик этой шняги без всяких задержек. Так, как сделал бы себе. Но только не с телефона.
А мк, повторюсь, ВСЕГДА работает в непрерывном цикле. И быть иначе не может.
Я всё-всё узнAю и стану профессором.
DrLithium
Открыл глаза
Сообщения: 79
Зарегистрирован: Вт фев 19, 2008 10:14:47
Откуда: SPb

Re: Нужна помощь по написанию функции на АСМе

Сообщение DrLithium »

у Вас дар речи отнимет.

Вы обо мне ни чего знать не можете. Фантазии на офф!
Я могу для Вас написать обработчик этой шняги без всяких задержек. Так, как сделал бы себе. Но только не с телефона.

Судя по вашим фантазиям, поделка будет так себе. Тем более, вы не справитесь с подобной задачей на должном уровне. Что б вы имели представление, вот вам одна из проблем: переход из перемотки в плей ведёт к потере высоких частот на 3-5 секунд. Что будете делать? Ась? Я-то знаю и решу в ближайшее время, а дилетанты мне ни к чему!
А мк, повторюсь, ВСЕГДА работает в непрерывном цикле. И быть иначе не может.

Да не. Ну правда? Всегда? А что такое прерывания знаете? Или вы мне решили Америку открыть подобным заявлением? Я о бесконечном цикле в МК, узнал ещё в 2008-м году, когда только начал изучать. Удивить меня решили всем известным фактом? Зачем? Ум показать? Кунг-фу знаний? Крутость? Мне это от вас не в какой форме подобного не надо, по вашим вопросам уже сложил впечатление. Тренируйтесь на кошках.
Если в голове каша, значит ваш котелок варит!
Ответить

Вернуться в «AVR»