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

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

Вт апр 26, 2022 21:44:34

А даташит пробовали искать?
Вы в своем коде скрестили ужа и ежа.
Изображение
И, да:
Код:
unsigned long millis();
Вложения
1.png
(3.99 KiB) Скачиваний: 354

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

Вт апр 26, 2022 22:09:47

а я вот какраз не вижу разницы в прескалерах, хоть 1, хоть 2, хоть 222 :) в любом случае таймер идёт покругу от 0 до положенного ему максимальньго значения. и 0 длится ровно такое-же время, как 1 и все остальные значения, максимальное значение тоже длится.
например:
если заставить считать таймер до 1, то отдин отсчет таймера в нём будет 0, а второй отсчет - 1 т.е. цифра 1, а отсчёта 2...
если до 0, то отсчёт будпт один - 0, потом переполнение и по новой, т.е. опять отсчетов на один больше, чем цифра, до которой считаем...

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

Ср апр 27, 2022 09:40:30

Вы в своем коде скрестили ужа и ежа.

это вы о чём ?


милис возвращяет uint32 да . а присваивать мы можем хоть в char если нам это не мешает.
даташит мы читаем все посты начиная с первого :)
формулу тоже все знаем . она не даёт ответ когда наганяются тики... плюс у нас речь о нормал режиме а не СТС
но вот еще раз внимательное прочтение кажется дало ответ
"As for the normal mode of operation, the TOV0 flag is set in the same timer clock cycle that the counter counts from MAX to
0x00."
т.е. прерывание наступает не на следующий тик процессора как я понял изначально а на следующий тик счётчика. вот поэтому и надо -1.

ну или как объяснил Ivanoff-iv :)


весм спасибо друзья особенно akl

Добавлено after 3 minutes 52 seconds:
только остался вопрос с дилей от авр как повысить его точность. возможно ли впринципе ? :)

Код:
#define __DELAY_ROUND_DOWN__
void _delay_ms(double __ms)
{
   double __tmp ;
#if __HAS_DELAY_CYCLES && defined(__OPTIMIZE__) && \
  !defined(__DELAY_BACKWARD_COMPATIBLE__) &&      \
  __STDC_HOSTED__
   uint32_t __ticks_dc;
   extern void __builtin_avr_delay_cycles(unsigned long);
   __tmp = ((F_CPU) / 1e3) * __ms;

   #if defined(__DELAY_ROUND_DOWN__)
      __ticks_dc = (uint32_t)fabs(__tmp);

   #elif defined(__DELAY_ROUND_CLOSEST__)
      __ticks_dc = (uint32_t)(fabs(__tmp)+0.5);

   #else
      //round up by default
      __ticks_dc = (uint32_t)(ceil(fabs(__tmp)));
   #endif

   __builtin_avr_delay_cycles(__ticks_dc);

#else
   uint16_t __ticks;
   __tmp = ((F_CPU) / 4e3) * __ms;
   if (__tmp < 1.0)
      __ticks = 1;
   else if (__tmp > 65535)
   {
      //   __ticks = requested delay in 1/10 ms
      __ticks = (uint16_t) (__ms * 10.0);
      while(__ticks)
      {
         // wait 1/10 ms
         _delay_loop_2(((F_CPU) / 4e3) / 10);
         __ticks --;
      }
      return;
   }
   else
      __ticks = (uint16_t)__tmp;
   _delay_loop_2(__ticks);
#endif
}

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

Ср апр 27, 2022 10:31:46

double __tmp; :facepalm:
Лучше не использовать delay, если возможно.

Какая точность нужна? Дайте пример. Для чего будете использовать? Частотомер? Функции времени? Хм...
Используйте таймер/и. A eсли время превышает разрядность, посчитайте k*t.
Все давно разработано, просто адаптируйте под свои цели.

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

Ср апр 27, 2022 10:46:10

Да там и uint32 достаточно. На восьмибитном-то УГ!
Но дабл на микроконтроллере, который даже флоаты не умеет — это уж совсем [censored] ☺

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

Ср апр 27, 2022 11:31:04

дабл на микроконтроллере, который даже флоаты не умеет — это уж совсем [censored] ☺

А что, есть такие, что умеют? Кроме DSP, разумеется.

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

Ср апр 27, 2022 11:39:45

Jack_A, флоаты-то? Конечно, полно МК, которые умеют флоаты. Взять, например, STM32F303…

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

Ср апр 27, 2022 13:15:40

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

когда мне нужно было более-менее точно считать задержки с разрешенными прерываниями, я загонял код в протеус и подгонял значение параметра _delay_ms до получения задержки, близкой к желаемой. имхо, иначе добиться такого результата, кроме как ручной подгонкой при помощи протеуса, крайне сложно...

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

Ср апр 27, 2022 16:07:48

полно МК, которые умеют флоаты. Взять, например, STM32F303…

Да, поотстал я от жизни... Этот МК помощнее на порядок, чем та миниЭВМ (так тогда обзывалось) СМ-4, на котором я в советские времена АСК делал. Грустно это...

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

Ср апр 27, 2022 16:14:58

короче написал свой дилей
Код:
void delay(unsigned long ms)
{
   if (ms < 1) return;
   uit32_t m = millis();
   while (millis() - m < ms);
}

может и коряво но точнее чем АВРовский :D

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

Ср апр 27, 2022 16:19:24

alex68md писал(а):короче написал свой дилей
Код:
void delay(unsigned long ms)
{
   ms += millis();
   while (millis() < ms);
}

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

Ср апр 27, 2022 16:30:30

ARV, красивее но не учтено переполнение.

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

Ср апр 27, 2022 16:52:08

Этот МК помощнее на порядок, чем та миниЭВМ (так тогда обзывалось) СМ-4, на котором я в советские времена АСК делал. Грустно это...

Почему грустно? Наоборот, здорово же! Я когда-то на "Весте" (советский клон ZX-spectrum'а) на бейсике мучился всякую фигню программировал, периодически вставки в машкодах... А ресурсов там было: 16кБ ПЗУ, 16кБ видео-ОЗУ и 32кБ ОЗУ для пользователя (причем, часть этой области - ремап на системные регистры).
В 30-рублевом STM32F030 (сейчас, правда, они по стольнику ☹) хоть оперативки тоже немного, зато ресурсы были - огого! Что до F303, сейчас они на али в районе 500-600р (очень дорого на мой взгляд), там есть не только аппаратная поддержка флоатов, но еще и ЦАП и куча всяких интересных вещей… Да хоть та же аппаратная поддержка сенсорных кнопок (правда, это есть и в более дешевых F072).

Добавлено after 6 minutes 31 second:
alex68md, еще раз напомню: такие бешеные задержки (в сотни микросекунд и выше) допустимы лишь во время первичной инициализации. В дальнейшем рантайме такое запускать ни в коем случае нельзя!
Нужно завести конечный автомат и проверять. Скажем, так (код для 32-битного МК, я с 8-битными завязал уже давно):
Код:
typedef enum{
  STATE_RELAX,
...
  STATE_SOMETH,
  STATE_WAIT,
...
} SM_state;

static SM_state st = STATE_RELAX;

void SM(){
  static uint32_t tlocal; // Tms - счетчик миллисекунд, который по прерыванию таймера инкрементируется
  switch(st){
    case ...
    case STATE_SOMETH:
      ...
      st = STATE_WAIT;
      tlocal = Tms;
    break;
    case STATE_WAIT:
      if(Tms - tlocal >= WAIT_PAUSE){
        st = ...;
        ...
      }
    case ...
    default: // STATE_RELAX - do nothing
  }
}

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

Ср апр 27, 2022 16:55:17

Почему грустно?

Когда глянешь - какие ресурсы предоставлены разработчикам теперь - и на чём корячилось наше поколение...
Только остались ли теперь разработчики как класс? Нонче всё больше менежёры, блохеры и титикакеры. :(

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

Ср апр 27, 2022 17:02:36

Eddy_Em, я так и сделал поначалу... но слишком дофига этих if (current_time-past_time > pause)
вот пытаюсь оптимизировать системными таймреами

PS: delay у меня в основном для инициализации. в рантайме его нет вообще.
ну кроме специфических мест где без делея следующая команда не обработается внешним устройством и надо выждать 100-200 милисекунд

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

Ср апр 27, 2022 17:08:10

где без делея следующая команда не обработается внешним устройством и надо выждать 100-200 милисекунд

Ни в коем случае так делать нельзя! Исключительно решать в конечном автомате!
А еще нельзя жирные функции за один присест запускать. Скажем, если у вас экранный буфер заполняется в течение 10мс, нужно разбить это на процедуры и выполнять по одной за каждый проход суперлупа. В этом случае все будет работать четко и слаженно. И не придется кучу функционала в прерывания выносить. Ну, а как заполнил буфер - запустил DMA и пусть оно себе весело данные отправляет в экран…

Добавлено after 1 minute 12 seconds:
Нонче всё больше менежёры, блохеры и титикакеры. :(

К сожалению, есть такое. Разработчиков осталось очень мало. И их очень трудно среди быдла распознать. А быдла расплодилось: все эти абдуринщики, калокуберы и прочая нечисть!

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

Ср апр 27, 2022 19:41:22

короче написал свой дилей

Поздравляю! Вы изобрели свой собственный велосипед, с квадратными колёсами.
wiring.c не пробовали посмотреть?

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

Ср апр 27, 2022 20:23:49

ARV, красивее но не учтено переполнение.
32 бита переполнятся через 49 суток...

Добавлено after 5 minutes 44 seconds:
Eddy_Em писал(а):А еще нельзя жирные функции за один присест запускать. Скажем, если у вас экранный буфер заполняется в течение 10мс, нужно разбить это на процедуры и выполнять по одной за каждый проход суперлупа. В этом случае все будет работать четко и слаженно.
слишком категорично! можно делать все, что приводит к желаемому результату. а категорически что-либо заявлять, как истину на все времена - недальновидно

из моего опыта
1. DIGISCRIPT - там вся интерпретация и чтение SD-карты делается в "жирных" функциях, при этом обеспечиваетсяя четкая привязка к 10-мс интервалам... и вы не поверите, каким именно способом! да, да, именно тупым ожиданием...

2. сейчас делаю еще один проектик... там та же песня: динамичекое обновление дисплея делается в главном цикле в "жирной" функции, которая длится, в зависимости от условий от 4 до 8 мс, и при этом обеспечивается 200FPS обновления дисплея. боле того, я сильно сомневаюсь, что "дроблением" можно что-либо улучшить или вообще даже получить то же самое...

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

Ср апр 27, 2022 20:34:20

динамичекое обновление дисплея делается в главном цикле в "жирной" функции, которая длится, в зависимости от условий от 4 до 8 мс, и при этом обеспечивается 200FPS обновления дисплея

Чё, нормально.
1000/8=125

И, мне Ваша аватарка совсем не понятна. На ней фото "фиги" спереди.
Несёт ли это какой-то смысл?
Или, если рассматривать человека снизу, увидим фигу?
Или, мы увидим её, заглянув внутрь?
Мне не понятно.
Мне кажется, что всё вами написанное в дивизе, вы относите в первую очередь к себе.
Вы об этом не задумывались?
А вот это "скушно, бабоньки", это-же явно отсылка к себе.
Займитесь собой.

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

Ср апр 27, 2022 21:26:51

void _delay_ms(double __ms)
На листинг машинного кода посмотрите, если __ms является константным выражением, то скорее всего никакого double на выходе не будет.
Если же там действительно переменная - вы попали на жирную арифметику с плавающей запятой, и непонятными последствиями для точности задержки :-(
Ответить