Какая у меня ошибка при расчете задержки?

Поклонники продукции Microchip Technology Inc тусуются тут.
Ответить
Нашел транзистор. Понюхал.
Аватара пользователя
Сообщения: 151
Зарегистрирован: Ср дек 01, 2021 15:09:09

Сообщение PenguinChik »

Рассчитал задержку на ассемблере с помощью программы. Задержка равняется 1 секунде. Но почему получился именно такой код? Я по этому коду пробую рассчитать задержку - у меня не получается 1 секунда.

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

movlw          0.173
movwf          Reg1
movlw          0.19
movwf          Reg2
movlw          0.6
movwf          Reg3
decfsz          Reg1,1
goto             $-1
decfsz          Reg2,1
goto             $-3
decfsz          Reg3,1
goto             $-5
Я считаю - сначала счет идет от 173 до нуля. Это 173 мкс. Потом программа перескакивает на Reg2. И количество циклов равно 255*19=4845. Потом программа опускается еще ниже и количество циклов уже равно 225*19*6 = 25650. И если общее число циклов сложить, то получится 30668 мкс. Так какая у меня ошибка при расчете задержки?
Реклама
Друг Кота
Аватара пользователя
Сообщения: 7363
Зарегистрирован: Пт авг 28, 2009 21:34:30
Откуда: 845-й км.

Сообщение uldemir »

У вас все циклы "256". Только каждый из первого цикла имеет чуть короче длину. потому как после первого выполнения

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

decfsz          Reg1,1
goto             $-1
оно выполнится 173 раза, но для второго выполнения там никто 173 не загружает, поэтому следующий раз этот цикл выполнится 256 раз. Так же и все остальные циклы.
Реклама
Друг Кота
Аватара пользователя
Сообщения: 25560
Зарегистрирован: Чт янв 10, 2008 22:01:02
Откуда: Московская область, Фрязино

Сообщение КРАМ »

[uquote="PenguinChik",url="/forum/viewtopic.php?p=4320080#p4320080"]Рассчитал задержку... бла...бла...бла...

movlw 0.173[/uquote]

Это что за ноль перед точкой?
[uquote="PenguinChik",url="/forum/viewtopic.php?p=4320080#p4320080"]Я считаю[/uquote]
Вы симулятором МПЛАБа пользоваться умеете? Ваши вопросы однозначно говорят о том, что вы даже не подозреваете о его наличии.
Ну и продолжение мазохизма в коде в стиле "а ля корабельников" да еще и в абсолютном формате не дает возможности наблюдать переменные в Watch.
Вы так ничему толковому никогда не научитесь.
Нашел транзистор. Понюхал.
Аватара пользователя
Сообщения: 151
Зарегистрирован: Ср дек 01, 2021 15:09:09

Сообщение PenguinChik »

[uquote="КРАМ",url="/forum/viewtopic.php?p=4320106#p4320106"][uquote="PenguinChik",url="/forum/viewtopic.php?p=4320080#p4320080"]Рассчитал задержку... бла...бла...бла...

movlw 0.173[/uquote]

Это что за ноль перед точкой?
[uquote="PenguinChik",url="/forum/viewtopic.php?p=4320080#p4320080"]Я считаю[/uquote]
Вы симулятором МПЛАБа пользоваться умеете? Ваши вопросы однозначно говорят о том, что вы даже не подозреваете о его наличии.
Ну и продолжение мазохизма в коде в стиле "а ля корабельников" да еще и в абсолютном формате не дает возможности наблюдать переменные в Watch.
Вы так ничему толковому никогда не научитесь.[/uquote]

Нет там никакого нуля, это здесь я по ошибке написал. В реальности, в программе нуля нет.

Добавлено after 37 minutes 32 seconds:
А команда "decfsz Reg,1" выполняется за два машинных цикла?
Реклама
Эиком - электронные компоненты и радиодетали
Друг Кота
Аватара пользователя
Сообщения: 7363
Зарегистрирован: Пт авг 28, 2009 21:34:30
Откуда: 845-й км.

Сообщение uldemir »

Иногда за 1, иногда за 2. Читайте даташит на микроконтроллер - там всё подробно написано.
If Program Counter (PC) is modified or a conditional test is true, the instruction requires two cycles. The second cycle is
executed as a NOP.
Реклама
Друг Кота
Аватара пользователя
Сообщения: 25560
Зарегистрирован: Чт янв 10, 2008 22:01:02
Откуда: Московская область, Фрязино

Сообщение КРАМ »

[uquote="PenguinChik",url="/forum/viewtopic.php?p=4320137#p4320137"]А команда...[/uquote]
Вообще то опыт расчета блокирующих задержек вреден... :)
В МК блокирующая задержка - зло. Задержки не должны мешать остальным задачам. Исключение составляют короткие задержки примерно до 100...200 машинных циклов. Большие делают на таймере. Причем для всех задержек используют ОДИН таймер, который работает непрерывно, генерируя прерывания, в обработчике которых и инкрементируют/декрементируют счетчики задержек. А в суперлупе просто периодически проверяются эти счетчики. Обычно такой таймер называют системным.
Реклама
Опытный кот
Аватара пользователя
Сообщения: 848
Зарегистрирован: Ср авг 03, 2022 05:22:56

Сообщение MLX90640 »

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

Ага, нашел-таки!
Pause_ver1.2.zip
(96.85 КБ) 82 скачивания
Изображение
Задержка в м.ц. - машинный цикл. А на PIC16 1 м.ц. = 4 такта осциллятора, то есть частота м.ц. в в 4 раза медленнее частоты МК. На картинке 6000 м.ц. = 24000 периодов осциллятора. И при 4 МГц показанная задержка = 6 мс.
PenguinChik вероятно не учитывает, что каждая инструкция в этих циклах занимает 1 м.ц., а инструкция сравнения и перехода - 2 м.ц. (если на память сейчас не ошибаюсь). То есть, нужно не просто циферки в счетчиках считать, а учитывать, сколько м.ц. проходит в каждом круге декремента.
Друг Кота
Аватара пользователя
Сообщения: 25560
Зарегистрирован: Чт янв 10, 2008 22:01:02
Откуда: Московская область, Фрязино

Сообщение КРАМ »

Инструкция сравнения, как уже сказали, занимает один цикл, если условие не выполняется и два - если выполняется. То есть два занимает любой переход.
Опытный кот
Аватара пользователя
Сообщения: 848
Зарегистрирован: Ср авг 03, 2022 05:22:56

Сообщение MLX90640 »

а... Ну я пишу чисто по памяти, я ж лет 7 вообще не брал в руки PIC, а на ассемблере его прогал так и того давнее.
Нашел транзистор. Понюхал.
Аватара пользователя
Сообщения: 151
Зарегистрирован: Ср дек 01, 2021 15:09:09

Сообщение PenguinChik »

[uquote="MLX90640",url="/forum/viewtopic.php?p=4320199#p4320199"]Когда-то в те времена была небольшая утилитка по расчету такой задержки. Както она называлась, чето типа Pause... Надо в своих старых архивах поискать, пользовался ведь...

Ага, нашел-таки![/uquote]

Ну да, с этой программой я разобрался. Все работает. А можно ли реализовать задержку без перезаписываний чисел в регистры? Другим способом? C помощью таймера, например
Друг Кота
Аватара пользователя
Сообщения: 7363
Зарегистрирован: Пт авг 28, 2009 21:34:30
Откуда: 845-й км.

Сообщение uldemir »

Можно, как бы странно это не звучало.
Друг Кота
Аватара пользователя
Сообщения: 25560
Зарегистрирован: Чт янв 10, 2008 22:01:02
Откуда: Московская область, Фрязино

Сообщение КРАМ »

[uquote="PenguinChik",url="/forum/viewtopic.php?p=4325415#p4325415"]C помощью таймера, например[/uquote]
Вы вообще читаете ответы?
Я же вам выше все написал. Именно про таймер... :facepalm:
[uquote="КРАМ",url="/forum/viewtopic.php?p=4320179#p4320179"]Вообще то опыт расчета блокирующих задержек вреден... :)
В МК блокирующая задержка - зло. Задержки не должны мешать остальным задачам. Исключение составляют короткие задержки примерно до 100...200 машинных циклов. Большие делают на таймере. Причем для всех задержек используют ОДИН таймер, который работает непрерывно, генерируя прерывания, в обработчике которых и инкрементируют/декрементируют счетчики задержек. А в суперлупе просто периодически проверяются эти счетчики. Обычно такой таймер называют системным.[/uquote]
Но "перезаписывать в регистры" все равно придется. Любая программа для МК наполовину состоит из такого кода.
С таймерными задержками исчезнет блокировка исполнения и исчезнет потребность считать машинные циклы для калибровки величины задержки.
OKF
Это не хвост, это антенна
Сообщения: 1432
Зарегистрирован: Вт июн 07, 2011 08:03:18

Сообщение OKF »

[uquote="PenguinChik",url="/forum/viewtopic.php?p=4320080#p4320080"]Рассчитал задержку на ассемблере с помощью программы.[/uquote]
Берёшь delay.h/delay.c из htpicc, смотришь выхлоп и не паришься, имея us и ms задержки.

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

#if XTAL_FREQ >= 12MHZ

// x <= 750 for 4mHz
#define DelayUs(x)  { unsigned char _dcnt; \
        _dcnt = (x) * ((XTAL_FREQ) / (12MHZ)); \
        while(--_dcnt != 0) \
          continue; }
#else

#define DelayUs(x)  { unsigned char _dcnt; \
        _dcnt = (x) / ((12MHZ) / (XTAL_FREQ)) | 1; \
        while(--_dcnt != 0) \
          continue; }
#endif

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

#include  "delay.h"

void DelayMs(unsigned char cnt)
{
  #if XTAL_FREQ <= 2MHZ
  do {
    DelayUs(996);
  } while(--cnt);
  #endif

  #if XTAL_FREQ > 2MHZ 
  unsigned char i;
  do {
    i = 4;
    do {
      DelayUs(250);
    } while(--i);
  } while(--cnt);
  #endif
}
Первый раз сказал Мяу!
Сообщения: 26
Зарегистрирован: Вт май 17, 2022 09:49:48

Сообщение Viktorkin »

бывают столь короткие задержки когда таймер использовать невыгодно. или бывает что по логике программы нужно именно подождать и ничего не делать. а реакции на чето там неотложное как раз по прерываниям и делать
Ответить

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