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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Как сделать времевую задержку в AVR без таймера
Student2
сообщение Aug 9 2009, 10:42
Сообщение #1


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

Группа: Участник
Сообщений: 83
Регистрация: 4-08-09
Из: Болгария / София
Пользователь №: 51 737



Хочу сделать переменную задержку без използование таймера с резолюцию 1 или 2 цикла.

То что сделал выглядить так:

CODE
#pragma inline=forced
#pragma optimize=s 9 /* this switches the maximum speed optimization for this function only */
void delay(uint8_t delatTime) /* delay routine */
/*------------------------------------------------------ */
{
if(delatTime> TIME_0) /* we do delay on base on the dwell time */
{ /* no branch - 2 clock cycles to this point */
if(delatTime> TIME_1)
{ /* no branch - 4 clock cycles to this point */
if(delatTime> TIME_2)
{ /* no branch - 6 clock cycles to this point */
if(delatTime> TIME_3)
{ /* no branch - 8 clock cycles to this point */
if(delatTime> TIME_4)
{ /* no branch - 10 clock cycles to this point */
if(delatTime> TIME_5)
{ /* no branch - 12 clock cycles to this point */
if(delatTime> TIME_6)
{ /* no branch - 14 clock cycles to this point */
if(delatTime> TIME_7)
{ /* no branch - 16 clock cycles to this point */
if(delatTime> TIME_8)
{ /* no branch - 18 clock cycles to this point */
if(delatTime> TIME_9)
{ /* no branch - 20 clock cycles to this point */
if(delatTime> TIME_10)
{ /* no branch - 22 clock cycles to this point */
__delay_cycles(2);
}
}
}
}
}
}
}
}
}
}
}
}


Я думаю что задержка с резолюции из одного цикла можно сделать с lookup table но не могу понять как ее построить в IAR.

Буду благодарен если поделитесь как Вы делаете задержки без използование таймера.
Go to the top of the page
 
+Quote Post
izerg
сообщение Aug 9 2009, 12:45
Сообщение #2


Знающий
****

Группа: Свой
Сообщений: 531
Регистрация: 1-02-05
Из: Украина, Киев
Пользователь №: 2 342



Цитата(Student2 @ Aug 9 2009, 13:42) *
Я думаю что задержка с резолюции из одного цикла можно сделать с lookup table но не могу понять как ее построить в IAR.



__delay_cycles(unsigned long int);
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.

Note: The specified value must be a constant integer expression and not an expression that is evaluated at runtime.

Цитата из справочника IAR.
Чем не устраивает delay_cycles?
Go to the top of the page
 
+Quote Post
Student2
сообщение Aug 9 2009, 13:02
Сообщение #3


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

Группа: Участник
Сообщений: 83
Регистрация: 4-08-09
Из: Болгария / София
Пользователь №: 51 737



Цитата(izerg @ Aug 9 2009, 15:45) *
__delay_cycles(unsigned long int);
Цитата из справочника IAR.
Чем не устраивает delay_cycles?


Меня устраивает если задержка работатет на переменная (var). К сожалению если поставить переменная в __delay_cycles() и компилатор начинает глючить:
Код
Fatal Error[Ta030]: Argument to __delay_cycles must be a constant expression.
Go to the top of the page
 
+Quote Post
Student2
сообщение Aug 10 2009, 08:06
Сообщение #4


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

Группа: Участник
Сообщений: 83
Регистрация: 4-08-09
Из: Болгария / София
Пользователь №: 51 737



Я увидел что IAR for TI имеет ключевое слово __even_in_range которое может использоваться в сочетание с switch() для создание очень эффективные lookup JUMP таблицы.

Вопрос - как можно создать такую JUMP lookup таблицу в IAR AVR?
Go to the top of the page
 
+Quote Post
izerg
сообщение Aug 10 2009, 10:03
Сообщение #5


Знающий
****

Группа: Свой
Сообщений: 531
Регистрация: 1-02-05
Из: Украина, Киев
Пользователь №: 2 342



Приведите пример кода, в котором хотите использовать такую задержку.
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Aug 10 2009, 10:17
Сообщение #6


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Код
void Pause(unsigned int volatile mks)
{
    while(mks--);
}

Правда, такую конструкцию оптимизатор может "оптимизировать" в ноль, поэтому лучше вставить инлайн-ассемблер и написать именно то, что нужно, в т.ч. с точностью до тактов
Если память не изменяет, в инструкции к ИАРу именно так и советуется поступать. И даже пример есть.


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
Goodefine
сообщение Aug 10 2009, 10:17
Сообщение #7


Местный
***

Группа: Свой
Сообщений: 211
Регистрация: 6-08-07
Из: Приднестровье, Тирасполь
Пользователь №: 29 581



Можно как то так:
Код
#define TICK 2
...
void delay_variable(uint8 tick)
{
     for(uint8 i=tick;i;i--) __delay_cycles(TICK);
}
...
delay_variable(x);


--------------------
Любой, заслуживающий внимания, опыт приобретается себе в убыток...
Go to the top of the page
 
+Quote Post
Палыч
сообщение Aug 10 2009, 11:05
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(Student2 @ Aug 10 2009, 11:06) *
Вопрос - как можно создать такую JUMP lookup таблицу в IAR AVR?
Этот вопрос, наверное, перекликается с Вашим вопросом http://electronix.ru/forum/index.php?showtopic=66032

Вы хотите с помощью этой таблицы формировать задержки? Если -так, то, наверное, необходимо написать на ассемблере, что-то типа этого:
Код
my_delay:
        ldi   r30, low (Label/2)
        ldi   r31, high (Label/2)
        add   r30, r16
        adc   r31, r17
        ijmp
Label:
        nop
        nop
........................
        nop
        nop
        ret
Go to the top of the page
 
+Quote Post
Student2
сообщение Aug 10 2009, 11:20
Сообщение #9


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

Группа: Участник
Сообщений: 83
Регистрация: 4-08-09
Из: Болгария / София
Пользователь №: 51 737



Цитата(Палыч @ Aug 10 2009, 14:05) *
Этот вопрос, наверное, перекликается с Вашим вопросом http://electronix.ru/forum/index.php?showtopic=66032


Спасибо за идею. Вопрос об "Как сделать времевую задержку в AVR без таймера" конечно имеет много общего с новый пост, но акцент сейчас к табличное описание lookup таблицу. В общем таблицу можно использовать для множество других приложений и конечно одно из них - задержка).

Что будеть если директно увеличить PC как делает __even_in_range ? Увидел что в AVR документации нет описание где находиться PC (program copunter) регистер.

Сообщение отредактировал Student2 - Aug 10 2009, 11:43
Go to the top of the page
 
+Quote Post
Student2
сообщение Aug 10 2009, 11:29
Сообщение #10


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

Группа: Участник
Сообщений: 83
Регистрация: 4-08-09
Из: Болгария / София
Пользователь №: 51 737



Цитата(izerg @ Aug 10 2009, 13:03) *
Приведите пример кода, в котором хотите использовать такую задержку.


Хочу установить pinState в 1 для 1, 2.... 7 cycles и потом возвратить в высокоимпедансное состояние

goto($ + delay); /* pseudocode, normally will yield error */
pinState = 1; /* force the pin to 1 */
pinState = 1; /* force the pin to 1 */
pinState = 1; /* force the pin to 1 */
pinState = 1; /* force the pin to 1 */
pinState = 1; /* force the pin to 1 */
pinState = 1; /* force the pin to 1 */
pinState = 1; /* force the pin to 1 */
pinStateTRIS = 0; /* float the pin */



Цитата(Goodefine @ Aug 10 2009, 13:17) *
Код
#define TICK 2
...
void delay_variable(uint8 tick)
{
     for(uint8 i=tick;i;i--) __delay_cycles(TICK);
}
...
delay_variable(x);


Резолюция кода есть 2 или больше системных циклов. То что надо - резолюция из одного системного цикла. Описание кода в начале темы есть резолюция из 2 цикла.

Сообщение отредактировал Student2 - Aug 10 2009, 11:35
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Aug 10 2009, 11:41
Сообщение #11


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(Student2 @ Aug 10 2009, 15:29) *
Хочу установить pinState в 1 для 1, 2.... 7 cycles и потом возвратить в высокоимпедансное состояние

сформировать таблицу из 7 NOP-ов и прыгать на нужный, учитывая задержку подготовительных операций
Для уверенности всё писать на инлайн-ассемблере
всё - это внутренности Pause()


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
Rst7
сообщение Aug 10 2009, 11:47
Сообщение #12


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



Ну если уж очень хочется извратиться, то можно так
CODE
#define ONE_NOP(NAME,NEXT_NAME)\
static void delay_##NEXT_NAME(char cool.gif;\
static void delay_##NAME(char cool.gif\
{\
__no_operation();\
delay_##NEXT_NAME(cool.gif;\
}\

ONE_NOP(4,3)
ONE_NOP(3,2)
ONE_NOP(2,1)
ONE_NOP(1,0)

#pragma optimize=no_inline
static void delay_0(char cool.gif
{
PORTB=b;
}

void delay_x(char b, char c)
{
char __flash *p=(char __flash *)delay_4;
p+=c;
((void(*)(char))p)(cool.gif;
}


с вот таким результатом
CODE
\ In segment CODE, align 2, keep-with-next
11 ONE_NOP(4,3)
\ delay_4:
\ 00000000 0000 NOP
\ 00000002 0000 NOP
\ 00000004 0000 NOP
\ 00000006 0000 NOP
\ 00000008 REQUIRE delay_0
\ 00000008 ; // Fall through to label delay_0
12 ONE_NOP(3,2)
13 ONE_NOP(2,1)
14 ONE_NOP(1,0)
15
16 #pragma optimize=no_inline

\ In segment CODE, align 2, keep-with-next
17 static void delay_0(char cool.gif
\ delay_0:
18 {
19 PORTB=b;
\ 00000000 B905 OUT 0x05, R16
20 }
\ 00000002 9508 RET
\ 00000004 REQUIRE _A_PORTB
21

\ In segment CODE, align 2, keep-with-next
22 void delay_x(char b, char c)
\ delay_x:
23 {
24 char __flash *p=(char __flash *)delay_4;
25 p+=c;
26 ((void(*)(char))p)(cool.gif;
\ 00000000 .... LDI R30, LOW(delay_4/2)
\ 00000002 .... LDI R31, (delay_4/2) >> 8
\ 00000004 E030 LDI R19, 0
\ 00000006 0FE1 ADD R30, R17
\ 00000008 1FF3 ADC R31, R19
\ 0000000A 9409 IJMP
27 }


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
Student2
сообщение Aug 10 2009, 11:52
Сообщение #13


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

Группа: Участник
Сообщений: 83
Регистрация: 4-08-09
Из: Болгария / София
Пользователь №: 51 737



Цитата(MrYuran @ Aug 10 2009, 14:41) *
сформировать таблицу из 7 NOP-ов и прыгать на нужный, учитывая задержку подготовительных операций
Для уверенности всё писать на инлайн-ассемблере
всё - это внутренности Pause()


Мне хотелось как нибудь не трогать ассемблеря (для лучшей поддержки кода) - ассемблер = "черт в коде". Тоже ассемблер и С вместе часто создают глубокие ошибки.
Go to the top of the page
 
+Quote Post
Student2
сообщение Aug 10 2009, 12:00
Сообщение #14


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

Группа: Участник
Сообщений: 83
Регистрация: 4-08-09
Из: Болгария / София
Пользователь №: 51 737



Спасибо Rst7 - код выглядит хорошо и буду пользоваться. Есть только одна проблема - начальное опоздание (время) для подготовки регистров. Если нужная задержка 2 цикла а начальное опоздание 6-8 циклов то будет добавочные 4-6 циклов. Но идея воистину хорошая!

Я думаю что это и есть путь к _even_in_range для AVR!

Сообщение отредактировал Student2 - Aug 10 2009, 12:05
Go to the top of the page
 
+Quote Post
Rst7
сообщение Aug 10 2009, 12:00
Сообщение #15


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



Цитата
Мне хотелось как нибудь не трогать ассемблеря


Ну так зайдите в другую тему (которую Вы создали про even_range) и прочитайте мой ответ smile.gif


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post

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

 


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


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