Комментарии 19
Я никогда не слышал ничего об AVR, но первый запрос в Гугле avr assembler sleep выдаёт что есть такая интсрукция как SLEEP. Можете сравнить её с вашим подходом?
(это я к тому, что перед реализацией всегда стоит посмотреть есть ли что-то готовое; пустые циклы негативно влияют на энергопотребление, если есть аппаратная возможность задержки, то лучше пользоваться ей)
(это я к тому, что перед реализацией всегда стоит посмотреть есть ли что-то готовое; пустые циклы негативно влияют на энергопотребление, если есть аппаратная возможность задержки, то лучше пользоваться ей)
но с ассемблером ковыряюсь недели 2, и пока не понял, как вынести все это в отдельный модуль, и сделать функцию в нем соответствующую.
Так как вы уже сохраняете все используемые регистры в макросе (push/pop), то можете просто вынести его тело в подпрограмму, передав время в качестве параметра или через стек, или через регистры.
Вообще, по опыту, полезность этой подпрограммы спорная. Если проект пишется на ассемблере, то явно под конкретный МК и под конкретную частоту. Все эти задержки высчитываются один раз на этапе написания, что экономит программную память, а так же работает намного точнее.
Так как вы уже сохраняете все используемые регистры в макросе (push/pop), то можете просто вынести его тело в подпрограмму, передав время в качестве параметра или через стек, или через регистры.
Вообще, по опыту, полезность этой подпрограммы спорная. Если проект пишется на ассемблере, то явно под конкретный МК и под конкретную частоту. Все эти задержки высчитываются один раз на этапе написания, что экономит программную память, а так же работает намного точнее.
Что-то с кодировкой, так предполагаю вы не AVR Studio писали?
Я так понял на 16 MHz оно у вас работает?
микросекунды не делал подсчет (в принципе реализуемо), а вот миллисекунды считает при любой частоте не менее 1,3 MHz
Я так понял на 16 MHz оно у вас работает?
микросекунды не делал подсчет (в принципе реализуемо), а вот миллисекунды считает при любой частоте не менее 1,3 MHz
Макросы занимают во флеше 34,78,198 байт. Суть в том что в 7 местах в коде ставилось по 15-20 NOP, что выглядело, по мне, не очень кошерно (думаю это от избалованности ЯП высоко уровня). При частоте <1,3 MHz не покатит точно, но я писал это в целях получения опыта и естественно на конкретный мк (но в принципе подходит на многие avr), так что если кому понадобится могут допилить под своё)
Но все-таки надо будет сделать в виде подпрограммы, только затраты на вызов посчитать.
Но все-таки надо будет сделать в виде подпрограммы, только затраты на вызов посчитать.
Немного отступая от темы… Никто не замечал что этот самый _delay_ms врёт? притом легко может обмануть где-то процентов на 30. Или это у меня что-то не так.
А разверните эту функцию. Она объявлена где то в .h файлах идущих в поставке вместе со средой программирования от производителя контроллера. Там пустой цикл на нужное количество тактов. Соответственно время задержки будет не точное если есть, например, обработка прерываний.
Мне понравилось такое решение:
из книжки «Практическое программирование микроконтроллеров Atmel AVR на языке ассемблера» Ю. Ревич с. 93-94
delay:
ldi delay2,$01
ldi delay1,$77
ldi delay0,$00 ; $017700 - даст задержку в 50мс при 9.6МГц
loop:
subi delay0,1
sbci delay1,0
sbci delay2,0
brcc loop
из книжки «Практическое программирование микроконтроллеров Atmel AVR на языке ассемблера» Ю. Ревич с. 93-94
Самое чудесное у Вас случится когда такая «чудо функция» окажется внутри обработчика прерываний.
Так что для точных таймингов и забивания головы какие функции можно или нельзя использовать только аппаратный таймер. Благо что в AVR их завались и повесить на него программное прерывание для подсчёта не проблема.
Так что для точных таймингов и забивания головы какие функции можно или нельзя использовать только аппаратный таймер. Благо что в AVR их завались и повесить на него программное прерывание для подсчёта не проблема.
Да не завались, в лучшем случае их три-четыре, а если используется ШИМ, режимы захвата или что-то ещё, то таймеров ой как не хватает.
Но всё же я бы не стал измерять время такой «универсальной» функцией, а реализовал бы алгоритм для конкретной задачи.
Но всё же я бы не стал измерять время такой «универсальной» функцией, а реализовал бы алгоритм для конкретной задачи.
Все три заняты, в том то и вся проблемы. Там на плате вообще весь мк обвешан))
Я ж не на часы программу пишу)
Я ж не на часы программу пишу)
Добрый день!
Ни в коей мере не претендую на профессионализм (контроллеры для меня хобби), однако мне совершенно непонятно, зачем писать для AVR на ассемблере? Если не хватает памяти, купите AVRку помощнее. Неужели все настолько упирается в цену кристаллов и совершенно не учитывается стоимость разработки и поддержки? А по теме, для задержек лучше использовать все же аппаратный таймер + спинлок, даже на ассемблере. Опять же, если не хватает таймеров, поставьте кристалл где таймеров 5 штук, либо используйте 1 таймер для разных задач (например 2 таймера для ШИМ, а третий для всего связанного со временем).
Ни в коей мере не претендую на профессионализм (контроллеры для меня хобби), однако мне совершенно непонятно, зачем писать для AVR на ассемблере? Если не хватает памяти, купите AVRку помощнее. Неужели все настолько упирается в цену кристаллов и совершенно не учитывается стоимость разработки и поддержки? А по теме, для задержек лучше использовать все же аппаратный таймер + спинлок, даже на ассемблере. Опять же, если не хватает таймеров, поставьте кристалл где таймеров 5 штук, либо используйте 1 таймер для разных задач (например 2 таймера для ШИМ, а третий для всего связанного со временем).
В том месте где я работаю всё уперлось в деньги) код на ассемблере по каким-то невиданным причинам (можно было обойтись вставками в Си) писали еще год назад, теперь настало моё время его поддерживать)
3 имеющихся таймера постоянно переинициализируются (2 режима, один для приема другой для передачи), так судя по всему еще и третий режим будет для индикации)
Основная цель заменить имеющиеся вот такие конструкции:
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
на
Ну и просто интересно было реализовать подобное)
3 имеющихся таймера постоянно переинициализируются (2 режима, один для приема другой для передачи), так судя по всему еще и третий режим будет для индикации)
Основная цель заменить имеющиеся вот такие конструкции:
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
на
DELAY_CL 20
Ну и просто интересно было реализовать подобное)
Есть программы, формирующие Assemblerный код под нужную задержку и частоту контроллера.
Есть web приложение AVRDelayCalculator которое формирует Assemblerный код под нужную задержку и частоту контроллера. Интерфейс можно переключить на Русский язык. Адрес страницы.
В поисковике можно найти по названию, название в строке поиска нужно ввести в кавычках.
Будут вопросы, пишите алгоритм проверен годами. Сначала был реализован в виде программы, но потом реализовал как web приложение. Метод рассчёта коэффициентов табличный, поэтому проблем со временем вычисления коэффициентов нет.
Есть web приложение AVRDelayCalculator которое формирует Assemblerный код под нужную задержку и частоту контроллера. Интерфейс можно переключить на Русский язык. Адрес страницы.
В поисковике можно найти по названию, название в строке поиска нужно ввести в кавычках.
Будут вопросы, пишите алгоритм проверен годами. Сначала был реализован в виде программы, но потом реализовал как web приложение. Метод рассчёта коэффициентов табличный, поэтому проблем со временем вычисления коэффициентов нет.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Реализация Задержки в AVR assembler без таймеров