Обсуждаем контроллеры компании Atmel.
Ответить

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

Вт апр 26, 2022 09:17:25

Привет

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 из ардуино то там точно.

как можно повысить точность дилей от авр ?

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

Вт апр 26, 2022 10:17:17

Может не учитывается, что в регистр сравнения нужно заносить 250-1

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

Вт апр 26, 2022 12:34:16

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?

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

Вт апр 26, 2022 12:38:02

Минус затем что счёт начинается с нуля! Или ты молдаван, дядя?

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

Вт апр 26, 2022 13:52:16

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

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

а прибавляем мы согласно формуле константу величиною 16мгц/1000/64 = 250 где ты тут увидел 249 ?
Последний раз редактировалось alex68md Вт апр 26, 2022 14:48:00, всего редактировалось 2 раз(а).

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

Вт апр 26, 2022 14:23:54

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

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;

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

Вт апр 26, 2022 15:00:10

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

выше я привел простой пример 10 тиков с нуля. в конце наш "ОСR" (переменная а) имеет 10. а регистр OCR (8 бит ) ни чем не отличается от этой переменной.

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

Вт апр 26, 2022 15:05:00

...почему некоторые пишут минус один а некоторые нет.
я склоняюсь что не надо минус один. зачем ?
Вложения
NEXT_OCR0_250.png
(64.79 KiB) Скачиваний: 72

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

Вт апр 26, 2022 15:34:33

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

я и сказал об этом вначале ктото в своих статьях / калькуляторах отнимает а ктото нет. пытаюсь понять зачем отнимать.

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

Вт апр 26, 2022 16:07:08

В Arduino так (можете увидеть во внутренних файлах Arduino IDE):
tone, в Hz, /64:
Код:
ocr = F_CPU / frequency / 2 / 64 - 1;
...
OCR0A = ocr;
Последний раз редактировалось veso74 Вт апр 26, 2022 16:09:52, всего редактировалось 1 раз.

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

Вт апр 26, 2022 16:10:33

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() )

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

Вт апр 26, 2022 16:14:47

Tone.cpp:
Код:
// frequency (in hertz) and duration (in milliseconds).
void tone(uint8_t _pin, unsigned int frequency, unsigned long duration)
...

За delay()/delayMicroseconds() будет сложно проанализировать. Использовать подсчет машинных циклов.

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

Вт апр 26, 2022 16:45:13

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

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

а если предделитеь 64/256/1024 то получается как я описал вроде. т.е. минус один не нужен

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

Вт апр 26, 2022 17:17:58

...а если предделитеь 64/256/1024 то получается как я описал вроде. т.е. минус один не нужен

Везде -1, на каждом прескалере.
Последний раз редактировалось veso74 Вт апр 26, 2022 18:22:13, всего редактировалось 5 раз(а).

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

Вт апр 26, 2022 17:20:46

alex68md Предделитель, разумеется, вносит свою лепту. Вот как студия отрабатывает секунду с 250

А вот так с 250-1

Заметьте на сколько, в первом случае, секунда длинше :)
Вложения
250-1.png
(43.9 KiB) Скачиваний: 76
250.png
(34.62 KiB) Скачиваний: 87

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

Вт апр 26, 2022 17:47:10

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

а для таймера ноль тужу секунду можете посматреть ?

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

Вт апр 26, 2022 18:52:56

Секунда с Т0 без предделителя

Секунда с предделителем 256
Вложения
OCR0A_250-1_PRESC256.png
(45.3 KiB) Скачиваний: 68
OCR0A_250-1.png
(41.92 KiB) Скачиваний: 68

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

Вт апр 26, 2022 19:01:38

akl, но как не понимаю :\ ? [про таймер 1]
минус один с предделителем 256 как у вас на фото = не дотикать 256 реальных МК тиков до нужной виличины. даже если прибавить один тик после сравнения. 255 не дотикает.

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

Вт апр 26, 2022 19:13:25

всё верно -1 всегда, при любом прескалере оборот тмймера считается за 256 (и частота делится на 256), хотя максимально возможное значение (оно же и применяется в нормальном режиме) это 255

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

Вт апр 26, 2022 20:43:23

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

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