Куда пропадает точность _delay_ms() ?

Обсуждаем контроллеры компании Atmel.
alex68md
Грызет канифоль
Сообщения: 275
Зарегистрирован: Сб янв 03, 2015 21:03:24

Куда пропадает точность _delay_ms() ?

Сообщение alex68md »

Привет

atmega328p
настраиваю таймер 0 в режиме Normal, предделитель 64, по сравнению 250 тиков (1 мс)
делаю
Код:

Код: Выделить всё

int a = 0, b = 0;
a = millis();
_delay_ms(7100);
b = millis();
#ifdef _UTIL_DELAY_H_
terminal ‹‹ a ‹‹ " " ‹‹ b;
#endif
получаю 7179 разницу.
если использую delay из ардуино то там точно.

как можно повысить точность дилей от авр ?
Реклама
akl
Друг Кота
Сообщения: 4445
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Re: Куда пропадает точность _delay_ms() ?

Сообщение akl »

Может не учитывается, что в регистр сравнения нужно заносить 250-1
Реклама
alex68md
Грызет канифоль
Сообщения: 275
Зарегистрирован: Сб янв 03, 2015 21:03:24

Re: Куда пропадает точность _delay_ms() ?

Сообщение alex68md »

akl, пробовал и так на разницу не влияет. это влияет на подсёт милис только. на делей функцию ни как.
это первое.
второе почему некоторые пишут минус один а некоторые нет.
я склоняюсь что не надо минус один. зачем ?

по формуле у меня 1мс ровно 250 тиков.
если у меня в OCR было например 5 то ровно 250 это 5+250 ане 249.
или другой простой пример

Код: Выделить всё

 
int main()
{
    unsigned char a = 0; //это наш OCR
    a++; // это наш тик
    cout<<" " <<(int)a;
    a++;
    cout<<" " <<(int)a;
    a++;
    cout<<" " <<(int)a;
    a++;
    cout<<" " <<(int)a;
    a++;
    cout<<" " <<(int)a;
    a++;
    cout<<" " <<(int)a;
    a++;
    cout<<" " <<(int)a;
    a++;
    cout<<" " <<(int)a;
    a++;
    cout<<" " <<(int)a;
    a++;
    cout<<" " <<(int)a;
}
после 10 тиков в OCR лежит 10 а не 9/
так что непонимаю зачем минус 1?
OKF
Это не хвост, это антенна
Сообщения: 1393
Зарегистрирован: Вт июн 07, 2011 08:03:18

Re: Куда пропадает точность _delay_ms() ?

Сообщение OKF »

Минус затем что счёт начинается с нуля! Или ты молдаван, дядя?
Реклама
Эиком - электронные компоненты и радиодетали
alex68md
Грызет канифоль
Сообщения: 275
Зарегистрирован: Сб янв 03, 2015 21:03:24

Re: Куда пропадает точность _delay_ms() ?

Сообщение alex68md »

OKF, а ты нацист дядя?

0 + 250 = 250
1 + 250 = 251
и тд
причём тут _откуда_ ты считаеш до того _что_ ты прибавляешь!?

а прибавляем мы согласно формуле константу величиною 16мгц/1000/64 = 250 где ты тут увидел 249 ?
Последний раз редактировалось alex68md Вт апр 26, 2022 14:48:00, всего редактировалось 2 раза.
Реклама
veso74
Поставщик валерьянки для Кота
Сообщения: 1907
Зарегистрирован: Сб май 05, 2012 20:24:52
Откуда: KN34PC, Болгария
Контактная информация:

Re: Куда пропадает точность _delay_ms() ?

Сообщение veso74 »

Если нужно, тренируйтесь здесь онлайн:

VR Timer Interrupts Calculator
https://www.arduinoslovakia.eu/applicat ... calculator

Arduino Timer Interrupts Calculator
http://www.8bit-era.cz/arduino-timer-in ... lator.html

цитат:

Код: Выделить всё

// 1000 Hz (16000000/((249+1)*64))
OCR1A = 249;
Реклама
alex68md
Грызет канифоль
Сообщения: 275
Зарегистрирован: Сб янв 03, 2015 21:03:24

Re: Куда пропадает точность _delay_ms() ?

Сообщение alex68md »

veso74, формулу я знаю. а на тех сайтах помимо формулы есть человеческий фактор который отнял еще единицу. это не даташит.
еслиб это был массив то да массив длиной 250 это с 0 до 249. но мы же тики считаем а не количество элементов в массиве

выше я привел простой пример 10 тиков с нуля. в конце наш "ОСR" (переменная а) имеет 10. а регистр OCR (8 бит ) ни чем не отличается от этой переменной.
akl
Друг Кота
Сообщения: 4445
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Re: Куда пропадает точность _delay_ms() ?

Сообщение akl »

[uquote="alex68md",url="/forum/viewtopic.php?p=4222064#p4222064"]...почему некоторые пишут минус один а некоторые нет.
я склоняюсь что не надо минус один. зачем ?[/uquote]
Вложения
NEXT_OCR0_250.png
(64.79 КБ) 98 скачиваний
alex68md
Грызет канифоль
Сообщения: 275
Зарегистрирован: Сб янв 03, 2015 21:03:24

Re: Куда пропадает точность _delay_ms() ?

Сообщение alex68md »

veso74,
вот статьи где не отнимают
https://narodstream.ru/avr-urok-10-tajm ... eryvaniya/
https://www.adnbr.co.uk/articles/counting-milliseconds
и тд

я и сказал об этом вначале ктото в своих статьях / калькуляторах отнимает а ктото нет. пытаюсь понять зачем отнимать.
veso74
Поставщик валерьянки для Кота
Сообщения: 1907
Зарегистрирован: Сб май 05, 2012 20:24:52
Откуда: KN34PC, Болгария
Контактная информация:

Re: Куда пропадает точность _delay_ms() ?

Сообщение veso74 »

В Arduino так (можете увидеть во внутренних файлах Arduino IDE):
tone, в Hz, /64:

Код: Выделить всё

ocr = F_CPU / frequency / 2 / 64 - 1;
...
OCR0A = ocr;
Последний раз редактировалось veso74 Вт апр 26, 2022 16:09:52, всего редактировалось 1 раз.
alex68md
Грызет канифоль
Сообщения: 275
Зарегистрирован: Сб янв 03, 2015 21:03:24

Re: Куда пропадает точность _delay_ms() ?

Сообщение alex68md »

akl, точно. теперь понятно откуда ноги растут. спасибо. но всёравно не всётак однозначно. точнее нельзя все случаи мести под одну гребенку. тобишь в большинстве случае все эти калькулятора где есть минус один тоже неправильные имхо.
сейчас объясню почему

когда у нас делитель 1 и каждый реальный тик процессора равен реальному тику в TCNT тогда да получается надо отнять единицу согласно вашей фото из даташита. НО в большинстве случаев у всех стоит предедлитель. когда счётчик тикает в 64 или даже в 1024 раз реже чем реальный тик процессора.
и выходит у нас есть погрешность в обоих случаях.
НО делая минус один мы делаем погрешность намного больше чем когда не делаем минус один. т.к.
при делителе например 64
минус один получается погрешность 1*64 - 1 = на 63 реальных тика _раньше_ нашей частоты.
без минус один у нас погрешность всего лиш на один реальный тик _позже_ нашей частоты.
ну из этих двух вариантов лучше меньшее зло т.е. без минуса.
правильно я мыслю?

наша частота - эта та ради который мы и выставляли предделитель и OCR

PS: а если предделитель 1024 так там еще больше погрешность с минусом :)

Добавлено after 1 minute 20 seconds:
veso74, это где вы такое увидели ?
я вижу там
#define clockCyclesPerMicrosecond() ( F_CPU / 1000000L )
#define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() )
#define microsecondsToClockCycles(a) ( (a) * clockCyclesPerMicrosecond() )
veso74
Поставщик валерьянки для Кота
Сообщения: 1907
Зарегистрирован: Сб май 05, 2012 20:24:52
Откуда: KN34PC, Болгария
Контактная информация:

Re: Куда пропадает точность _delay_ms() ?

Сообщение veso74 »

Tone.cpp:

Код: Выделить всё

// frequency (in hertz) and duration (in milliseconds).
void tone(uint8_t _pin, unsigned int frequency, unsigned long duration)
...
За delay()/delayMicroseconds() будет сложно проанализировать. Использовать подсчет машинных циклов.
alex68md
Грызет канифоль
Сообщения: 275
Зарегистрирован: Сб янв 03, 2015 21:03:24

Re: Куда пропадает точность _delay_ms() ?

Сообщение alex68md »

да delayMicroseconds() они там в коментах каждый шаг расписывают
if 3 тика. а если true 4. и тд
и то так понимаю в конце некое округление. ну мне микро секунды не нужны.

по поводу таймера в tone() они там предделитель в 1 ставят. тогда всё согласно даташиту. (фото от akl выше)

а если предделитеь 64/256/1024 то получается как я описал вроде. т.е. минус один не нужен
veso74
Поставщик валерьянки для Кота
Сообщения: 1907
Зарегистрирован: Сб май 05, 2012 20:24:52
Откуда: KN34PC, Болгария
Контактная информация:

Re: Куда пропадает точность _delay_ms() ?

Сообщение veso74 »

[uquote="alex68md",url="/forum/viewtopic.php?p=4222252#p4222252"]...а если предделитеь 64/256/1024 то получается как я описал вроде. т.е. минус один не нужен[/uquote]
Везде -1, на каждом прескалере.
Спойлер

Код: Выделить всё

// if we are using an 8 bit timer, scan through prescalars to find the best fit
    if (_timer == 0 || _timer == 2)
    {
      ocr = F_CPU / frequency / 2 - 1;
      prescalarbits = 0b001;  // ck/1: same for both timers
      if (ocr > 255)
      {
        ocr = F_CPU / frequency / 2 / 8 - 1;
        prescalarbits = 0b010;  // ck/8: same for both timers

        if (_timer == 2 && ocr > 255)
        {
          ocr = F_CPU / frequency / 2 / 32 - 1;
          prescalarbits = 0b011;
        }

        if (ocr > 255)
        {
          ocr = F_CPU / frequency / 2 / 64 - 1;
          prescalarbits = _timer == 0 ? 0b011 : 0b100;

          if (_timer == 2 && ocr > 255)
          {
            ocr = F_CPU / frequency / 2 / 128 - 1;
            prescalarbits = 0b101;
          }

          if (ocr > 255)
          {
            ocr = F_CPU / frequency / 2 / 256 - 1;
            prescalarbits = _timer == 0 ? 0b100 : 0b110;
            if (ocr > 255)
            {
              // can't do any better than /1024
              ocr = F_CPU / frequency / 2 / 1024 - 1;
              prescalarbits = _timer == 0 ? 0b101 : 0b111;
            }
          }
        }
      }[/codе][/spoiler]
Последний раз редактировалось veso74 Вт апр 26, 2022 18:22:13, всего редактировалось 5 раз.
akl
Друг Кота
Сообщения: 4445
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Re: Куда пропадает точность _delay_ms() ?

Сообщение akl »

alex68md Предделитель, разумеется, вносит свою лепту. Вот как студия отрабатывает секунду с 250
СпойлерИзображение
А вот так с 250-1
СпойлерИзображение
Заметьте на сколько, в первом случае, секунда длинше :)
alex68md
Грызет канифоль
Сообщения: 275
Зарегистрирован: Сб янв 03, 2015 21:03:24

Re: Куда пропадает точность _delay_ms() ?

Сообщение alex68md »

akl, хм интересно.

а для таймера ноль тужу секунду можете посматреть ?
akl
Друг Кота
Сообщения: 4445
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Re: Куда пропадает точность _delay_ms() ?

Сообщение akl »

Секунда с Т0 без предделителя
СпойлерИзображение
Секунда с предделителем 256
СпойлерИзображение
Вложения
OCR0A_250-1_PRESC256.png
(45.3 КБ) 126 скачиваний
OCR0A_250-1.png
(41.92 КБ) 131 скачивание
alex68md
Грызет канифоль
Сообщения: 275
Зарегистрирован: Сб янв 03, 2015 21:03:24

Re: Куда пропадает точность _delay_ms() ?

Сообщение alex68md »

akl, но как не понимаю :\ ? [про таймер 1]
минус один с предделителем 256 как у вас на фото = не дотикать 256 реальных МК тиков до нужной виличины. даже если прибавить один тик после сравнения. 255 не дотикает.
Аватара пользователя
Ivanoff-iv
Друг Кота
Сообщения: 7077
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

Re: Куда пропадает точность _delay_ms() ?

Сообщение Ivanoff-iv »

всё верно -1 всегда, при любом прескалере оборот тмймера считается за 256 (и частота делится на 256), хотя максимально возможное значение (оно же и применяется в нормальном режиме) это 255
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
alex68md
Грызет канифоль
Сообщения: 275
Зарегистрирован: Сб янв 03, 2015 21:03:24

Re: Куда пропадает точность _delay_ms() ?

Сообщение alex68md »

Ivanoff-iv, так вот я пытаюсь понять почему всегда.
я понял почему при 1:1. один тик догоняется при переходе на прерывание.

но когда прескалер 256
и мы в OCR пишем delay-1 то мы отнимаем реальных процессорных 256 тиков от требуемой величины .. да прерывание срабатывает только на следующий процессорный тик. т.е. получится 256-1 = 255 реальных процессорных тиков мы не дотикали. когда / в какой момент нагоняются эти недостяющие 255 тиков ?
Ответить

Вернуться в «AVR»