A mikrovezérlők elengedhetetlen tulajdonsága a megszakításkezelés (interrupt) lehetősége. A PIC18F családban a megszakításkezelés kétszintű, azaz, hozzá tudunk rendelni prioritási szintet az adott perifériához, amely majd kiváltja a megszakítást. Lehet például az AD átalakítás végén magasszintű megszakítást kiváltani, míg egy időzítő túlcsordulásakor alacsonyt (vagy fordítva). A PIC18F családban minden periféria (pl.: AD átalakító, SSP, Timer1, stb) képes megszakítást kiváltani.
A magasszintű megszakítás a 0x0008 címen, az alacsonyszintű megszakítási vektor pedig a 0x0018 címen található.
1. ábra Interrupt a PIC18F csalában
A Microchip által közölt ábrán (1. ábra) láthatjuk a megszakításkezelés "logikáját". Minden megszakítástkiváltó perifériához három bit (xxxIF, xxxIP, xxxIE) tartozik. Nézzük meg a Timer0 időzítő IT bitjeit.
Ahhoz, hogy a megszakításkezelést használni tudjuk, nem elég az adott perifériának ezt a lehetőségét engedélyezni, hanem "globálisan" is engedélyeznünk kell. Erre szolgál a GIE bit, amely az INTCON regiszterben találunk.
Ebben a mintakódban csak a Timer0 ad túlcsorduláskor megszakítást.
#include <p18f14k50.h>
#define LED0 LATCbits.LATC0
void InterruptHandler();
main()
{
INTCON = 0x20; // 0010 0000 : TMR0IE=1, engedélyezzük
// a TMR0 megszakításkérését
INTCON2 = 0x84; // 1000 0100 : TMR0IP = 1, magasszintű IT
RCONbits.IPEN = 0; // nem engedélyezzük a kétszintű megszakítást
TMR0H = 0; // töröljük a TMR0 számlálót
TMR0L = 0;
T0CON = 0x80; // 1000 0000 : TMR0ON=1, TMR0 engedélyezve
// 16bites mód, belső CLK, 1:2 osztás
INTCONbits.GIEH = 1; // engedélyezzük a megszakítást
TRISC = 0x00;
while(1)
{
// ide írhatjuk a kódot, amely állandóan
// meghívásra kerül, innen "lépünk" ki
// a megszakításkor
}
}
#pragma code InterruptVector = 0x08
void InterruptVector()
{
_asm
goto InterruptHandler
_endasm
}
#pragma code
#pragma interrupt InterruptHandler
void InterruptHandler()
{
// Timer0 adta a megszakítást?
if(INTCONbits.TMR0IF)
{
INTCONbits.TMR0IF = 0; // szoftveresen töröljük az IT flaget
LED0 = !LED0; // villogtatjuk a LED0-t
}
}
Most nézzük meg azt, amikor kétszintű megszakítást alkalmazunk. Magasszintű megszakítást ad a Timer0 a túlcsorduláskor, alacsonyszintűt pedig az AD átalakító, amikor véget ér az analóg átalakítás.
#include <p18f14k50.h>
void InterruptHandlerHigh();
void InterruptHandlerLow();
main()
{
INTCON = 0x20; // 0010 0000 : TMR0IE=1, engedélyezzük
// a TMR0 megszakításkérését
INTCON2 = 0x84; // 1000 0100 : TMR0IP = 1, magasszintű IT
PIE1bits.ADIE = 1; // AD átalakító megszakításának engedélyezése
IPR1bits.ADIP = 0; // alacsonyszintű megszakítás
// AD beállítása
ADCON0 = 0B00101001; // AN10 a bemenő jel, engedélyezve az AD
ADCON1 = 0B00000000; // ref fesz: Vdd, GND
ADCON2 = 0B10101010; // jobbra igazítás, 12Tad, Fosc/32
RCONbits.IPEN = 1; // engedélyezzük a kétszintű megszakítást
TMR0H = 0; // töröljük a TMR0 számlálót
TMR0L = 0;
T0CON = 0x80; // 1000 0000 : TMR0ON=1, TMR0 engedélyezve
// 16bites mód, belső CLK, 1:2 osztás
INTCONbits.GIEH = 1; // engedélyezzük a megszakítást
TRISC = 0x00;
ADCON0bits.GO = 1; // AD átalakítás indítása
while(1)
{
// ide írhatjuk a kódot, amely állandóan
// meghívásra kerül, innen "lépünk" ki
// a megszakításkor
}
}
#pragma code InterruptVectorHigh = 0x08
void InterruptVectorHigh()
{
_asm
goto InterruptHandlerHigh
_endasm
}
#pragma code InterruptVectorLow = 0x18
void InterruptVectorLow()
{
_asm
goto InterruptHandlerLow
_endasm
}
#pragma code
#pragma interrupt InterruptHandlerHigh
void InterruptHandlerHigh()
{
}
#pragma code
#pragma interrupt InterruptHandlerLow
void InterruptHandlerLow()
{
}
Azok a függvények, amelyek megszakításkor meghívásra kerülnek, üresek, azokat majd az Olvasó töltheti ki. Fontos azonban, hogy a megszakítást jelző flag-eket (pl.: PIR1bits.ADIF, INTCONbits.TMR0IF) szoftveresen törölni kell.
Ebben a cikkben egy kétsoros LCD felprogramozását és a hozzátartozó sajátfüggvényeket, makrókat mutatjuk be. Nem térünk ki viszont az LCD-k felépítésére, vezérlésére.. . . .
Ebben a cikkben egy kétsoros LCD felprogramozását és a hozzátartozó sajátfüggvényeket, makrókat mutatjuk be. Nem térünk ki viszont az LCD-k felépítésére, vezérlésére.. . . .