Страница 1 из 3
Куда пропадает точность _delay_ms() ?
Добавлено: Вт апр 26, 2022 09:17:25
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 из ардуино то там точно.
как можно повысить точность дилей от авр ?
Re: Куда пропадает точность _delay_ms() ?
Добавлено: Вт апр 26, 2022 10:17:17
akl
Может не учитывается, что в регистр сравнения нужно заносить 250-1
Re: Куда пропадает точность _delay_ms() ?
Добавлено: Вт апр 26, 2022 12:34:16
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?
Re: Куда пропадает точность _delay_ms() ?
Добавлено: Вт апр 26, 2022 12:38:02
OKF
Минус затем что счёт начинается с нуля! Или ты молдаван, дядя?
Re: Куда пропадает точность _delay_ms() ?
Добавлено: Вт апр 26, 2022 13:52:16
alex68md
OKF, а ты нацист дядя?
0 + 250 = 250
1 + 250 = 251
и тд
причём тут _откуда_ ты считаеш до того _что_ ты прибавляешь!?
а прибавляем мы согласно формуле константу величиною 16мгц/1000/64 = 250 где ты тут увидел 249 ?
Re: Куда пропадает точность _delay_ms() ?
Добавлено: Вт апр 26, 2022 14:23:54
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;
Re: Куда пропадает точность _delay_ms() ?
Добавлено: Вт апр 26, 2022 15:00:10
alex68md
veso74, формулу я знаю. а на тех сайтах помимо формулы есть человеческий фактор который отнял еще единицу. это не даташит.
еслиб это был массив то да массив длиной 250 это с 0 до 249. но мы же тики считаем а не количество элементов в массиве
выше я привел простой пример 10 тиков с нуля. в конце наш "ОСR" (переменная а) имеет 10. а регистр OCR (8 бит ) ни чем не отличается от этой переменной.
Re: Куда пропадает точность _delay_ms() ?
Добавлено: Вт апр 26, 2022 15:05:00
akl
[uquote="alex68md",url="/forum/viewtopic.php?p=4222064#p4222064"]...почему некоторые пишут минус один а некоторые нет.
я склоняюсь что не надо минус один. зачем ?[/uquote]
Re: Куда пропадает точность _delay_ms() ?
Добавлено: Вт апр 26, 2022 15:34:33
alex68md
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
veso74
В Arduino так (можете увидеть во внутренних файлах Arduino IDE):
tone, в Hz, /64:
Код: Выделить всё
ocr = F_CPU / frequency / 2 / 64 - 1;
...
OCR0A = ocr;
Re: Куда пропадает точность _delay_ms() ?
Добавлено: Вт апр 26, 2022 16:10:33
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() )
Re: Куда пропадает точность _delay_ms() ?
Добавлено: Вт апр 26, 2022 16:14:47
veso74
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
alex68md
да delayMicroseconds() они там в коментах каждый шаг расписывают
if 3 тика. а если true 4. и тд
и то так понимаю в конце некое округление. ну мне микро секунды не нужны.
по поводу таймера в tone() они там предделитель в 1 ставят. тогда всё согласно даташиту. (фото от akl выше)
а если предделитеь 64/256/1024 то получается как я описал вроде. т.е. минус один не нужен
Re: Куда пропадает точность _delay_ms() ?
Добавлено: Вт апр 26, 2022 17:17:58
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]
Re: Куда пропадает точность _delay_ms() ?
Добавлено: Вт апр 26, 2022 17:20:46
akl
alex68md Предделитель, разумеется, вносит свою лепту. Вот как студия отрабатывает секунду с 250
Спойлер

А вот так с 250-1
Спойлер

Заметьте на сколько, в первом случае, секунда длинше

Re: Куда пропадает точность _delay_ms() ?
Добавлено: Вт апр 26, 2022 17:47:10
alex68md
akl, хм интересно.
а для таймера ноль тужу секунду можете посматреть ?
Re: Куда пропадает точность _delay_ms() ?
Добавлено: Вт апр 26, 2022 18:52:56
akl
Секунда с Т0 без предделителя
Спойлер

Секунда с предделителем 256
Спойлер

Re: Куда пропадает точность _delay_ms() ?
Добавлено: Вт апр 26, 2022 19:01:38
alex68md
akl, но как не понимаю :\ ? [про таймер 1]
минус один с предделителем 256 как у вас на фото = не дотикать 256 реальных МК тиков до нужной виличины. даже если прибавить один тик после сравнения. 255 не дотикает.
Re: Куда пропадает точность _delay_ms() ?
Добавлено: Вт апр 26, 2022 19:13:25
Ivanoff-iv
всё верно -1 всегда, при любом прескалере оборот тмймера считается за 256 (и частота делится на 256), хотя максимально возможное значение (оно же и применяется в нормальном режиме) это 255
Re: Куда пропадает точность _delay_ms() ?
Добавлено: Вт апр 26, 2022 20:43:23
alex68md
Ivanoff-iv, так вот я пытаюсь понять почему всегда.
я понял почему при 1:1. один тик догоняется при переходе на прерывание.
но когда прескалер 256
и мы в OCR пишем delay-1 то мы отнимаем реальных процессорных 256 тиков от требуемой величины .. да прерывание срабатывает только на следующий процессорный тик. т.е. получится 256-1 = 255 реальных процессорных тиков мы не дотикали. когда / в какой момент нагоняются эти недостяющие 255 тиков ?