• 1
  • 2

Spomalenie Delay

. .

Spomalenie, (funkcia Delay()) je závislé od vnútornej frekvencie nastaveného oscilátora. Keďže procesor umožňuje
po delení rôzne frekvencie, nastavenie oneskorenia klasickým cyklom "for", a spomalenie na jeden inštrukčný
cyklus procesora príkazom asm("nop") by bolo veľmi neefektívne.

 

V konečnom dôsledku by spomalenie jedným inštrukčným cyklom asm("nop") trvalo v rôznych režimoch vnútornej
oscilácie rôzny čas a oživenie (napríklad displeja) by bolo možné len pri zvolených časových hodnotách danej frekvencie.

Pri frekvencií napríklad 4 MHz, by 1 us trvala dlhšie než pri 8 Mhz. Z tochto dôvodu je jasné, že musíme nájsť takú matematickú rovnicu, ktorá pre všetke druhy frekvencií bude poskytovať taký časový kooeficient spomalenia, aby boli časy rovnaké.

Pomocou PPLDIV možme mcu nastaviť požadovanú frekvenciu v rozmedzí:
NoDiv - 4 MHZ
Div by 2 - 8 MHZ
Div by 3 - 12 MHZ
Div by 4 - 16 MHZ
Div by 5 - 20 MHZ
Div by 6 - 24 MHZ

Keď si všimneme, najmenšou možnou frekvenciou sú 4 Mhz.

To využijeme ako počiatočný základ navrhnutia funkcie. Budeme brať v úvahu, že pri 4 Mhz bude jedna us trvať jeden inštrukčný cyklus "nop". Koeficient spomalenia bude v tomto bode nulový. Rozdiel medzi jednotlivými frekvenčnými bodmi je 4 Mhz.
Pri 8 Mhz, bude 1 us o 4 Mhz rýchlejšia. Je to dvojnásobok, a preto potrebujeme koeficient spomalenia 2 - tzn. inštrukčný cyklus sa u nastavenia 8 Mhz pre 1us vykoná 2 krát. Pri 2 us sa vykoná 4 krát.
Pri 4 Mhz sme stanovili nulový časový koeficient a preto sa pre 1us vykoná jeden "nop", pre 2us "nop->nop".

Z pozorovania vidíme, ze pre 12 Mhz bude koeficient 4, čiže vždy dvojnásobok predošlého.
1 Mhz = 1000000 Hz, pre 4 Mhz = ((4000000- 2000000)/1000000) - (4000000 / 2)/1000000 = 0.
Pri dosadení 8000 bude výsledok 2.

Číslo bude naša neznáma a funkcia časového koeficientu bude:
((x - 2000000)/1000000) - (x / 2)/1000000.

Návrh funkcie spomalenia pre vnútorné frekvencie MCU pic 24FJx. Pri definovaní rôznych frekvencií _v_clock_, sa vypočíta funkciou _Clock(x) rôzny koeficient spomalenia.

config_diall.h


#ifndef _v_clock_
#define _v_clock_ 4000000
#endif

#ifndef _Clock
#define _Clock(x) ((x - 2000000)/1000000)-(x/2)/1000000
#endif

#define NOP10() asm("nop;nop;nop;nop;nop;nop;nop;nop;nop;nop")
#define NOP1() asm("nop")

void Delay_us (int __us__)
     {
         unsigned i;
             for(i = 0; i <= __us__* _Clock(_v_clock_); i++)
                 {
                    NOP1();
                 }
     }

void Delay_ms (int __ms__)
     {
         unsigned ms_cycl, us_cycl;
             for(ms_cycl = 0; ms_cycl <= __ms__ * _Clock(_v_clock_); ms_cycl++)
                 {
                    for(us_cycl = 0; us_cycl <= 100; us_cycl++)
                        {
                           NOP10();
                        }
                 }
     }

void Delay_s (int __s__)
     {
         unsigned s_cycl, ms_cycl;
             for(s_cycl = 0; s_cycl <= __s__ * _Clock(_v_clock_); s_cycl++)
                 {
                    for(ms_cycl = 0; ms_cycl <= 1000; ms_cycl++)
                        {
                           Delay_ms(1);
                         }
                 }
    }



Funkcie Delay() sú implementované ako súčasť hlavičkového súboru config_diall.h, odkaz >> TU <<

Ako defaultná frekvencie (ak nie je definovaná) sa berie frekvencia 4MHz .
Pokiaľ by sme MCU nastavilí na inú frekvenciu, napr. 8MHz, je nutné túto frekvenciu (v Hz) definovať v súbore main.c .

main.c


#define _v_clock_ 8000000 

#include "config_diall.h"

...code...