roboforum.ru

Технический форум по робототехнике.

cvAVR - delay_us(переменная) - можно?

Программирование микроконтроллеров AVR, PIC, ARM.
Разработка и изготовление печатных плат для модулей.

cvAVR - delay_us(переменная) - можно?

Сообщение sky-walker » 20 окт 2012, 00:03

Всем привет!

Возникла простейшая задача... Необходимо сделать паузу от 1000 до 2000мкс, функция delay_us не позволяет использовать переменную... Если делать типа for(i=0; i<count; i++){ delay_us(1); } - появляется лишняя задержка, и немалая (если i - unsigned short, то накидывается 1,5мс для задержки 1мс...). С циклом с #asm("nop"); - та же байда.

Как решить?
Аватара пользователя
sky-walker
 
Сообщения: 40
Зарегистрирован: 29 сен 2012, 14:41
прог. языки: C\C++, AutoIt, PHP

Re: cvAVR - delay_us(переменная) - можно?

Сообщение Angel71 » 20 окт 2012, 00:29

что там "накидывается" зависит как минимум от частоты и какой код компилятор сгенерит. на асме у вас "байда" только потому, что в коде накосячили. ищите по форуму, обсуждалось и не раз (третий раз уже про поиск, упс). это если лень разбираться как работает delay_us. +в зависимости от задачи таймеры могут оказаться намного более уместными. если совсем лень, до цикла расчитываете на сколько нужно count уменьшить. или прикидываете какой минимальный шаг задержек. допустим 100мкс, тогда в цикле вызываете не delayus(100), а delayus(60) или delayus(35) или delayus(70). сколько именно в нём писать считайте за ранее под конкретную частоту и настройки компилятора.
Аватара пользователя
Angel71
 
Сообщения: 10668
Зарегистрирован: 18 апр 2009, 22:18
Предупреждения: -1

Re: cvAVR - delay_us(переменная) - можно?

Сообщение boez » 20 окт 2012, 12:27

Я подозреваю, что автору нужна дискретность в 1-2 мкс, судя по величине задержки :)
Делай на таймере, иначе будет дрожать наверняка. Ну или открывай .h-файл с функцией delay_ms, смотри по какой формуле там считается количество циклов и как устроена сама функция задержки - и делай такую же, но со своим пересчетом (обычно delay_us использует арифметику с плавающей точкой для расчета, но расчет делает компилятор - поэтому и нельзя использовать переменные, а ты сделай такой же расчет, но в целых числах и во время выполнения, на самой АВРке).
boez
 
Сообщения: 1981
Зарегистрирован: 27 авг 2008, 10:45
Откуда: Харьков
прог. языки: С/С++

Re: cvAVR - delay_us(переменная) - можно?

Сообщение sky-walker » 20 окт 2012, 13:05

boez,
Да, ошибка на 1-2мкс - вполне допустима, но желательно не более.
Спасибо за идею и объяснение, буду пробовать переделать delay_us (gjxtve не таймер, см. ниже)

Angel71,
компилятор указан в теме, частота 8МГц (забыл указать), мк мега8. На асме ошибки в коде быть не может, ибо в строчке for(i=0; i<1500*8; i++){#asm("nop");} ошибиться ну просто негде. И если Вы думаете, что в поиск я не ходил (к тому же еще и 3раза) - то это заблуждение. Перед созданием темы я Яндексю (не менеее 3-5страниц и 3-5 формулировок) и по форуму ищу - кроме таймера ничего не находилось.

Идею с таймером видел, но сделать неудобно, потому что данный код и так вызывается в прерывании TIM1_CAPT + тикает TIM0. Вешать на TIM2 - значит для покрытия диапазона нужно ставить предделитель 64 => возможна 8мкс задержка (если я считаю верно), а это уже нехорошо... + часть кода надо будет перекидывать в другое прерывание, а он уже и так нечитабельный.... Переписал под WinAVR (там _delay_us может принимать переменные), но ошибка огромная (протеус вместо 2000 показал 2114мкс)

Пауза нужна для создания импульса заданной (1000-2000мкс) длины.
Аватара пользователя
sky-walker
 
Сообщения: 40
Зарегистрирован: 29 сен 2012, 14:41
прог. языки: C\C++, AutoIt, PHP

Re: cvAVR - delay_us(переменная) - можно?

Сообщение boez » 20 окт 2012, 13:38

На WinAVR при использовании переменных тянется плавающая точка в АВР - объем прошивки не смутил? :)
И самое главное - не надо в прерывании делать delay_us(1000). Очень это нехорошо и неправильно. Надо переписать управление таймером так, чтобы он считал сам. Т.е. попали первый раз в прерывание - посмотрели, что флаг сброшен, поставили его и задали таймеру считать 1000-2000 мкс. Досчитал, опять попал в прерывание - посмотрели что флаг стоит, сняли его, поставили таймеру считать 18000-19000 мкс (дополнение предыдущего до 20 мс). И так все время. Надо несколько импульсов на разные выходы - флаг делаем не бинарный а число. 1-первый импульс, 2-второй, 3-третий, 0-пауза. Пауза равна 20000 минус сумма импульсов. Идея ясна?
boez
 
Сообщения: 1981
Зарегистрирован: 27 авг 2008, 10:45
Откуда: Харьков
прог. языки: С/С++

Re: cvAVR - delay_us(переменная) - можно?

Сообщение Romikgy » 20 окт 2012, 14:33

Таймер первый имеет 16 битный счетчик можно на нем сделать такую задержку
die Wahrheit ist irgendwo da draußen
Аватара пользователя
Romikgy
 
Сообщения: 750
Зарегистрирован: 15 ноя 2009, 13:37
Откуда: Porto Franco "Odessa"

Re: cvAVR - delay_us(переменная) - можно?

Сообщение sky-walker » 20 окт 2012, 15:27

Romikgy,
Я знаю, но он уже задействован... Я с его помощью считаю длину входящего импульса. Наверно, можно в его же прерывании перенастраивать и заново запускать его, но не знаю... Надо попробовать...

boez,
Смутил, и смущает все время работы. Теперь буду знать причину...
Идею уловил. Смущает одно: вы форумный экстрасенс? :) Я ведь не говорил про несколько выходных каналов и период в 20мс... Чувствую, Вы догадались ).
Вечером обязательно попробую реализовать. (днем как-то тяжко пишется под АВР...)
Аватара пользователя
sky-walker
 
Сообщения: 40
Зарегистрирован: 29 сен 2012, 14:41
прог. языки: C\C++, AutoIt, PHP

Re: cvAVR - delay_us(переменная) - можно?

Сообщение Angel71 » 20 окт 2012, 16:14

sky-walker, и что с того, что в заголовке указано cvavr? вы смысл не улавливаете, ладно, проехали.
На асме ошибки в коде быть не может, ибо в строчке for(i=0; i<1500*8; i++){#asm("nop");} ошибиться ну просто негде.

:) да ладно? на асме только один ноп. т.е. по вашему этот цикл на 12000 итераций должен был 12000 тактов проца проработать? вау! гляньте тогда в асм листинг, узнаете много нового. потом гляньте за сколько тактов каждая инструкция выполняется.
Аватара пользователя
Angel71
 
Сообщения: 10668
Зарегистрирован: 18 апр 2009, 22:18
Предупреждения: -1

Re: cvAVR - delay_us(переменная) - можно?

Сообщение sky-walker » 20 окт 2012, 16:28

Ну я асма не знаю, я ведь сказал только про строчку #asm("nop"); - а так пишется в Си. И цикл я делаю на Си (иначе в кавычках было бы другое выражение, так ведь?)

Смысл я уловил как раз, но реализовать на чистом асме и вставить вместо цикла я не могу (см. выше). Если Вы покажете решение этой проблемы на асме, который будет работать так, как надо, буду очень Вам признателен...
Аватара пользователя
sky-walker
 
Сообщения: 40
Зарегистрирован: 29 сен 2012, 14:41
прог. языки: C\C++, AutoIt, PHP

Re: cvAVR - delay_us(переменная) - можно?

Сообщение Angel71 » 20 окт 2012, 17:02

http://dfe.petrsu.ru/koi/posob/avrlab/avrasm-rus.htm, http://roboforum.ru/forum2/topic4705.html теперь знаете.
и что вам даст кусок кода? тупо запихаете его в программу и даже не попытавшись хоть немного въехать в базовые вещи галопом поскачите дальше? а в следующие разы в подобной ситуации опять и опять будете код просить? про циклы вам уже в другой теме писали. тут вы всё поняли и в коде на асме "ошибиться просто негде". на асме да, не ошиблись, зато сишный обсес просто улыбает. выше приводился ленивый вариант решения
Angel71 писал(а):до цикла расчитываете на сколько нужно count уменьшить. или прикидываете какой минимальный шаг задержек. допустим 100мкс, тогда в цикле вызываете не delayus(100), а delayus(60) или delayus(35) или delayus(70). сколько именно в нём писать считайте заранее под конкретную частоту и настройки компилятора.

не очень хорошее решение, но ленивый вариант на то и ленивый. значит нужно было ещё точно такой же вариант упомянуть с использованием nop? т.е. "Смысл я уловил как раз", но, т.к. на самом деле ничего не поняли, вам нужно одну и туже идею каждый раз под новым соусом подсовывать? так что с готовыми кусками кода это не ко мне. ищите "управление сервами", на вики там даже примерчки с 4мя вариантами есть. как реализовать управление кучей серв так же давно разжёвано.
Аватара пользователя
Angel71
 
Сообщения: 10668
Зарегистрирован: 18 апр 2009, 22:18
Предупреждения: -1

Re: cvAVR - delay_us(переменная) - можно?

Сообщение sky-walker » 20 окт 2012, 18:26

Мда... Я понял Вашу идею сразу, ну не могу я писать так как Вы показали в ленивом варианте, Ошибка задержки должна быть как можно меньше... Я еще после первого поста boez отказался от идеи цикла (и все же интересно - что Вас улыбает в моем "сишном обсесе"?). Кода я не прошу, мне просто было интересна реализация на асме, а вникать ради этого в asm не хотелось (и не хочется, я приверженец С++ во всем).
Как управлять сервами через таймеры я видел, но мне это не подходит, т.к. оный занят.
И еще небольшая просьба: выделяйте, пожалуйста, поконкретнее начала предложений и разбивайте слишком длинные на несколько коротких, читать ваши посты иногда довольно затруднительно...
И кстати, спасибо за ссылки в справочник asm - я бы их в жизни не нашел бы, я ж искать не умею, к тому же и непонятливый...
Аватара пользователя
sky-walker
 
Сообщения: 40
Зарегистрирован: 29 сен 2012, 14:41
прог. языки: C\C++, AutoIt, PHP

Re: cvAVR - delay_us(переменная) - можно?

Сообщение Angel71 » 20 окт 2012, 18:51

если поняли, почему вместо 2114 у вас не 2000 +- пара мкс? ~900 тактов это наверно проц в булошную бегал, аха. не знаете вы ни си, ни тем более си++, у вас только приверженость к названию. знать как правильно записать какую-то конструкцию не то же самое, что понимать как это работает. хотя бы поверхностное знание асма и уменее посмотреть какой код компилятор генерирует и понимать как вообще работает мк, избавляет от кучи банальных ошибок.
cat.jpg

так что не вникайте. правильно, а накой? у вас же не критический к времени исполнения кусок кода, а хня какая-то, для которой единообразной сколько будет работать. для сферической ситуации то, что таймер под что-то уже задействован совершенно не означает, что использовать ещё под что-то нет никакой возможности. как не означает и обратное.
главное, что меня компилятор понимает и программы работают именно так, как и задумывалось. :) все эти выделения и разбивки лирика. :pardon: не нравиться или не способны понять (только после поста boez, т.е. со всторого раза о таймере задумались), не буду для вас ничего писать. всё очень просто :) тыц по "добавить в чс" и ваши сообщения уже не показывает.
Аватара пользователя
Angel71
 
Сообщения: 10668
Зарегистрирован: 18 апр 2009, 22:18
Предупреждения: -1


Вернуться в Микроконтроллеры

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1