Добавление 1-секундной задержки на тактовой частоте 20 МГц (?)

Редактировать: PIC 16F684

Хорошо, у меня есть простые двоичные часы с 3 светодиодами, которые считают от 0 до 7, и я хочу добавить задержку примерно в 1 секунду между каждым включением света.

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

Я думаю, что частота часов составляет 4 МГц, вот скриншот руководства: http://i.imgur.com/tJatQ.png

Вот соответствующие выдержки из моего кода:

COUNT1 EQU 20h      ; Delay counter #1
COUNT2 EQU 21h      ; Delay counter #2

...

LOOP0
        MOVLW   TRIS_D0_D1      ; Move value defined in Constants to TRISA, to switch on LED 0.
        TRIS    PORTA           ;
        CLRF    PORTA           ; Clear all outputs.
        MOVLW   D0              ; Set the accumulator to the value of D0.
        MOVWF   PORTA           ; Move the accumulator to PORTA, to switch on LED 0.

    ; Using COUNTs to add a delay
        decfsz    COUNT1,1       ; Decrease COUNT1 by 1, and skip the next line if the result is 0.
        goto      LOOP0          ; If COUNT1 is 0, carry on. If not, go to LOOP0.   
        decfsz    COUNT2,1       ; Decrease COUNT2 by 1, and skip the next line if the result is 0.
        goto      LOOP0          ; If COUNT1 is 0, carry on. If not, go to LOOP0.

Тем не менее, я почти уверен, что ошибаюсь со временем, может кто-нибудь помочь мне?


person Jake Lee    schedule 29.04.2012    source источник
comment
В первом разделе определены счетчики, не так ли? И эти 2 (надеюсь) будут использоваться для создания задержки. Также я добавил в пост модель PIC. Извиняюсь.   -  person Jake Lee    schedule 29.04.2012
comment
Я мало что знаю о сборке PIC, но мне кажется, что вы считаете до 20 часов (32 десятичных знака) и 21 часа (33 десятичных знака). Но вы должны считать до 20 миллионов циклов. IIRC PIC выполняет инструкцию каждые 4 цикла. Если вы считаете свои инструкции, это будет означать, что вам нужно сосчитать до 20 миллионов / 4 цикла / 7 инструкций. Но вообще использовать такие шлейфы для задержек не очень надежно. PIC, который вы используете, обеспечивает в общей сложности 6 таймеров. Гораздо лучше использовать их для работы.   -  person Nico Erfurth    schedule 30.04.2012
comment
Есть ли нежелание смотреть техпаспорт здесь?   -  person user957902    schedule 30.04.2012
comment
User957902, вот откуда ссылка на imgur. Я не был уверен, какое значение было правильным.   -  person Jake Lee    schedule 01.05.2012


Ответы (2)


Предположение: код в LOOP0 — это код, который вы хотите выполнить один раз за задержку, а не столько раз, сколько возможно во время задержки. Я также предполагаю, что вы устанавливаете COUNT1 и COUNT2 для чего-то - код, который вы разместили, объявляет две "переменные", но не назначает их.

Код, который у вас есть на данный момент, будет многократно выполнять код LOOP0 COUNT1 + COUNT2 раз. Это потому, что каждая петля является отдельной. Это дает вам максимальную задержку 510 циклов. Как говорили другие комментаторы, PIC16 выполняют примерно одну инструкцию за цикл, поэтому вам нужно отложить 1 000 000 циклов, чтобы подождать одну секунду на частоте 4 МГц.

Если мы рассмотрим ситуацию, когда мы хотим ждать 196392 циклов, нам по существу необходимо реализовать 16-битный счетчик. Мы делаем это, уменьшая один счетчик в цикле. Каждый раз, когда этот цикл выходит, мы уменьшаем еще один счетчик. Когда оба счетчика равны нулю, цикл возвращается. Вот пример:

COUNT1 EQU 20h
COUNT2 EQU 21h

LOOP0
    ;do some stuff here
        ...

    ;delay loop starts here:
    ;assume COUNT1=0 and COUNT2=0
Delay_0
    decfsz COUNT1
    goto Delay_0
    decfsz COUNT2   ;COUNT1 = 0 so 0xff cycles have passed
    goto Delay_0
    goto LOOP0 ;both COUNT1 and COUNT2 = 0 - 196392 cycles have now passed

Инструкции ветвления стоят 1 цикл, если они не пропускаются, и 2, если пропускаются. goto всегда занимает 2 цикла, что означает, что фактическое время, необходимое для выполнения одного полного счета, составляет 767 циклов (255 * 3 + 2). Мы можем рассчитать время, необходимое для обоих, как ((255 * 3 + 2) + 3) * 255 + 2.

На Dos4Ever есть отличное объяснение процедур задержки. Здесь рассматривается, как работают процедуры задержки и как рассчитать значения счетчика и стоимость процедуры задержки.

И, наконец, если вам просто нужны процедуры задержки копирования и вставки, генератор процедур задержки в PIClist почти идеально.

person Mathew Hall    schedule 30.04.2012
comment
Хороший ответ +1! Может быть, только несколько вещей. Если мы войдем в процедуру задержки с COUNT2 равным 0, тогда должно быть выполнено 256 (а не 255) коротких циклов! И я скучаю по CLRWDT инструкции. :) - person GJ.; 01.05.2012
comment
Ура, я использовал это, чтобы понять это, очень полезно. - person Jake Lee; 01.05.2012

Приведенный выше код с двумя циклами при условии, что оба счетчика изначально установлены на ноль, занимает 197119 циклов (вместо 196392), верно?

Я имею в виду код:

  • Delay_0 decfsz COUNT1
  • перейти к Delay_0
  • COUNT2
  • перейти к Delay_0

Причина в том, что внутренний цикл, связанный с count1, будет повторяться 255 раз, что означает {255 раз по 3 цикла команд} плюс окончательный decfsz занимает 2 дополнительных цикла. Таким образом, в самый ПЕРВЫЙ раз, когда проходит этот внутренний цикл, соответствующая задержка (d1F) будет равна d1F = 255*3 + 2 = 767 циклов. Все это происходит еще до того, как мы доберемся до decfsz для count2. Затем остальная часть активности происходит, когда мы достигаем decfsz count2; который начинается с decfsz count2, за которым следует goto Delay_0, где 'goto' вызовет другую задержку внутреннего цикла (равную d1F). Таким образом, эта тройная комбинация, состоящая из decfsz count2, goto Delay_0 и d1F, будет связана со значением индекса count2, равным 255. Затем мы продолжаем получать тройные комбинации... с индексом 254, затем с индексом 253... вплоть до count2 index of 1. Это означает, что мы получаем 255 тройных комбинаций. И, наконец, мы заканчиваем с окончательным decfsz count2 (с индексом 0). Окончательная «инструкция» decfsz count2 занимает 2 цикла вместо 1. Таким образом, вторая часть задержки тогда равна (d1F+3)*255 + 2. «3» (циклы инструкции) обусловлены инструкциями decfsz плюс goto во время нормального режима работы. зацикливание.

Поэтому, когда мы сложим первую и вторую части задержки вместе, мы получим:

  • d2F = d1F + (d1F+3)x255 + 2 = 767 + (767+3)x255 + 2 = 197119

Теперь, если у нас есть несколько циклов, мы можем использовать уравнения:

  • d(n)_F = d(n-1)_F + {d(n-1)_F + 3}x255 + 2 = 256xd(n-1)_F + 767

а также

  • d(n)_C = d(n-1)_C + {d(n-1)_F + 3}x{count_n - 1} + 2

где «F» в d(n)_F или d(n-1)_F обозначает состояние, при котором все счетчики инициализируются НУЛЕВЫМ значением. И «C» в d(n)_C обозначает условие, при котором счетчик для n-го цикла инициализируется любым значением, которое мы изначально выбрали. А «n» связан с n-м циклом. А «n-1» связан с (n-1)-м циклом.

Итак, если у нас есть 2 цикла, то d(1)_F — это задержка из-за цикла №1 с «полным» количеством циклов (т. е. counter1 изначально равен НУЛЮ или 256); а d(2)_F — задержка из-за цикла № 1 И цикла № 2 для случая, когда и счетчик 1, и счетчик 2 изначально равны НУЛЮ или 256.

  • d(1)_C — это задержка из-за цикла №1 для случая, когда count1 инициализируется любым значением, которое мы изначально выбрали.
  • d(2)_C — это задержка из-за цикла №1 И цикла №2 для случая, когда count2 инициализируется любым значением, которое мы изначально выбрали.

Обратите внимание, что count_n — это НАЧАЛЬНОЕ значение счетчика для n-го цикла. Кроме того, если конкретный счетчик изначально инициализирован НУЛЕВЫМ значением, часто бывает удобно рассматривать это значение как «256». Это, конечно, для ВОСЕМЬ битного счетчика. Например, если count1 = 0, удобно рассматривать его как count1 = 256 (вместо 0).

  • Мы также можем определить: d(0)_F = 0 и d(0)_C = 0.

Таким образом, для трехконтурной системы с count1 = 1, count2 = 4 и count3 = 2,

  • d(1)_F = 256xd(0)_F + 767 = 256x0 + 767 = 767

  • d(1)_C = 0 + {0 + 3}x{1 - 1} + 2 = 2

  • d(2)_F = 256xd(1)_F + 767 = 256x767 + 767 = 197119

  • d(2)_C = d(1)_C + {d(1)_F + 3}x{4 - 1} + 2 = 2 + {767+3}x3 + 2 = 2314

  • d(3)_F = 256xd(2)_F + 767 = 256x197119 + 767 = 50463231

  • d(3)_C = d(2)_C + {d(2)_F + 3}x{2 - 1} + 2 = 199438

Система из 3 петель выглядит так:

  • Delay_0 счетчик decfsz1
  • перейти к Delay_0
  • decfsz count2
  • перейти к Delay_0
  • decfsz count3
  • перейти к Delay_0

Кенни Леонг

person user2473445    schedule 13.06.2013