|
Как сделать времевую задержку в AVR без таймера |
|
|
|
Aug 9 2009, 10:42
|

Частый гость
 
Группа: Участник
Сообщений: 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. Буду благодарен если поделитесь как Вы делаете задержки без използование таймера.
|
|
|
|
|
Aug 9 2009, 12:45
|

Знающий
   
Группа: Свой
Сообщений: 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?
|
|
|
|
|
Aug 9 2009, 13:02
|

Частый гость
 
Группа: Участник
Сообщений: 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.
|
|
|
|
|
Aug 10 2009, 10:17
|

Местный
  
Группа: Свой
Сообщений: 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);
--------------------
Любой, заслуживающий внимания, опыт приобретается себе в убыток...
|
|
|
|
|
Aug 10 2009, 11:05
|

Гуру
     
Группа: Свой
Сообщений: 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
|
|
|
|
|
Aug 10 2009, 11:20
|

Частый гость
 
Группа: Участник
Сообщений: 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
|
|
|
|
|
Aug 10 2009, 11:29
|

Частый гость
 
Группа: Участник
Сообщений: 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
|
|
|
|
|
Aug 10 2009, 11:41
|

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

|
Цитата(Student2 @ Aug 10 2009, 15:29)  Хочу установить pinState в 1 для 1, 2.... 7 cycles и потом возвратить в высокоимпедансное состояние сформировать таблицу из 7 NOP-ов и прыгать на нужный, учитывая задержку подготовительных операций Для уверенности всё писать на инлайн-ассемблере всё - это внутренности Pause()
--------------------
Программирование делится на системное и бессистемное. ©Моё :) — а для кого-то БГ — это Bill Gilbert =)
|
|
|
|
|
Aug 10 2009, 11:47
|

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

|
Ну если уж очень хочется извратиться, то можно так CODE #define ONE_NOP(NAME,NEXT_NAME)\ static void delay_##NEXT_NAME(char  ;\ static void delay_##NAME(char  \ {\ __no_operation();\ delay_##NEXT_NAME(  ;\ }\ 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  { PORTB=b; } void delay_x(char b, char c) { char __flash *p=(char __flash *)delay_4; p+=c; ((void(*)(char))p)(  ; } с вот таким результатом 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  \ 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)(  ; \ 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 }
--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
|
|
|
|
|
Aug 10 2009, 11:52
|

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

|
Цитата(MrYuran @ Aug 10 2009, 14:41)  сформировать таблицу из 7 NOP-ов и прыгать на нужный, учитывая задержку подготовительных операций Для уверенности всё писать на инлайн-ассемблере всё - это внутренности Pause() Мне хотелось как нибудь не трогать ассемблеря (для лучшей поддержки кода) - ассемблер = "черт в коде". Тоже ассемблер и С вместе часто создают глубокие ошибки.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|