|
|
  |
Формирование задержки |
|
|
|
Sep 11 2007, 10:47
|

Местный
  
Группа: Свой
Сообщений: 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 мкс Если работать через прерывания таймера - думается мне, обработка не даст большей выгоды. Или я не прав? Как вариант, конечно, увеличивать частоту кварца...
|
|
|
|
|
Sep 11 2007, 10:57
|

Гуру
     
Группа: Свой
Сообщений: 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
|
|
|
|
|
Sep 11 2007, 11:06
|

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

|
Цитата(zltigo @ Sep 11 2007, 17:57)  Если есть таймер, безусловно надо пользоваться им и не маяться дурью с программыми задержками. Только прерывания никчему - просто ожидание в цикле достижения таймером нужного значения. А какже время на установку регистров и обработку значений таймера? На единицах микросекунд оно уже будет давать свой "осадок"...  Цитата Только причем здесь IAR??? Выбирая ветку форума надо подумать... Подумал и пришел к выводу, что непосредственно к МК AVR оно имеет равное отношение как и к IAR. Стареет логика? Sorry, просьба переместить...
Сообщение отредактировал aspID - Sep 11 2007, 11:08
|
|
|
|
|
Sep 11 2007, 11:19
|
Бывалый
    
Группа: Свой
Сообщений: 1 584
Регистрация: 7-08-07
Пользователь №: 29 615

|
Цитата(aspID @ Sep 11 2007, 15:06)  А какже время на установку регистров и обработку значений таймера? На единицах микросекунд оно уже будет давать свой "осадок"...  Подумал и пришел к выводу, что непосредственно к МК AVR оно имеет равное отношение как и к IAR. Стареет логика? Sorry, просьба переместить... Судя по первому сообщению, Вы работаете с AVR. задайте вопрос там. Коротко. Прерывание при малых задержках бред. Насчет точности абстрактный пример. Прибор имеет 100 делений класс 5, т.е 5 %. При полной шкале, 100 делений - ошибка 5%, т.е. 5 делений. При 50 -10%, т.е. 5 делений. При 10 -50%, т.е. 5 делений. При 5 -100%, т.е. 5 делений. При 1 -500%, т.е. 5 делений. Мораль - измерение малых величин некорректно.
|
|
|
|
|
Sep 11 2007, 16:36
|

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

|
Цитата Мораль - измерение малых величин некорректно Хотите сказать, что наны вообще нереально использовать? Или кварца в 3,6864МГц для микросекунд мало?? Цитата Прерывание при малых задержках бред. Это все-таки к чему? К тому, что следует перейти на таймер или все же оставаться на макросе? Просто с конкретным случаем - "использование макроса" я проверил работу, а со случаем "использование таймера" не заморачивался. Наверняка не я первый, не я последний задался этим вопросом...
|
|
|
|
|
Sep 11 2007, 17:03
|
Частый гость
 
Группа: Свой
Сообщений: 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 мкс.  А если хотите получить точно 5 и 1 мкс то надо взять кварц кратный 1МГц (допустим 10МГц). Ну и ещё как вариант, использовать ассемблер.
|
|
|
|
|
Sep 11 2007, 18:48
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 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мкс - так что всё на месте.
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
Sep 11 2007, 21:39
|
Гуру
     
Группа: Свой
Сообщений: 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 если значительное, то вызов процедуры с заданием параметра + выравнивание недостающих тактов.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|