Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Как сделать задержку?
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Daermon
При работе с АЦП нужны небольшие интервалы? Например 40нс держать RD, или CS... и т.п.
Хочу сделать метод
inline void Wait(unsigned int ns)
{
тут поставить ожидание с пустыми циклами...только не могу точно задать интервал, так как не уверен
за сколько выполнится та или иная операция.



}
Вот параметры кварцев

#define PLLAR 0x2026BF04 //* 179,712000 MHz for PCK
#define PLLBR 0x10483F0E //* 48,054857 MHz (divider by 2 for USB)
#define MCKR 0x00000202 //* PCK/3 = MCK Master Clock = 59,904000MHz with PLLA selected
#define SLOWCLOCK 32768 //* In Hz
#define MAIN_OSC_CLK 18432000 //* In Hz

Есть какие нибудь др способы, точно задать маленькие интервалы задержки? Таймеры с прерываниями не предлагать.
Сергей Борщ
Цитата(Daermon @ Nov 21 2007, 12:40) *
тут поставить ожидание с пустыми циклами...только не могу точно задать интервал, так как не уверен
за сколько выполнится та или иная операция.
Сделайте цикл до миллиона, измерьте получившееся время, поделите на миллион, получите время одной итерации.
Цитата(Daermon @ Nov 21 2007, 12:40) *
Таймеры с прерываниями не предлагать.
А таймеры без прерываний?
sergeeff
Думается:
1. Задержки в 40 ns программно не удастся получить никогда.
2. А что АЦП не сидит на нормальной шине с RD, WR и CS?
Daermon
Цитата(sergeeff @ Nov 21 2007, 23:30) *
Думается:
1. Задержки в 40 ns программно не удастся получить никогда.
2. А что АЦП не сидит на нормальной шине с RD, WR и CS?


Посчитал...запустил вот такой код. (по прерыванию Таймера в 100 микросек инкриментирую
counter +=100)
//*******************************************************************
counter = 0;
Wait(200000000);
sprintf (msg,"\n\r200000000 tacts per %d microseconds\n\r",counter);
Print.PrintString(msg);
while(1) {}

//*******************************************************************
inline void Wait(unsigned int mcs)
{
int cycles = mcs; // 200 MIPS - 200 операций в микросекунду

for(int l=0; l<cycles;l++);
};

получил след результаты:
около 7 секунд - без оптимизации
5,5 секунд с оптимизацией Low
А вот максимальная оптимизация вообще 0 дает...!! почему интересно?



Получается могу задать интервал в 30ns при вызове Wait(1);

Хотя не уверен в верности данного подсчета. Так как таймер влияет на измерения. причем в зависимости от времени срабатывания получаются разные результаты ...

АЦП как раз сидит на шине , а для того чтобы управлять RD, CONVST, A0 сигналами необходимы небольшие задерки...
например держать 125ns A0 для выбора АЦП0 или АЦП1 на микрухе,
30ns для того чтобы держать RD для выбора ChA0 ChB0 .. и т.п.
или 15ns держать CONVST (старт преобразования)

p.s проект IAR4.41a
alexander55
Цитата(Daermon @ Nov 22 2007, 09:37) *
А вот максимальная оптимизация вообще 0 дает...!! почему интересно?

Выкорчевано из программы, как зловредный элемент. biggrin.gif
Вы в этом можете убедиться по листингу.
aaarrr
Цитата(Daermon @ Nov 22 2007, 09:37) *
получил след результаты:
около 7 секунд - без оптимизации
5,5 секунд с оптимизацией Low
А вот максимальная оптимизация вообще 0 дает...!! почему интересно?

Потому что при максимальной оптимизации пустой цикл выбрасывается.

UPD: Уже заметили.

Цитата(Daermon @ Nov 22 2007, 09:37) *
АЦП как раз сидит на шине , а для того чтобы управлять RD, CONVST, A0 сигналами необходимы небольшие задерки...
например держать 125ns A0 для выбора АЦП0 или АЦП1 на микрухе,
30ns для того чтобы держать RD для выбора ChA0 ChB0 .. и т.п.
или 15ns держать CONVST (старт преобразования)

Вы пытаетесь получить задержки сопоставимые с периодом тактового сигнала процессора. Циклы тут не нужны: сама по себе запись в порт PIO займет несколько тактов.
Alex03
Цитата(Daermon @ Nov 22 2007, 11:37) *
for(int l=0; l<cycles;l++);
А вот максимальная оптимизация вообще 0 дает...!! почему интересно?

volatile int i - поможет.

Если длительность можно и больше, а это видимо так, то ИМХО зря не рассматриваете вариант использования (опроса) уже имеющегося таймера. т.е. например есть таймер с инкрементом каждые M нс и пересчётом N тогда примерно так:
Код
wait(uint n)
{
    uint x = get_cur_timer_val();
    n /= M;
    
    while((get_cur_timer_val() - x + N) % N < n)
    {
    }
}


Мог ошибиться, да и упростить можно.
Впрочем для Ваших времён может это и лишнее. smile.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.