loader
Foto

Órajel előállítása a PIC32MX5xx,6xx, 7xx családokban

A beágyazott rendszerek egyik építőeleme a mikrovezérlő. Nagyon sok alkalmazásnál a pontos órajel előállítása elengedhetetlen, ezért a Microchip PIC32MX5XX,6XX,7XX családok mikrovezérlőinek az órajebeállításának a lehetőségét nézzük meg ebben a cikkben.

Korábban már foglalkoztunk a PIC32MX mikrovezérlő órajelelőállításával, de most újra elővesszük ezt a témát, és most az XC32-es fordító segítségével készítjük el a különböző példáink használatát. Továbbá, a könnyebb megértés kedvéért logikai analizátor segítségével ellenőrizzük az adott program működését.

A PIC32MX795F512L mikrovezérlő órajelelőállításért a következő ábrán látható modul felel. Négy különböző órajelforrás egyikét tudjuk felhasználni a rendszerórajel (SYSCLK), illetve a periféria órajel (PBCLK) előállítására. Használhatunk tehát két külső órajelforrást (POSC, SOSC), illetve két belső órajelforrást (FRC, LPRC) is. Ha egyéb lehetőségünk nem lenne, akkor összesen négy különböző értéke lehetne a rendszerórajelnek, de az első ábrán látható még PLL, "div16", illetve még egy "Postscaler" is, így tehát az előállítandó SYSCLK konkrét értéke szinte tetszőleges lehet.

kep
1. ábra   A PIC32MX795F512L mikrovezérlő belső órajel előállítására használt modul
 

Látható az első ábrán, hogy a különböző órajelértékek egy multiplexer bemeneteire csatlakoznak, és ezek egyike fog a multiplexer kimenetén megjelenni, és ez az érték lesz a SYSCLK órajel értéke. A "COSC0", "COSC1", "COSC2" bitekkel tudjuk beállítani azt, hogy a multiplexer melyik bemenete jelenjen meg a kimeneten, amely a SYSCLK lesz.
Például, ha a belső órajelmodult szeretnénk felhasználni a SYSCLK előállítására, akkor az "FRC" (vagy az LPRC) belső modult kell alkalmaznunk. "FRC" alkalmazásával ekkor 8MHz lenne a SYSCLK, de lehetne 8MHz/16 (FRC/16) is, illetve a "Postscaler" osztóval egyéb értékekkel is le lehetne osztani a 8MHz-et. Ugyanakkor, ha 8MHz-nél nagyobb értéket szeretnénk adni a SYSCLK-nak, akkor tudunk PLL-t alkalmazni (FRCPLL). Ez a PLL szintén használható akkor, ha az elsődleges külső órajelforrást (POSC) szeretnénk igénybe venni. Másodlagos órajelforrás alkalmazásánál (SOSC) a PLL-t nem tudjuk használni, ezt mutatja az első ábra is. Igaz, ennek a belső modulnak a fő feladata a Watchdog Timer órajellel történő elllátása.

A periféria órajel a SYSCLK értékétől függ, a rendszerórajelet osztjuk le 1:1, 1:2, 1:4, 1:8 értékek egyikével (PBDIV), hogy megkapjuk PBCLK-t.

Látható tehát az, hogy a PIC32MX család zászlóshajójánál, a PIC32MX795F512L-nél az órajelbeállítás eléggé összetettnek tűnik. Használhatnánk az OSCCON regisztert, hogy a SYSCLK és a PBCLK konkrét értékeit beállítsuk, de véleményünk szerint egyszerűbb a "config" regiszterek írása. Ebben a cikkben ezt a módszert nézzük meg.

Indítsuk el az MpLABX-et, és hozzunk létre egy új projektet. Ezután a projekthez adjunk hozzá egy "C" file-t, amelybe másoljuk be a következő programot.

#include <xc.h>

#define D0  LATDbits.LATD0
#define D1  LATDbits.LATD1
#define D2  LATDbits.LATD2

void villog()
{
    D1 = ~D1;
}

int main(void)
{
    TRISD = 0x0000;
    LATD = 0x0000;
    
    while(1)
    {
        D0 = ~D0;
        villog();
    }
}

 

A program elején beolvassuk az "xc.h" header file tartalmát, pontosabban, azon keresztül annak az eszköznek a header file-ának a tartalmát, amelyet a projekt létrehozásakor kiválasztottunk. Ezután elneveztük a "D" port alsó három bitjét D0-nak, D1-nek, illetve D2-nek. Tekintettel arra, hogy nem csak az volt a cél, hogy az adott portbit állapotváltásait figyeljük logikai analizátorral, hanem arra is kiváncsiak voltunk, hogy mekkora késleltetést okoz egy függvényhívás. Ezért két portbiten (D0, D1) figyeljük az állapotváltásokat, de az egyiknél (D1) az állapotváltást egy függvényhívással valósítjuk meg. Ezért deklaráltunk egy sajátfüggvényt, a "villog()"-ot. 
A "main()" függvény futtatásával indul el a projekt, ahol először beállítjuk a "D" portot kimenetté, majd minden bitet nullázunk. Ezután a "while(1)" végtelen ciklusban először a LATD regiszter nulladik bitjét negáljuk, majd meghívjuk a "villog()" függvényt, ahol szintén a "D" port 1. bitjén állapotváltás történik. Látható a 2. ábrán, hogy a két portbiten az állapotváltás nem egyszerre történik meg, hanem kb 35us idő telik el a két portbit közötti állapotváltásnál. Tehát a két stackművelet (a függvényhívás miatt van) jelentős időkülönbséget okoz.

kep
2.ábra   Mérési eredmény (50us/div)
 

Nem tudjuk az első ábra alapján megállapítani a konkrét működési frekvenciát, hiszen a magasszíntű programozási nyelv használata miatt nem tudjuk azt, hogy egy függvényhívás, értékadás hány órajelciklust igényel.
Módosítsuk most úgy az alkalmazásunkat, hogy beállítunk konkrét műkődési frekvenciát. Legyen a rendszerórajel (SYSCLK), illetve a periféria órajel (PBCLK) 8MHz. Ebben az esetben nem kell alkalmaznunk PLL-t ezeknek az órajeleknek a beállításához, hiszen a fel tudjuk használni az "FRC"-t, amelynek a frekvenciája 8MHz. Ennek a beállítása történhet az OSCCON regiszter közvetlen értékadásával is, de általában a "pragma config"-ot alkalmazzák a config regiszterek beállításánál. Az utóbbi megoldás alkalmazásával a következők szerint módosul az alkalmazásunk.


#include <xc.h>

#define D0  LATDbits.LATD0
#define D1  LATDbits.LATD1
#define D2  LATDbits.LATD2

#pragma config POSCMOD = OFF, FSOSCEN = OFF, FNOSC = FRC
#pragma config FPBDIV = DIV_1

void villog()
{
    D1 = ~D1;
}

int main(void)
{
    TRISD = 0x0000;
    LATD = 0x0000;
    
    while(1)
    {
        D0 = ~D0;
        villog();
    }
}

 

A "POSCMOD = OFF" értékadással az elsődleges külső órajelforrást, az "FSOSCEN = OFF" értékadással pedig a másodlagos külső órajelforrást tiltottuk le. Ezért már csak a két belső órajelforrás (FRC, LPRC) egyikének a kimenetét tudjuk felhasználni a SYSCLK és a PBCLK értékeinek a beállításához. Az "FNOSC = FRC" értékadással az FRC forrást választottuk ki, amelynek a kimenete 8MHz. Tehát a SYSCLK értéke 8MHz, és mivel az "FPBDIV = DIV_1", ezért a periféria órajel is 8MHz.

kep
3. ábra   Mérési eredmény (50us/div)
 

A következő példánál növeljük a SYSCLK értékét, legyen például 80MHz. Ennek az értéknek az előállításához már igénybe kell vennünk a belső PLL hurkot is. A PLL hurok egy elő-, egy utóosztóból, továbbá egy szorzóból áll, amelyeknek konkrét értékeket kell adnunk a "pragma config" értékadásokkor. Először beállítjuk a belső órajelforrást, amely megint az FRC lesz, de bekapcsoljuk még a PLL-t is. Ezért nem a "FNOSC = FRC"-t kell alkalmaznunk, hanem az "FNOSC = FRCPLL"-t. Az "FPLLMUL = MUL_20" beállítással a PLL hurokban található szorzó értékét állítottuk be (8*20), majd az előosztó beállítása következik ("FPLLIDIV = DIV_2", 8*20/2). Végül a PLL hurok utóosztójának a beállítása következik ("FPLLODIV = DIV_1", 8*20/2/1).

#include <xc.h>

#define D0  LATDbits.LATD0
#define D1  LATDbits.LATD1
#define D2  LATDbits.LATD2

#pragma config POSCMOD = OFF, FSOSCEN = OFF
#pragma config FPBDIV = DIV_1
#pragma config FNOSC = FRCPLL, FPLLMUL = MUL_20, FPLLIDIV = DIV_2, FPLLODIV = DIV_1

void villog()
{
    D1 = ~D1;
}

int main(void)
{
    TRISD = 0x0000;
    LATD = 0x0000;
    
    while(1)
    {
        D0 = ~D0;
        villog();
    }
}

 

Fordítsuk le a módosított alkalmazásunkat, majd a kapott hex file-t töltsük le a mikrovezérlőbe. A mérési eredmény a következő ábrán látható.

kep
4. ábra   Mérési eredmény (50us/div)
 

Most zoomoljunk bele a mérési eredménybe (5. ábra).

kep
5. ábra   Mérési eredmény (5us/div)
 

Nézzük most meg azt a lehetőséget, amikor az LPRC belső órajelforrást használjuk fel a SYSCLK (és ezáltal a PBCLK) előállításához. Ennek a belső órajelforrásnak a kimenete csatlakozik a Watchdog Timer órajelbemenetére.

Ehhez a következő módosításokat kell elvégezni a tesztprogramunkon.

#include <xc.h>

#define D0  LATDbits.LATD0
#define D1  LATDbits.LATD1
#define D2  LATDbits.LATD2

#pragma config POSCMOD = OFF, FSOSCEN = OFF
#pragma config FPBDIV = DIV_1
#pragma config FNOSC = LPRC

void villog()
{
    D1 = ~D1;
}

int main(void)
{
    TRISD = 0x0000;
    LATD = 0x0000;
    
    while(1)
    {
        D0 = ~D0;
        villog();
    }
}

 

Látható a futási eredményen, hogy a logikai analizátor már nem 50us/Div osztást alkalmaz, hanem a 10ms/Div-et, tehát a periódusidő jelentősen megnőtt (6. ábra).

kep
6. ábra   Mérési eredmény (10ms/div)
 

 



Egyéb cikkek

További cikkeink ebben a témakörben

Régebbi cikkeink

Október közepén elindítjuk az Atmel 8 bites mikrovezérlőkről szóló sorozatunkat. Ehhez használnunk kell természetesen egy fejlesztőkörnyezetet is. Több ilyen is létezik, például a WinAVR, vagy az Atmel Studio. Mi az Atmel Studio-t fogjuk használni, e. . . .

A PIC18F mikrovezérlők ma is népszerű a fejlesztők körében. Noha 8 bites architektúráról beszélünk, számos érdekes és hasznos alkalmazás megvalósítható vele. Elég csak az USB-re, vagy akár az Ethernetre gondolnunk. Ezért a Szerkesztőség egy sorozat k. . . .

A Microchip által javasolt fejlesztőkörnyezet az MPLABX, amely felváltja az MPlab-ot. Használata nehézkesnek tűnhet, ezért megnézzük ennek az IDE környezetnek a használatát, készítünk egy egyszerű projektet, amely egy PIC32 mikrovezérlőre épül.. . . .