реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Формирование задержки
aspID
сообщение Sep 11 2007, 10:47
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 343
Регистрация: 24-01-07
Из: Новосибирск
Пользователь №: 24 714



На данном этапе некритично, но интересно, как можно формировать задержки длительностью в единицы мкс.

На данный момент используется:
Код
#define _delay_us(x) __delay_cycles(x*F_CPU/1000000)


на частоте
Код
#define F_CPU 3686400UL
просто исполняю следующий код и смотрю за сигналом
Код
  DDRD |= (1 << PD6);
  while (1)
  {
    PORTD |= ( 1 << PD6 );
    _delay_us(5);
    PORTD &= ~( 1 << PD6 );
    _delay_us(1);
  }

на уровне десятков мкс работает нормально, 5 мкс растягиваются до 5,4 мкс а 1 мкс - до 1,85 мкс

Если работать через прерывания таймера - думается мне, обработка не даст большей выгоды. Или я не прав? Как вариант, конечно, увеличивать частоту кварца...
Go to the top of the page
 
+Quote Post
zltigo
сообщение Sep 11 2007, 10:57
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(aspID @ Sep 11 2007, 13:47) *
Если работать через прерывания таймера - думается мне

Если есть таймер, безусловно надо пользоваться им и не маяться дурью с программыми задержками. Только прерывания никчему - просто ожидание в цикле достижения таймером нужного значения. Систематическая погрешность на вызов функции и 'startup' по любому будет присутствовать....

P.S.
Только причем здесь IAR??? Выбирая ветку форума надо подумать...


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
aspID
сообщение Sep 11 2007, 11:06
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 343
Регистрация: 24-01-07
Из: Новосибирск
Пользователь №: 24 714



Цитата(zltigo @ Sep 11 2007, 17:57) *
Если есть таймер, безусловно надо пользоваться им и не маяться дурью с программыми задержками. Только прерывания никчему - просто ожидание в цикле достижения таймером нужного значения.

А какже время на установку регистров и обработку значений таймера? На единицах микросекунд оно уже будет давать свой "осадок"... unsure.gif

Цитата
Только причем здесь IAR??? Выбирая ветку форума надо подумать...

Подумал и пришел к выводу, что непосредственно к МК AVR оно имеет равное отношение как и к IAR. Стареет логика? Sorry, просьба переместить...

Сообщение отредактировал aspID - Sep 11 2007, 11:08
Go to the top of the page
 
+Quote Post
alexander55
сообщение Sep 11 2007, 11:19
Сообщение #4


Бывалый
*****

Группа: Свой
Сообщений: 1 584
Регистрация: 7-08-07
Пользователь №: 29 615



Цитата(aspID @ Sep 11 2007, 15:06) *
А какже время на установку регистров и обработку значений таймера? На единицах микросекунд оно уже будет давать свой "осадок"... unsure.gif
Подумал и пришел к выводу, что непосредственно к МК AVR оно имеет равное отношение как и к IAR. Стареет логика? Sorry, просьба переместить...

Судя по первому сообщению, Вы работаете с AVR. задайте вопрос там.
Коротко.
Прерывание при малых задержках бред.
Насчет точности абстрактный пример.
Прибор имеет 100 делений класс 5, т.е 5 %.
При полной шкале, 100 делений - ошибка 5%, т.е. 5 делений.
При 50 -10%, т.е. 5 делений.
При 10 -50%, т.е. 5 делений.
При 5 -100%, т.е. 5 делений.
При 1 -500%, т.е. 5 делений.
Мораль - измерение малых величин некорректно.
Go to the top of the page
 
+Quote Post
aspID
сообщение Sep 11 2007, 16:36
Сообщение #5


Местный
***

Группа: Свой
Сообщений: 343
Регистрация: 24-01-07
Из: Новосибирск
Пользователь №: 24 714



Цитата
Мораль - измерение малых величин некорректно

Хотите сказать, что наны вообще нереально использовать? Или кварца в 3,6864МГц для микросекунд мало??

Цитата
Прерывание при малых задержках бред.

Это все-таки к чему? К тому, что следует перейти на таймер или все же оставаться на макросе?

Просто с конкретным случаем - "использование макроса" я проверил работу, а со случаем "использование таймера" не заморачивался. Наверняка не я первый, не я последний задался этим вопросом...
Go to the top of the page
 
+Quote Post
bodja74
сообщение Sep 11 2007, 16:46
Сообщение #6


Знающий
****

Группа: Свой
Сообщений: 543
Регистрация: 22-10-05
Пользователь №: 9 984



Мораль очень проста smile.gif
1 микросекунда - это почти 4 такта ядра,а точнее 3.6864 smile.gif при частоте 3,6864МГц
Возможно четыре NOP спасут отца русской демократии ,если устроит такая точность smile.gif
Go to the top of the page
 
+Quote Post
AndreyKeil
сообщение Sep 11 2007, 17:03
Сообщение #7


Частый гость
**

Группа: Свой
Сообщений: 96
Регистрация: 16-11-05
Из: г.Екатеринбург
Пользователь №: 10 930



На вашем месте я бы сделал так:


#define F_CPU 0.277778 //это равно 1/3.686400
//while (1) {
// PORTD|= (1 << 6);

XX0: SBI 0x12, 0x06
// __delay_cycles(5/F_CPU);
LDI R16, 5
XX1: DEC R16
BRNE XX1
RJMP XX2
// PORTD&= ~(1 << 6);
XX2: CBI 0x12, 0x06
// __delay_cycles(1/F_CPU-3); //...-3 это поправка(количество циклов)
RJMP XX0
}

В симуляторе получилось 5,15 и 1,09 мкс. smile.gif

А если хотите получить точно 5 и 1 мкс то надо взять кварц кратный 1МГц (допустим 10МГц).
Ну и ещё как вариант, использовать ассемблер.
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Sep 11 2007, 17:07
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Мораль такова что IAR максимально точно генерит задержку, но, естественно, она должна быть кратна целому числу тактов процессора. Так как не существует команды выполняющейся за пол такта. Соответственно 5мкс/1/3.6864 = 5*3.6864 = 18.432 что соответствует 18 тактам. 18/3.6864=4.88мкс

Вероятно вы вставили операцию работы с портом с двух сторон чтобы замерить это это добавило ещё 2 такта 20/3.6864 = 5.425мкс - что полностью соотносится с увиденным
Go to the top of the page
 
+Quote Post
ReAl
сообщение Sep 11 2007, 18:48
Сообщение #9


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(SasaVitebsk @ Sep 11 2007, 19:07) *
Мораль такова что IAR максимально точно генерит задержку, но, естественно, она должна быть кратна целому числу тактов процессора. Так как не существует команды выполняющейся за пол такта. Соответственно 5мкс/1/3.6864 = 5*3.6864 = 18.432 что соответствует 18 тактам. 18/3.6864=4.88мкс
Вероятно вы вставили операцию работы с портом с двух сторон чтобы замерить это это добавило ещё 2 такта 20/3.6864 = 5.425мкс - что полностью соотносится с увиденным

А учитывая то, что задержка почти наверняка генерируется при помощи чего-то подобного
Код
    ldi r16, some_constant
L1:
    dec r16
    brne L1

время вообще кратно не одному, а трём целым тактам (тут с 18-ю просто повезло).
Для 1мкс some_constant = 1, три такта на этом "цикле", два такта на rjmp к началу while(1) и два такта на sbi, в которое превратилось PORTD |= ( 1 << PD6 ); - итого семь тактов, 1,9мкс - так что всё на месте.


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Sep 11 2007, 21:39
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Цитата(ReAl @ Sep 11 2007, 21:48) *
А учитывая то, что задержка почти наверняка генерируется при помощи чего-то подобного
Код
    ldi r16, some_constant
L1:
    dec r16
    brne L1

время вообще кратно не одному, а трём целым тактам (тут с 18-ю просто повезло).
Для 1мкс some_constant = 1, три такта на этом "цикле", два такта на rjmp к началу while(1) и два такта на sbi, в которое превратилось PORTD |= ( 1 << PD6 ); - итого семь тактов, 1,9мкс - так что всё на месте.


Нет. Задержка генерируется точно согласно алгоритму и выравнивается с точностью до такта.

То есть если вы закажите 2 такта, то будет
rjmp pc+1
если 3
rjmp pc+1
nop
если значительное, то вызов процедуры с заданием параметра + выравнивание недостающих тактов.
Go to the top of the page
 
+Quote Post
defunct
сообщение Sep 11 2007, 22:28
Сообщение #11


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата
Это все-таки к чему? К тому, что следует перейти на таймер или все же оставаться на макросе?

К тому что на практике в МК не нужны короткие задержки.
Использовать таймер для более менее нормальных задержек (от единиц ms с тактовой >8Mhz).

Там где нельзя отказаться от коротких задержек - надо правильно подбирать чип и кварц - не megaXXX на 3.68Mhz, а tinyXXX на 16.000Mhz, 20.000Mhz. чтоб микросекунда получалась целым числом тактов, и чтоб тактов в микросекунде получалось как можно больше. Программу писать не на Си, а на asm. Как правило, там где могут понадобиться очень короткие задержки, там будет очень короткая и тупая программа (за очень редким исключением).
Go to the top of the page
 
+Quote Post
aspID
сообщение Sep 12 2007, 03:47
Сообщение #12


Местный
***

Группа: Свой
Сообщений: 343
Регистрация: 24-01-07
Из: Новосибирск
Пользователь №: 24 714



Большое спасибо отозвавшимся. Намотал на ус :-)
Измерял время с помощью осциллографа, а кварц "некратный" был выбран "кратным" для возможности работы с USART на 115200. smile.gif

З.Ы. чип tiny2313
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 12:44
Рейтинг@Mail.ru


Страница сгенерированна за 0.01497 секунд с 7
ELECTRONIX ©2004-2016