Есть ли стандартная функция в C, которая позволяет установить конкретную задержку в nSec? - PullRequest
2 голосов
/ 10 мая 2019

В моем приложении мне нужно сгенерировать функцию на C, которая будет обеспечивать определенную задержку в наносекундах. Этот таймер задержки должен быть выполнен программно, так как в моем AVR MCU не осталось аппаратных таймеров. Моя проблема в том, что я хотел бы иметь возможность установить значение в наносекундах. У меня тактовая частота MCU составляет 20 МГц (период 50 нс). Я подумал, что быстрый цикл "для", как;

for (n=0; n<value; n++)

, но это не будет учитывать, сколько циклов добавляется к каждому циклу при компиляции. У кого-нибудь есть предложения? Я действительно не хочу писать код на ассемблере.

Ответы [ 2 ]

1 голос
/ 11 мая 2019

Кстати, вы даете нам слишком мало информации. но я думаю, что могу ответить без них, но это заставляет отвечать долго. Давайте начнем с более простой проблемы: у вас есть такая ситуация, когда ваше действие должно выполняться меньше раз, чем выполняет наиболее частый isr. Например, вам нужно отправлять байт каждые 1 с, но ваш isr выполняется каждые 1 мс. Короче говоря, вам нужно отправлять байт каждые 1000 выполнений ISR, затем вы делаете счетчик в ISR, который увеличивает каждый ISR, а когда достигает 1000, вы отправляете байт и устанавливаете cnt равным 0.

ISR()
{
  cnt++;
  if(cnt >= 1000)
  {
    execute(Z);
    cnt = 0;
  }
}

Если у вас возникла проблема, isr медленнее, чем желаемое время выполнения ваших действий, тогда я за редизайн использования вами таймеров. Затем вы должны заставить этот ISR выполняться быстрее, а затем разделить время, подсчитав ожидаемый isr, как я описал выше. Это было упомянуто в комментариях.

Я предлагаю вам переосмыслить способ использования таймеров.

0 голосов
/ 14 мая 2019

Поскольку вы используете AVR, вам следует изучить функции задержки AVR-Libc, _delay_us и _delau_ms, которые описаны здесь:

https://www.nongnu.org/avr-libc/user-manual/group__util__delay.html

Они являются стандартными в контексте AVR, но не являются стандартными для всех сред C в целом.

Некоторые примеры кода для начала работы:

#define F_CPU 20000000
#include <util/delay.h>

int main() {
  while (1) {
    _delay_us(0.05);
  }
}

Обратите внимание, что, хотя _delay_usи каждая функция _delay_ms принимает double в качестве аргумента, вся арифметика с плавающей запятой выполняется во время компиляции, если это возможно, чтобы создать эффективный код для вашей задержки.

...