Перейти к содержанию
    

Функция __delay_cycles(...);

Использую компилятор IAR. В фирменных исходниках применяют функцию __delay_cycles(...); Но в документации её нет. Только скудное упоминание в каком-то htm файле. Ведёт себя странно, компилятор её то оптимизирует, то оставляет.

Какие обции компилятора (или что ещё) нужно задействовать, что бы она всегда работала?

Какая максимальная задержка на ней возможна?

А может есть ещё какая-нибудь функция задержки на N мс?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Использую компилятор IAR. В фирменных исходниках применяют функцию __delay_cycles(...); Но в документации её нет. Только скудное упоминание в каком-то htm файле. Ведёт себя странно, компилятор её то оптимизирует, то оставляет.

 

Да ну что вы... вот из PDFки что идет в комплекте:

 

__delay_cycles __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.

 

на самом деле код будет сгенерирован примитивный - константу в регистр(ы) и вертушка(ки). В случае необходимости добавляются NOPы. Да вы напишите и посмотрите в листинг... Все сразу станет ясно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Минимальная задержка один такт. Компилятор просто вставит NOP, который выполняется один такт. Если больше задержка, то будет подставлен код, выполняющийся указанное количество тактов. Действительно, посмотри листинг и все поймешь.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Практически все, кто работает на IAR пользуются этой встроенной функцией для создания задержки:

 

__delay_cycles __delay_cycles(unsigned long int);

 

Делаете такие определения:

//**********************************************

#define ClkFreq 16000000 // частота кварцевого резонатора или частота на которой работает контроллер.

#define _1us (unsigned long int)((ClkFreq / 1000000) / 1.25) // 1.25 погрешность на вызов функции для 1us.

#define _1ms (unsigned long int)(ClkFreq / 1000)

//**********************************************

 

Сами функции задержки соответственно могут выглядеть так:

void DelayMs(unsigned int d)

{

while(--d)__delay_cycles(_1ms);

}

 

void DelayUs(unsigned int d)

{

while(--d)__delay_cycles(_1us);

}

 

Делаете вызов той или другой функции в зависимости на сколько милисекунд или микросекунд делаете задержку.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Код функции я вижу в дисассемблере. Но вопрос в другом. Иногда эта функция вообще не вставляется. Почему компилятор её оптимизирует? На 480 мс работает, 1 с нет, частота проца 4 МГц. Ставлю подряд 3 вызова по 400 мс, нет их в коде. В другом месте программы подряд 5-10 вызовов работают. Что за чудеса?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Проблема до конца непонятна...

Тогда поясните из какого места в своей программы Вы пытаетесь сделать вызов подпрограммы задержки на 1000мс (1с)?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Точек задержек в программе несколько, в разных файлах проекта. В одних файлах они работают, а в других оптимизируются. В html-ках что-то сказано про это, но я с IAR-ом пока на ВЫ и не пойму в чём дело.

Максимальная задержка на (unsigned long int) нопов? (unsigned long int) в IAR-е 4 байта?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Стоят ли у Вас

#include <inavr.h>

#include <io'ваш тип контроллера'.h>

во всех файлах c/cpp?

Обычно все работает, как положено...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Точек задержек в программе несколько, в разных файлах проекта. В одних файлах они работают, а в других оптимизируются. В html-ках что-то сказано про это, но я с IAR-ом пока на ВЫ и не пойму в чём дело.

Максимальная задержка на (unsigned long int) нопов? (unsigned long int) в IAR-е 4 байта?

 

Максимальная задержка -- посмотрите экспериментально, она существенно меньше доступного диапазона unsigned long, что-то в районе 480 тысяч если я еще помню.

С иаром идет комплект документации в pdf-файлах, ищите раздел Intrinsic function или что-то подобное

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Стоят ли у Вас

#include <inavr.h>

#include <io'ваш тип контроллера'.h>

во всех файлах c/cpp?

Обычно все работает, как положено...

 

Да, всё везде стоит.

В файле iccavr.htm говорится

 

AVRC0012: When compiling with optimization level 6 or higher, calls to the __delay_cycles intrinsic function were considered to be dead code, and were thus removed.

 

У меня оптимизация "минимум размер кода" может это мой случай? Но в других точках проекта эта функция работает.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если все же не так критично отнестись к требованиям Вашей оптимизации попробуйте "поиграться" с отключением элементов оптимизации в разделе: Project->Options...->ICCAVR->Optimizations: Enabled optimizations. Возможно это даст какой то результат. Других вариантов пока нет, кроме как организовать задержку на таймерах, если они в данный момент не используются.

P.S. Непредвиденными последствиями после "оптимизации кода" страдают многие компиляторы, особенно это проявляется, когда производиться дезассемблирование кода. Дизассемблер не может восстановить участки исходника, т.к. они оптимизированы, а попросту говоря их не существует.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Можно переписать функцию задержки с внутренней переменной, объявленной как volatile:

 

void delayms(unsigned long ms)
{
volatile unsigned long dly;
       dly=ms;
       while(--dly) __delay_cycles(_1ms));
}

 

Тогда никакие оптимизации не страшны :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Согласен. Возможно, что вариант с применением volatile будет иметь положительный эффект(надо пробовать, практика подтвердит!).

http://www.kalinin.ru/programming/cpp/12_09_00.shtml

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...