Как сделать задержку микросекунды в AVR (ATmega8) с таймером? - PullRequest
0 голосов
/ 11 февраля 2020

Я хочу сделать переменную задержку в ATmega8. Но в функции delay_us () я могу просто поставить постоянное значение. Я думаю, что могу сделать переменную задержку микросекунды с таймером, но я не знаю, как с этим работать.

Пожалуйста, помогите мне.

1 Ответ

1 голос
/ 28 февраля 2020

Вы можете использовать задержку l oop: вы задерживаетесь на одну микросекунду в каждой итерации и делаете столько итераций, сколько микросекунд вы должны записать:

void delay_us(unsigned long us)
{
    while (us--) _delay_us(1);
}

Однако есть несколько проблемы с этим подходом:

  • требуется время для управления итерациями (уменьшение счетчика, сравнение с нулем, условная ветвь ...), поэтому задержка в пределах l oop должна быть значительно короче что 1 мкс
  • требуется время для вызова функции и возврата из нее, и это следует исключить из счетчика итераций, но, поскольку это время может быть не полным числом микросекунд, вам придется добавить небольшая задержка, чтобы перейти к следующей полной микросекунде
  • , если компилятор встроит функцию, все будет отключено.

Попытка исправить эти проблемы приводит к чему-то вроде этого:

// Only valid with a 16 MHz clock.
void __attribute__((noinline)) delay_us(unsigned long us)
{
    if (us < 2) return;
    us -= 2;
    _delay_us(0.4375);
    while (us--) _delay_us(0.3125);
}

Для более полной версии, которая может обрабатывать различные тактовые частоты, см. функцию delayMicroseconds() от ядра Arduino AVR. Обратите внимание, что функция точна только для нескольких дискретных частот. Также обратите внимание, что задержка l oop выполняется во встроенной сборке, чтобы не зависеть от оптимизации компилятора.

...