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

 
 
 
Reply to this topicStart new topic
> Функция задержки
алексей500
сообщение Jun 19 2010, 23:10
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 43
Регистрация: 22-05-10
Пользователь №: 57 445



А не подскажите, как реализовать функцию задержки в микросекундах, ну или в тактах, без таймера и прерываний? Нашёл на форуме вот такое:



Код
volatile unsigned int x = us * 12;

while(--x);




Только это был ответ на:

Цитата
Никто не поделиться кодом, который делает задежку в микросекундах без таймеров, а так просто с помощью нупов или циклом для частоты 48 Мгц???



А для произвольной частоты это можно организовать? Пишу в IAR. Контроллер AT91SAM7A3.
Заранее спасибо.
Go to the top of the page
 
+Quote Post
SSerge
сообщение Jun 20 2010, 01:01
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 719
Регистрация: 13-09-05
Из: Novosibirsk
Пользователь №: 8 528



Уже сделано. У IAR есть встроенная (intrinsic) функция
__delay_cycles(unsigned long int);


--------------------
Russia est omnis divisa in partes octo.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jun 20 2010, 07:36
Сообщение #3


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(SSerge @ Jun 20 2010, 04:01) *
Уже сделано. У IAR есть встроенная (intrinsic) функция
__delay_cycles(unsigned long int);
Нету такой функции в IAR для ARM. Потому что время исполнения одной команды и участка кода рассчитать гораздо сложнее, чем на AVR, исходя из настроек всяких кешей, ускорителей флеши да и просто из места расположения команды (внутренее/внешнее ОЗУ / внутренняя/внешняя флеш).
алексей500 - возьмите осциллограф, подергайте ногой перед и после такого цикла и подберите. Рассчитать его точно невозможно по указанным выше причинам. Да еще и результат компиляции такого цикла может быть разным для разных уровней оптимизации и разных версий компилятора.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
алексей500
сообщение Jun 20 2010, 10:40
Сообщение #4


Участник
*

Группа: Участник
Сообщений: 43
Регистрация: 22-05-10
Пользователь №: 57 445



Ок, спасибо, попробуем.
Go to the top of the page
 
+Quote Post
defunct
сообщение Jun 22 2010, 01:58
Сообщение #5


кекс
******

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



Цитата(Сергей Борщ @ Jun 20 2010, 10:36) *
Да еще и результат компиляции такого цикла может быть разным для разных уровней оптимизации и разных версий компилятора.

Если в системе есть тикающий таймер, который работает на частоте проца, то совсем нечего делать.
delay_us( ) сведется к
{
unsigned StartTime = *TIMER_CURR;
while( *TIMER_CURR - StartTime < n);
}

Если нет, то ассемблер ведь имеется.... а значит все не так уж скверно.
Пишем и размещаем где угодно

Код
__asm void delay_cycles(unsigned n)
{
do_wait
    DEC      r0
    BNE      do_wait
    BX       lr
}


Затем калибруем для получения "delay_us".
Как сделать. Ну напр так, при инициализации:

1. запустить таймер с частотой PCLK (где PCLK - при возможности сделать равной MCLK - частоте проца)
2. выполнить 1000 раз delay_cycles( n ), где n - число больше 0 но не больше чем частота MCLK / Mhz / 3
3. прочитать таймер, получить число тактов "Ticks" начиная со старта теста.
4. посчитать реальное время Tmks (в микросекундах) затраченное на 1000 пусков delay_cycles( n ), как Ticks * 10^6 / PCLK.
5. раcсчитать реальное Ncycles с которым необходимо запускать delay_cycles( Ncycles) чтобы получить задержку в 1us, по простой пропорции:

Ncycles = n * 1000 / Tmks

6. Проверить точность Ncycles (проходом с п.1 по п.4)
7. ну и подкрутить delay_cycles() парочкой NOP'ов если потребуется.
Go to the top of the page
 
+Quote Post
aspID
сообщение May 22 2012, 08:37
Сообщение #6


Местный
***

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



Позвольте подниму эту тему из далекого забытого прошлого...

До недавнего времени для создания задержек пользовался макроподстановками (кстати, найденными здесь же)

Код
#ifndef F_CPU
# warning "F_CPU not defined for delay.h, using 1MHz"
# warning "To define F_CPU go Proj->Opt->C/C++->Defined symbols"
# define F_CPU 1000000UL
#endif

#define _delay_ns(x) __delay_cycles(x*F_CPU/1000000000)
#define _delay_us(x) __delay_cycles(x*F_CPU/1000000)
#define _delay_ms(x) __delay_cycles(x*F_CPU/1000)
#define _delay_s(x) __delay_cycles(x*F_CPU)


Но внимательно изучая на досуге IAR C/C++ Compiler Reference Guide нашел там следующее:
Цитата
Description Makes the compiler generate code that takes the given amount of cycles to perform, that
is, it inserts a time delay that lasts the specified number of cycles.
The specified value must be a constant integer expression and not an expression that is
evaluated at runtime
.

Вот я и позадумался... а правильно ли так использовать?
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение May 22 2012, 09:35
Сообщение #7


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Если в качестве x вы подставляете константу, то и все выражение может быть вычисленно на этапе компиляции и компилятор может вставить код задержки на нужное количество циклов. Если в качестве x вы подставите переменную - компилятор выругается и компилировать откажется.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
aspID
сообщение May 22 2012, 09:37
Сообщение #8


Местный
***

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



Цитата(Сергей Борщ @ May 22 2012, 16:35) *
Если в качестве x вы подставляете константу, то и все выражение может быть вычисленно на этапе компиляции и компилятор может вставить код задержки на нужное количество циклов. Если в качестве x вы подставите переменную - компилятор выругается и компилировать откажется.

Понял, спасибо.
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 2nd July 2025 - 06:37
Рейтинг@Mail.ru


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