<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="da">
	<id>https://holstebro-htx.dk/index.php?action=history&amp;feed=atom&amp;title=Interrupt</id>
	<title>Interrupt - Versionshistorie</title>
	<link rel="self" type="application/atom+xml" href="https://holstebro-htx.dk/index.php?action=history&amp;feed=atom&amp;title=Interrupt"/>
	<link rel="alternate" type="text/html" href="https://holstebro-htx.dk/index.php?title=Interrupt&amp;action=history"/>
	<updated>2026-05-23T02:29:49Z</updated>
	<subtitle>Versionshistorie for denne side i Holstebro HTX Wiki</subtitle>
	<generator>MediaWiki 1.45.1</generator>
	<entry>
		<id>https://holstebro-htx.dk/index.php?title=Interrupt&amp;diff=2086&amp;oldid=prev</id>
		<title>Bar: /* Oscillator fejl interrupt */</title>
		<link rel="alternate" type="text/html" href="https://holstebro-htx.dk/index.php?title=Interrupt&amp;diff=2086&amp;oldid=prev"/>
		<updated>2022-10-17T15:46:43Z</updated>

		<summary type="html">&lt;p&gt;&lt;span class=&quot;autocomment&quot;&gt;Oscillator fejl interrupt&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;da&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Ældre version&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Versionen fra 17. okt. 2022, 17:46&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l622&quot;&gt;Linje 622:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Linje 622:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[fil:int-xx.png]]&amp;lt;br /&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[fil:int-xx.png]]&amp;lt;br /&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;#039;&amp;#039; demo-program  interrupt &amp;#039;&amp;#039;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;#039;&amp;#039; demo-program  interrupt &amp;#039;&amp;#039;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;--&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;--&amp;gt;  &lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[Kategori:JAL]]&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[Kategori:JAL]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Bar</name></author>
	</entry>
	<entry>
		<id>https://holstebro-htx.dk/index.php?title=Interrupt&amp;diff=2050&amp;oldid=prev</id>
		<title>Bar: 1 version importeret</title>
		<link rel="alternate" type="text/html" href="https://holstebro-htx.dk/index.php?title=Interrupt&amp;diff=2050&amp;oldid=prev"/>
		<updated>2022-10-17T14:56:34Z</updated>

		<summary type="html">&lt;p&gt;1 version importeret&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Ny side&lt;/b&gt;&lt;/p&gt;&lt;div&gt;Nogle&lt;br /&gt;
gange&lt;br /&gt;
har&lt;br /&gt;
man&lt;br /&gt;
brug&lt;br /&gt;
for,&lt;br /&gt;
hvad&lt;br /&gt;
man&lt;br /&gt;
måske&lt;br /&gt;
kunne&lt;br /&gt;
kalde&lt;br /&gt;
en&lt;br /&gt;
slags&lt;br /&gt;
multitasking,&lt;br /&gt;
hvor&lt;br /&gt;
man&lt;br /&gt;
udover&lt;br /&gt;
den&lt;br /&gt;
normale&lt;br /&gt;
kode,&lt;br /&gt;
der&lt;br /&gt;
kører [[FOREVER]] loop&lt;br /&gt;
også&lt;br /&gt;
har&lt;br /&gt;
noget&lt;br /&gt;
kode&lt;br /&gt;
der&lt;br /&gt;
skal&lt;br /&gt;
afvikles&lt;br /&gt;
på&lt;br /&gt;
bestemte&lt;br /&gt;
tidspunkter.&lt;br /&gt;
Det&lt;br /&gt;
kan&lt;br /&gt;
man&lt;br /&gt;
gøre&lt;br /&gt;
med&lt;br /&gt;
interrupt.&lt;br /&gt;
&lt;br /&gt;
==Hvad sker der ved interrupt==&lt;br /&gt;
Interrupt betyder at afbryde, og det der netop sker er, at den kode der afvikles bliver afbrudt af en hændelse (tid, skift på et ben, AD færdig eller hvad det kan være).&lt;br /&gt;
&lt;br /&gt;
Når koden afbrydes, så sker det ved at der kaldes en speciel adresse / rutine. &lt;br /&gt;
&lt;br /&gt;
Hvis man arbejder med interrupt i [[assembler]], så sker der det, at man kalder adresse 4 i PIC&amp;#039;en (kaldet en interrupt-vector), hvorefter man som programmør fuldt ud har ansvaret for hvad der så skal ske (typisk skal man gemme CPU-status og W-registeret), så skal man udføre noget og til slut reetablere det man har gemt, og returnere fra interruptet.&lt;br /&gt;
&lt;br /&gt;
Hvis man arbejder i [[JAL]], så er det noget enklere, da man blot skriver en interrupt-rutine, hvor man først tjekker på om det er den givne hændelse der har interruptet, og hvis det er, så udfører man det man ønsker.&lt;br /&gt;
&lt;br /&gt;
Man kan godt have flere interrupt-rutiner i JAL. Det eneste man skal være klar over er, at man ikke kvæler processoren i for mange interrupts, samt at man skal huske at afstille det der interruptede.&lt;br /&gt;
&lt;br /&gt;
==Eksempel på anvendelse af interrupt==&lt;br /&gt;
Dette eksempel gennemgår hvordan man kan lave et timer-interrupt, der sker hvert 4. millisekund, så man ud fra dette kan lave et ur der tæller sekunder, minutter og timer.&lt;br /&gt;
&lt;br /&gt;
Det centrale i interruptet er interrupt-rutinen der kan skrives som følger:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;jal&amp;quot;&amp;gt;&lt;br /&gt;
 procedure interrupt_handler is pragma interrupt&lt;br /&gt;
    if intcon_tmr0if then&lt;br /&gt;
       TMR0 = timer_value  -- Sæt timeren til den afpassede værdi&lt;br /&gt;
       tim_int &lt;br /&gt;
       -- Slet TOIF for at re-enable timer interrupt&lt;br /&gt;
       intcon_tmr0if = False&lt;br /&gt;
    end if&lt;br /&gt;
 end procedure&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Navnet på proceduren betyder ikke noget, men det er vigtigt at der står pragma interrupt, da det er disse keywords der angiver at det er en rutine der skal kaldes, når der sker et interrupt.&lt;br /&gt;
&lt;br /&gt;
Der undersøges så på det bit der hedder TMR0IF, som ligger i INTCON. Det er TiMeR 0 Interrupt Flag, altså et bit der sættes, når det er timer 0 der har udløst interruptet.&lt;br /&gt;
&lt;br /&gt;
Hvis det er Timer 0, så starter man med at skrive en ny værdi i TMR0, så den kan tælle videre derfra (beskrives senere).&lt;br /&gt;
&lt;br /&gt;
Så kaldes den procedure tim_int, der håndterer selv tids-registreringen, også mere om dette senere.&lt;br /&gt;
&lt;br /&gt;
Når vi har serviceret dette, så er det vigtigt at TMR0IF bliver afstillet igen, ellers vil der komme et nyt interrupt fra samme kilde igen, lige efter vi har returneret fra proceduren.&lt;br /&gt;
&lt;br /&gt;
For at der overhovedet kan komme et interrupt fra timeren, så skal interruptet slåes til. Det gøres som følger:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;jal&amp;quot;&amp;gt;&lt;br /&gt;
 -- Initialiser interruptet&lt;br /&gt;
 intcon_tmr0ie = True     -- Sæt timerinterrupt aktivt&lt;br /&gt;
 intcon_inte = False      -- Passiver Port B ben 0 interrupt&lt;br /&gt;
 intcon_rabie = False     -- Passiver Port B ben 4-7 kanttrigget interrupt&lt;br /&gt;
 intcon_gie = True        -- Enable interrupt generelt&lt;br /&gt;
 -- &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Her er det TMR0IE der bliver sat i INTCON. Det betyder at TiMeR 0 Interrupt Enable sættes, altså at dette interrupt nu er aktivt. Bare for en sikkerheds skyld afstilles de andre interrupts.&lt;br /&gt;
&lt;br /&gt;
Den anden ting der skal stilles for at der kan komme interrupt er at det generelle interrupt slås til ved at sætte GIE (General Interrupt Enable) i INTCON.&lt;br /&gt;
&lt;br /&gt;
===Specielt for Timerinterrupt===&lt;br /&gt;
Nu er det sikret at interruptet kan komme, og at det bliver serviceret - tilbage i indstillingerne er at bestemme hvor tit det skal komme. Her skal vi have fat i OPTION_REG og TMR0. Koden ser ud som følger:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;jal&amp;quot;&amp;gt;&lt;br /&gt;
 -- Starten af initialiseringskoden&lt;br /&gt;
 -- Bit 7 til 1 : Port B pull up disabled&lt;br /&gt;
 -- Bit 6 til 0 : Port B-0 interrupt på faldende kant&lt;br /&gt;
 -- Bit 5 til 0 : Clock til TMR0 fra den interne clock (4MHz / 4)&lt;br /&gt;
 -- Bit 4 til 0 : Kant for clock til TMR0 (ikke relevant)&lt;br /&gt;
 -- Bit 3 til 0 : Timer rate til TMR0 (hvis den er 1 er det WDT)&lt;br /&gt;
 -- Bit 2-0 Timer rate&lt;br /&gt;
 --   000       2&lt;br /&gt;
 --   001       4&lt;br /&gt;
 --   010       8&lt;br /&gt;
 --   011      16&lt;br /&gt;
 --   100      32&lt;br /&gt;
 --   101      64&lt;br /&gt;
 --   110     128&lt;br /&gt;
 --   111     256&lt;br /&gt;
 OPTION_REG = 0b_1000_0011    -- Se ovenstående eller datablad for nærmere detaljer&lt;br /&gt;
 TMR0 = timer_value&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bit 7 og 6 har ikke noget med Timer 0 at gøre, men ligger i dette register, så de er også nævnt her.&lt;br /&gt;
&lt;br /&gt;
Bit 5 angiver at takten der skal tælles med stammer fra den takt der angiver processorens hastighed - hvis man anvender en anden clock-frekvens skal man naturligvis til at ændre sine beregninger for clocken. I beregningen skal man tage højde for at der deles med 4 i forhold til den oprindelige clock-frekvens, så når vi bruger 4 MHz er den frekvens vi starter med her altså 1 MHz.&lt;br /&gt;
&lt;br /&gt;
Bit 4 er ikke relevant i denne sammenhæng, det er kun hvis man bruger et eksternt ben til at give clock-signaler, så kan det betyde noget om det er på forkant eller på bagkant det sker.&lt;br /&gt;
&lt;br /&gt;
Bit 3 angiver at den timer-hastigehed vi angiver faktisk også kommer ind i Timer 0.&lt;br /&gt;
&lt;br /&gt;
Bit 0-2 angiver med 3 bit hvilken delingsfaktor der skal på interruptet. Her har jeg valgt 011, altså at den 1 MHz vi starter med deles med 16. Det angiver hvert tællerskridt.&lt;br /&gt;
&lt;br /&gt;
Det er altså denne værdi der skrives i OPTION_REG Her angivet som en binær værdi for nemheds skyld).&lt;br /&gt;
&lt;br /&gt;
Den værdi der skrives i TMR0 er 6. Grunden til dette er at vi gerne vil have interrupt for hver 4. millisekund. Det får vi ved at TMR0 er et [[Byte]] register, og da timer 0 tæller opad, så vil det komme til at tælle 250 gange (256 - 6) inden der sker overflow, og altså interrupt. Da vi starter med 1 MHz svarer tiden til 1 mikrosekund, og hvert tælleskridt er altså 16 mikrosekunder, og når vi har 250 af dem, så får vi 250 * 16 = 4000 mikrosekunder, altså 4 millisekunder mellem hvert interrupt, under forudsætning af at vi stiller TMR0 til 6 hver gang der sker et interrupt, men det gør vi jo også i interrupt-proceduren.&lt;br /&gt;
&lt;br /&gt;
Dette var forklaringen på alle værdierne, men for at gøre det lidt lettere, så kan man få omregnet sine ønsker til koden ved at gå ind på en [http://eng-serve.com/pic/pic_timer.html pic timer calculator] for at få sine værdier, og rent faktisk også får koden (godt nok i C), men det er et godt skridt i den rigtige retning.&lt;br /&gt;
&lt;br /&gt;
Endelig så er der tilbage at forklare hvordan vi kan få sekunder, minutter og timer til at fungere. Det sker i proceduren tim_int, der ser ud som følger:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;jal&amp;quot;&amp;gt;&lt;br /&gt;
 -- Procedure der i interruptet håndterer optællingen af tid til et ur.&lt;br /&gt;
 procedure tim_int is&lt;br /&gt;
    ms_4 = ms_4 + 1&lt;br /&gt;
    if (ms_4 == 250) then&lt;br /&gt;
       ms_4 = 0&lt;br /&gt;
       sekund = sekund + 1&lt;br /&gt;
       if (sekund == 60) then&lt;br /&gt;
          sekund = 0&lt;br /&gt;
          minut = minut + 1&lt;br /&gt;
          if (minut == 60) then&lt;br /&gt;
             minut = 0&lt;br /&gt;
             time = time + 1&lt;br /&gt;
             if (time == 24) then&lt;br /&gt;
                time = 0&lt;br /&gt;
             end if&lt;br /&gt;
          end if&lt;br /&gt;
       end if&lt;br /&gt;
    end if   &lt;br /&gt;
 end procedure&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Variablen ms4 tæller fra 0 til 250, og hver gang den nulstilles er der gået 1000 millisekunder, altså et sekund, og det betyder at sekund-variablen tælles en op.&lt;br /&gt;
&lt;br /&gt;
Når sekundvariablen når 60 så nulstilles den, og minutvariablen tælles en op. Tilsvarende gøres med minutvariablen, så der tælles timer op, og timerne nulstilles så ved 24.&lt;br /&gt;
&lt;br /&gt;
Hvis man ønskede at bygge dato på, så skulle der bygges videre på denne procedure til at håndtere dag, måned og år, hvis man ville det.&lt;br /&gt;
&lt;br /&gt;
Den samlede kode, der er implementeret med display-visning ved hjælp af [[ALCD]]-modulet ligger i en [[Media:Interrupt.zip|zip-fil her]].&lt;br /&gt;
&lt;br /&gt;
==Andre interruptkilder==&lt;br /&gt;
Som standard har de PIC-kredse vi bruger følgende interrupts:&lt;br /&gt;
&lt;br /&gt;
Timer0 som vist i eksemplet før.&lt;br /&gt;
&lt;br /&gt;
Eksternt interrupt fra et ben (kan indstilles til forkant og bagkant)&lt;br /&gt;
&lt;br /&gt;
Interrupt, når EEPROM brænding er færdig.&lt;br /&gt;
&lt;br /&gt;
Interrupt på niveauskift på et antal ben - hvilke ben det er kan ses i tabellen herunder.&lt;br /&gt;
&lt;br /&gt;
Ud over det, så kan de PIC-kredse vi arbejder med andre ting med interruptet - man er selvfølgelig nødt til at gå i databladet for den enkelte processor for at se hvordan det virker, så dette er bare en oversigt over hvilke muligheder der er.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! !![[PIC16F84]]!![[PIC16F628]]!![[PIC12F675]]!![[PIC16F684]]!![[PIC16F690]]!![[PIC16F877]]&lt;br /&gt;
|-&lt;br /&gt;
|AD||align=&amp;quot;center&amp;quot;| Nej ||align=&amp;quot;center&amp;quot;| Nej ||align=&amp;quot;center&amp;quot;| Ja ||align=&amp;quot;center&amp;quot;| Ja ||align=&amp;quot;center&amp;quot;| Ja ||align=&amp;quot;center&amp;quot;| Ja &lt;br /&gt;
|-&lt;br /&gt;
|Comperator||align=&amp;quot;center&amp;quot;| Nej ||align=&amp;quot;center&amp;quot;| Nej ||align=&amp;quot;center&amp;quot;| Ja ||align=&amp;quot;center&amp;quot;| 2 stk ||align=&amp;quot;center&amp;quot;| 2 stk ||align=&amp;quot;center&amp;quot;| Nej&lt;br /&gt;
|-&lt;br /&gt;
|EEPROM||align=&amp;quot;center&amp;quot;| Ja ||align=&amp;quot;center&amp;quot;| Ja ||align=&amp;quot;center&amp;quot;| Ja ||align=&amp;quot;center&amp;quot;| Ja ||align=&amp;quot;center&amp;quot;| Ja ||align=&amp;quot;center&amp;quot;| Ja&lt;br /&gt;
|-&lt;br /&gt;
|INT - eksternt ben||align=&amp;quot;center&amp;quot;| Ja ||align=&amp;quot;center&amp;quot;| Ja ||align=&amp;quot;center&amp;quot;| Ja ||align=&amp;quot;center&amp;quot;| Ja ||align=&amp;quot;center&amp;quot;| Ja ||align=&amp;quot;center&amp;quot;| Ja&lt;br /&gt;
|-&lt;br /&gt;
|Niveau skift||align=&amp;quot;center&amp;quot;|Port B4-7||align=&amp;quot;center&amp;quot;|Port B4-7||align=&amp;quot;center&amp;quot;|Port A0-5||align=&amp;quot;center&amp;quot;|Port A0-5||align=&amp;quot;center&amp;quot;|Port A0-5 og Port B4-7||align=&amp;quot;center&amp;quot;|Port B4-7&lt;br /&gt;
|-&lt;br /&gt;
|Timer 0 (8 bit)||align=&amp;quot;center&amp;quot;| Ja ||align=&amp;quot;center&amp;quot;| Ja ||align=&amp;quot;center&amp;quot;| Ja ||align=&amp;quot;center&amp;quot;| Ja ||align=&amp;quot;center&amp;quot;| Ja ||align=&amp;quot;center&amp;quot;| Ja&lt;br /&gt;
|-&lt;br /&gt;
|Timer 1 (16 bit)||align=&amp;quot;center&amp;quot;| Nej ||align=&amp;quot;center&amp;quot;| Ja ||align=&amp;quot;center&amp;quot;| Ja ||align=&amp;quot;center&amp;quot;| Ja ||align=&amp;quot;center&amp;quot;| Ja ||align=&amp;quot;center&amp;quot;| Ja&lt;br /&gt;
|-&lt;br /&gt;
|Timer 2 (8 bit)||align=&amp;quot;center&amp;quot;| Nej ||align=&amp;quot;center&amp;quot;| Ja ||align=&amp;quot;center&amp;quot;| Nej ||align=&amp;quot;center&amp;quot;| Ja ||align=&amp;quot;center&amp;quot;| Ja ||align=&amp;quot;center&amp;quot;| Ja&lt;br /&gt;
|-&lt;br /&gt;
|USART (seriel)||align=&amp;quot;center&amp;quot;| Nej ||align=&amp;quot;center&amp;quot;| Ja ||align=&amp;quot;center&amp;quot;| Nej ||align=&amp;quot;center&amp;quot;| Nej ||align=&amp;quot;center&amp;quot;| Ja ||align=&amp;quot;center&amp;quot;| Ja&lt;br /&gt;
|-&lt;br /&gt;
|Capture Compare||align=&amp;quot;center&amp;quot;| Nej ||align=&amp;quot;center&amp;quot;| Ja ||align=&amp;quot;center&amp;quot;| Nej ||align=&amp;quot;center&amp;quot;| Ja ||align=&amp;quot;center&amp;quot;| Ja ||align=&amp;quot;center&amp;quot;| 2 stk&lt;br /&gt;
|-&lt;br /&gt;
|Oscillator Fail||align=&amp;quot;center&amp;quot;| Nej ||align=&amp;quot;center&amp;quot;| Nej ||align=&amp;quot;center&amp;quot;| Nej ||align=&amp;quot;center&amp;quot;| Ja ||align=&amp;quot;center&amp;quot;| Ja ||align=&amp;quot;center&amp;quot;| Nej&lt;br /&gt;
|-&lt;br /&gt;
|Synkron seriel||align=&amp;quot;center&amp;quot;| Nej ||align=&amp;quot;center&amp;quot;| Nej ||align=&amp;quot;center&amp;quot;| Nej ||align=&amp;quot;center&amp;quot;| Nej ||align=&amp;quot;center&amp;quot;| Ja ||align=&amp;quot;center&amp;quot;| Ja&lt;br /&gt;
|-&lt;br /&gt;
|Parallel slave port||align=&amp;quot;center&amp;quot;| - ||align=&amp;quot;center&amp;quot;| - ||align=&amp;quot;center&amp;quot;| - ||align=&amp;quot;center&amp;quot;| - ||align=&amp;quot;center&amp;quot;| - ||align=&amp;quot;center&amp;quot;| Ja &lt;br /&gt;
|-&lt;br /&gt;
|Bus Collision||align=&amp;quot;center&amp;quot;| - ||align=&amp;quot;center&amp;quot;| - ||align=&amp;quot;center&amp;quot;| - ||align=&amp;quot;center&amp;quot;| - ||align=&amp;quot;center&amp;quot;| - ||align=&amp;quot;center&amp;quot;| Ja &lt;br /&gt;
|}&lt;br /&gt;
==Demo-eksempler på interrupt==&lt;br /&gt;
&lt;br /&gt;
Demo-eksemplerne er ikke lavet til at udføre noget praktisk, men udelukkende tænkt til at demonstrere hvordan interruptet initialiseres (indstilles og sættes i gang) og lige så meget kode i interruptet til at man kan se at det fungerer - det er simple funktioner der udføres som at vippe med en udgang, så man kan måle / se reaktionen.&lt;br /&gt;
&lt;br /&gt;
Koderne kan hentes i [[media:interrupt-jal.zip|denne ZIP-fil]].&lt;br /&gt;
&lt;br /&gt;
For at interruptet kan fungere skal det slås til. Det er dels de enkelte interrupts, men også det globale interrupt GIE der skal slås til.&lt;br /&gt;
&lt;br /&gt;
Ud over dette har hovedkoden blot et tomt forever loop.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;jal&amp;quot;&amp;gt;&lt;br /&gt;
INTCON_GIE = true     -- Enable alle interrupt&lt;br /&gt;
&lt;br /&gt;
forever loop&lt;br /&gt;
   -- I denne kode sker der intet,&lt;br /&gt;
   -- men der kunne også udføres kode der ikke er så tidskritisk&lt;br /&gt;
end loop&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Interrupt koden er skrevet ud i hvert sit modul, der i princippet kan fungere individuelt. Hvert modul har sin egen interrupt-rutine, men JAL sørger for at alle interrupt-rutiner bliver serviceret.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;jal&amp;quot;&amp;gt;&lt;br /&gt;
include timer1&lt;br /&gt;
include timer2&lt;br /&gt;
include int&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Timer 0 interrupt===&lt;br /&gt;
Dette interrupt er sat op til at vippe med pin_a4 for hver 64,000 ms ved en clockfrekvens på 4 MHz.&lt;br /&gt;
&lt;br /&gt;
De 64 ms er beregnet ud fra prescaleren og den værdi TMR0 reloades med samt den clock-frekvens PIC&amp;#039;en arbejder med delt med 4.&lt;br /&gt;
&lt;br /&gt;
Ved 4 MHz får timeren en frekvens på 1 MHz, så er det så simpelt at produktet af prescaleren og den tid man reloader TMR0 med er det antal mikrosekunder man ønsker.&lt;br /&gt;
&lt;br /&gt;
 Tid = PS * Timercount = 256 * 250 = 64000 mikrosekunder&lt;br /&gt;
&lt;br /&gt;
Det timercount man får opnår man ved at reloade tælleren med en værdi, således at den kommer til at tælle 250 gange inden den løber over, så reload-værdien er 256 minus det ønskede timercount.&lt;br /&gt;
&lt;br /&gt;
 Reload TMR0 = 256 - 250 = 6&lt;br /&gt;
&lt;br /&gt;
Koden ser ud som følger:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;jal&amp;quot;&amp;gt;&lt;br /&gt;
-- Demo til Timer 0 Interrupt&lt;br /&gt;
&lt;br /&gt;
pin_a4_direction = output&lt;br /&gt;
&lt;br /&gt;
INTCON_TMR0IE = true    -- Aktiver Timer 0 interrupt&lt;br /&gt;
INTCON_TMR0IF = false   -- Afstil interruptet&lt;br /&gt;
OPTION_REG_T0CS = false    -- Timer 0 source fra Fosc/4&lt;br /&gt;
OPTION_REG_T0SE = false    -- Rising edge for T0 clock&lt;br /&gt;
OPTION_REG_PSA = false    -- Prescaler til Timer 0&lt;br /&gt;
OPTION_REG_PS = 0b_111    -- Prescaler til 256&lt;br /&gt;
&lt;br /&gt;
-- Interruptrutine - kaldes automatisk&lt;br /&gt;
procedure timer_0_int is pragma interrupt&lt;br /&gt;
   if INTCON_TMR0IF then    -- Reager på Timer 0 interrupt&lt;br /&gt;
      TMR0 = 6&lt;br /&gt;
      INTCON_TMR0IF = false&lt;br /&gt;
      pin_a4 = ! pin_a4&lt;br /&gt;
   end if&lt;br /&gt;
end procedure&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Det giver et output på pin_a4 som følger:&lt;br /&gt;
&lt;br /&gt;
[[fil:int-timer0.png]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;Output fra demo-program på timer0-interrupt&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
===Timer 1 interrupt===&lt;br /&gt;
Dette interrupt er sat op til at vippe med pin_c5 for hvert halve sekund.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;jal&amp;quot;&amp;gt;&lt;br /&gt;
-- Demo til Timer 0 Interrupt&lt;br /&gt;
&lt;br /&gt;
pin_C5_direction = output&lt;br /&gt;
&lt;br /&gt;
PIE1_TMR1IE = true    -- Enable interrupt&lt;br /&gt;
PIR1_TMR1IF = false&lt;br /&gt;
INTCON_PEIE = true    -- Aktiver ekstra interrupt (bl.a. timer 1)&lt;br /&gt;
T1CON_TMR1CS = false    -- Timer 0 source fra Fosc/4&lt;br /&gt;
T1CON_TMR1ON = true    -- Rising edge for T0 clock&lt;br /&gt;
T1CON_T1OSCEN = true    -- Prescaler til Timer 0&lt;br /&gt;
T1CON_T1CKPS = 0b_11    -- Prescaler til 8&lt;br /&gt;
&lt;br /&gt;
-- Interruptrutine - kaldes automatisk&lt;br /&gt;
procedure timer_1_int is pragma interrupt&lt;br /&gt;
   if PIR1_TMR1IF then    -- Reager på Timer 0 interrupt&lt;br /&gt;
      TMR1 = 65535 - 62500&lt;br /&gt;
      PIR1_TMR1IF = false&lt;br /&gt;
      pin_C5 = ! pin_C5&lt;br /&gt;
   end if&lt;br /&gt;
end procedure&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Det giver et output på pin_c5 som følger:&lt;br /&gt;
&lt;br /&gt;
[[fil:int-timer1.png]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;Output fra demo-program på timer1-interrupt&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
===Timer 2 interrupt===&lt;br /&gt;
Dette interrupt er sat op til at vippe med pin_a0 med forskelligt interval, startende med 1,8 ms og op til 65 ms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;jal&amp;quot;&amp;gt;&lt;br /&gt;
-- Demo til Timer 2 Interrupt&lt;br /&gt;
&lt;br /&gt;
pin_a0_direction = output&lt;br /&gt;
&lt;br /&gt;
-- Indstil timer 2 til at bestemme pulslængde&lt;br /&gt;
-- Her er demonstreret hvordan man kan få samme tider med forskellige oscillatorer&lt;br /&gt;
if target_clock == 4_000_000 then&lt;br /&gt;
T2CON_TOUTPS = 0b_0010   -- Postscaler til / 3&lt;br /&gt;
elsif target_clock == 8_000_000 then&lt;br /&gt;
T2CON_TOUTPS = 0b_0101   -- Postscaler til / 6&lt;br /&gt;
elsif target_clock == 20_000_000 then&lt;br /&gt;
T2CON_TOUTPS = 0b_1110   -- Postscaler til / 15&lt;br /&gt;
else&lt;br /&gt;
pragma error &amp;quot;Oscillatorfrekvens ikke defimeret&amp;quot;&lt;br /&gt;
end if&lt;br /&gt;
&lt;br /&gt;
-- Her sættes tiden til langsomst muligt&lt;br /&gt;
T2CON_TOUTPS = 0b_1111   -- Postscaler til / 16&lt;br /&gt;
&lt;br /&gt;
T2CON_TMR2ON = true   -- Tænd timer 2&lt;br /&gt;
T2CON_T2CKPS = 0b_10  -- Prescale 16&lt;br /&gt;
PIE1_TMR2IE = true    -- Enable interrupt&lt;br /&gt;
INTCON_PEIE = true    -- Aktiver ekstra interrupt (bl.a. timer 2)&lt;br /&gt;
&lt;br /&gt;
-- Interruptrutine - kaldes automatisk&lt;br /&gt;
procedure timer_2_int is pragma interrupt&lt;br /&gt;
   if PIR1_TMR2IF then    -- Reager på Timer 2 interrupt&lt;br /&gt;
      PIR1_TMR2IF = false&lt;br /&gt;
      PR2 = PR2 + 1       -- Lav en skiftende tid på interruptet&lt;br /&gt;
      if PR2 == 0 then&lt;br /&gt;
         PR2 = 5&lt;br /&gt;
      end if&lt;br /&gt;
      pin_a0 = ! pin_a0&lt;br /&gt;
   end if&lt;br /&gt;
end procedure&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Det giver et output på pin_a0 som følger:&lt;br /&gt;
&lt;br /&gt;
[[fil:int-timer2-1.png]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;Output fra demo-program på timer2-interrupt&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Set i en anden timebase ser det ud som følger:&lt;br /&gt;
&lt;br /&gt;
[[fil:int-timer2-2.png]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;Output fra demo-program på timer2-interrupt timebase 10 ms&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
===Kanttrigget RA2 interrupt===&lt;br /&gt;
Dette er et af de oprindelige interrupts fra de tidlige PIC-kredse, hvor man kan indstille om det er positivt gående eller negativt gående der skal interruptes på, men man kan ikke ændre på hvilket ben det er forbundet til. På [[PIC12F675]], [[PIC16F684]] og [[PIC16F690]] er interruptet placeret på pin_a2, på [[PIC16F84]], [[PIC16F628]] og [[PIC16F877]] er interruptet placeret på pin_b0.&lt;br /&gt;
&lt;br /&gt;
I dette eksempel er interruptet er sat op til at vippe med pin_a1 når der kommer en forkant på pin_a2.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;jal&amp;quot;&amp;gt;&lt;br /&gt;
-- Demo til kanttrigget Interrupt&lt;br /&gt;
&lt;br /&gt;
pin_a2_direction = input&lt;br /&gt;
pin_a1_direction = output&lt;br /&gt;
&lt;br /&gt;
INTCON_INTE = true    -- Aktiver eksternt interrupt på RA2&lt;br /&gt;
INTCON_INTF = false   -- Afstil interruptet&lt;br /&gt;
OPTION_REG_INTEDG = true    -- Rising edge of int&lt;br /&gt;
&lt;br /&gt;
-- Interruptrutine - kaldes automatisk&lt;br /&gt;
procedure int_interrupt is pragma interrupt&lt;br /&gt;
   if INTCON_INTF then    -- Reager på pin A2 kant interrupt&lt;br /&gt;
      INTCON_INTF = false&lt;br /&gt;
      pin_a1 = ! pin_a1&lt;br /&gt;
   end if&lt;br /&gt;
end procedure&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For at illustrere at der sker et skift på alle forkanter af pin_a2, så sættes pin_a2 til pin_a0, der er timer 2, som giver en varierende puls, som så bliver halveret over til pin_a1.&lt;br /&gt;
&lt;br /&gt;
Det giver et output hvor pin_a0 ar den blå kurve, og pin_a1 er den røde kurve som følger:&lt;br /&gt;
&lt;br /&gt;
[[fil:int-kant.png]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;Output fra demo-program på kant trigget interrupt på RA2&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
===Niveau-skift interrupt===&lt;br /&gt;
Dette interrupt er sat op til at vippe med pin_c6 når der kommer en forkant på pin_b4.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;jal&amp;quot;&amp;gt;&lt;br /&gt;
-- Demo til Ports A B Change Interrupt&lt;br /&gt;
&lt;br /&gt;
pin_c6_direction = output&lt;br /&gt;
pin_b4_direction = input&lt;br /&gt;
&lt;br /&gt;
INTCON_RABIE = true    -- Aktiver Timer 0 interrupt&lt;br /&gt;
INTCON_RABIF = false   -- Afstil interruptet&lt;br /&gt;
-- Mulige input er RA0 til RA5 - vær opmærksom på at oscillator og reset kan blokere:&lt;br /&gt;
-- RA4 og RA5 virker ikke, når der bruges ekstern oscillator&lt;br /&gt;
-- RA3 virker ikke ved ekstern reset&lt;br /&gt;
-- Andre mulige input er RA4 til RA7 - her kan også ligge andre funktioner&lt;br /&gt;
IOCB_IOCB4 = true     -- Enable interrupt fra pin_a3&lt;br /&gt;
&lt;br /&gt;
-- Interruptrutine - kaldes automatisk&lt;br /&gt;
procedure porta_int is pragma interrupt&lt;br /&gt;
   if INTCON_RABIF then    -- Reager på Port A Change interrupt&lt;br /&gt;
      if pin_b4 then -- reager kun på et skift til høj&lt;br /&gt;
         pin_c6 = ! pin_c6&lt;br /&gt;
      end if&lt;br /&gt;
      INTCON_RABIF = false&lt;br /&gt;
   end if&lt;br /&gt;
end procedure&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For at demonstrere dette interrupt hvor der sker et skift på alle forkanter af pin_b4, så sættes pin_a2 til pin_a0, der er timer 2, som giver en varierende puls, som så bliver halveret over til pin_a1. Denne forbindes videre til pin_b4, som så giver yderligere en halvering ud til pin_c6. På denne måde deles frekvensen med 4 - og puls-pause-tiderne ganges med 4 som det kan ses på følgende optagelse:&lt;br /&gt;
&lt;br /&gt;
[[fil:int-change.png]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;Output fra demo-program på chamge interrupt på pin_c6&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
===Serielt modtage interrupt===&lt;br /&gt;
Dette interrupt er til den serielle port i asynkront mode. Der skal indstilles hvordan den [[Seriel port|serielle port]] skal kommunikere med hastighed og antal bit. Når der ikke kommunikeres er den serielle linje høj. En asynkron seriel karakter består af en lav startbit og 8 databit samt en høj startbit som vist her:&lt;br /&gt;
&lt;br /&gt;
[[fil:int-seriel.png]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039; Asynkron seriel karakter med en lav startbit, 8 databit og en høj stopbit &amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
For at kunne kommunikere via interruptet skal man først have indstillet baudrate. Det gør man her ved at inkludere baudrate. Derefter slås de forskellige ting til for at kunne modtage asynkront og interrupte.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;jal&amp;quot;&amp;gt;&lt;br /&gt;
include baudrate&lt;br /&gt;
&lt;br /&gt;
pin_b5_direction = input   -- RX/DT pin input (modtagerben)&lt;br /&gt;
pin_b7_direction = output  -- TX/CK pin output (senderben)&lt;br /&gt;
&lt;br /&gt;
PIE1_RCIE = true      -- Aktiver serielt receive interrupt&lt;br /&gt;
PIR1_RCIF = false     -- Afstil interruptet&lt;br /&gt;
INTCON_PEIE = true    -- Aktiver ekstra interrupt (bl.a. seriel modtagelse)&lt;br /&gt;
RCSTA_SPEN = true     -- Enable den serielle port&lt;br /&gt;
TXSTA_SYNC = false    -- Sæt den serielle port til Asynkron mode&lt;br /&gt;
RCSTA_CREN = true     -- Enable modtagelse&lt;br /&gt;
&lt;br /&gt;
TXSTA_TXEN = true     -- Enable sending på den serielle port til echoet&lt;br /&gt;
var byte tx_antal = 0 -- Tæller der bruges til sending&lt;br /&gt;
var byte rc_byte      -- Den modtagne byte&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Når dette er indstillet vil man kunne modtage en byte serielt på RX-benet. Modtagelsen af en byte som den viste udløser dette interrupt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;jal&amp;quot;&amp;gt;&lt;br /&gt;
-- Interruptrutine - kaldes automatisk&lt;br /&gt;
procedure serial_rc_interrupt is pragma interrupt&lt;br /&gt;
   if PIR1_RCIF then    -- Reager på serielt modtage interrupt&lt;br /&gt;
      PIR1_RCIF = false&lt;br /&gt;
      if RCSTA_FERR then&lt;br /&gt;
         RCSTA_SPEN = false&lt;br /&gt;
         RCSTA_SPEN = true&lt;br /&gt;
      elsif RCSTA_FERR then&lt;br /&gt;
         RCSTA_SPEN = false&lt;br /&gt;
         RCSTA_SPEN = true&lt;br /&gt;
      else&lt;br /&gt;
         rc_byte = RCREG   -- Hent den modtagne byte&lt;br /&gt;
         tx_antal = 0&lt;br /&gt;
         TXREG = rc_byte   -- Send den igen som echo (vil starte TX-interrupt)&lt;br /&gt;
      end if&lt;br /&gt;
   end if&lt;br /&gt;
end procedure&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I interruptet sendes den modtagne byte tilbage på TX-benet. Dette kaldes at lave Echo.&lt;br /&gt;
&lt;br /&gt;
Når man gør det i [[jaledit]]s serielle terminal ser det ud som følger:&lt;br /&gt;
&lt;br /&gt;
[[fil:int-receive.png]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039; Visning af hvordan serielt modtage-interrupt reagerer ved at give et echo til terminalen &amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
===Serielt sende interrupt===&lt;br /&gt;
Som med modtage-interruptet kan man på den serielle port sende en byte i asynkront mode. Indstillinger med hastighed og bits gælder også for senderen. Sendingen sker ved at der skrives en karakter til senderegisteret TXREG. Dette interrupt kommer når registeret er klar til at modtage en ny karakter, så man på denne måde kan få sendt karakterer hurtigt efter hinanden.&lt;br /&gt;
&lt;br /&gt;
Der skal igen laves en række indstillinger for at få sende-interruptet til at fungere:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;jal&amp;quot;&amp;gt;&lt;br /&gt;
pin_b5_direction = input   -- RX/DT pin input (modtagerben)&lt;br /&gt;
pin_b7_direction = output  -- TX/CK pin output (senderben)&lt;br /&gt;
&lt;br /&gt;
PIE1_TXIE = true      -- Aktiver serielt receive interrupt&lt;br /&gt;
INTCON_PEIE = true    -- Aktiver ekstra interrupt (bl.a. seriel modtagelse)&lt;br /&gt;
RCSTA_SPEN = true     -- Enable den serielle port&lt;br /&gt;
TXSTA_SYNC = false    -- Sæt den serielle port til Asynkron mode&lt;br /&gt;
&lt;br /&gt;
TXSTA_TXEN = true     -- Enable sending på den serielle port til echoet&lt;br /&gt;
PIR1_TXIF = false     -- Afstil interruptet&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I dette eksempel arbejder sende-interruptet sammen med det modtage-interruptet der er beskrevet ovenfor. Når der modtages en karakter, så sendes den tilbage som et echo. Når TXREG er klar til en ny karakter kommer der et TX-interrupt, hvor man så kan fortsætte med at sende, og her sendes den samme karakter så 4 gange mere, og der sendes CR og LF som giver en ny linje i terminalvinduet. Dette er implementeret som følger:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;jal&amp;quot;&amp;gt;&lt;br /&gt;
-- Interruptrutine - kaldes automatisk&lt;br /&gt;
procedure serial_TX_interrupt is pragma interrupt&lt;br /&gt;
   if PIR1_TXIF then       -- Reager på serielt sende interrupt&lt;br /&gt;
      PIR1_TXIF = false&lt;br /&gt;
      if tx_antal &amp;lt; 6 then&lt;br /&gt;
         if tx_antal &amp;lt; 4 then&lt;br /&gt;
            TXREG = rc_byte   -- Send den sidst den modtagne byte&lt;br /&gt;
         else&lt;br /&gt;
            if tx_antal &amp;lt; 5 then&lt;br /&gt;
               TXREG = 0x0D      -- Send CR&lt;br /&gt;
            else&lt;br /&gt;
               TXREG = 0x0A      -- Send LF&lt;br /&gt;
            end if&lt;br /&gt;
         end if&lt;br /&gt;
         tx_antal = tx_antal + 1&lt;br /&gt;
      end if&lt;br /&gt;
   end if&lt;br /&gt;
end procedure&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[fil:int-transmit.png]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039; Terminal-vinduet der viser at hver karakter returneres 5 gange efterfulgt af et linjeskift &amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
===Synkron seriel port interrupt===&lt;br /&gt;
PIC&amp;#039;en kan også arbejde med synkron kommunikation - ikke testet.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang=&amp;quot;jal&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[fil:int-xx.png]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039; demo-program  interrupt &amp;#039;&amp;#039;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===AD konvertering interrupt===&lt;br /&gt;
Når man anvender AD-konvertering, så sætter man AD-konverteren i gang, og alt efter indstillingerne, så går der noget tid inden man kan aflæse det konverterede. I [[ADC holst]] biblioteket venter man blot indtil konverteringen er færdig.&lt;br /&gt;
&lt;br /&gt;
Dette interrupt kan indstilles til at ske når konverteringen er færdig, så man kan få PIC&amp;#039;en til at lave andre ting mens konverteringen sker.&lt;br /&gt;
&lt;br /&gt;
Her illustreres den opsætning der skal laves for at indstille AD-konverteringen til at fungere på pin_c2 der har tilknyttet analog kanal 6:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;jal&amp;quot;&amp;gt;&lt;br /&gt;
pin_c2_direction = input   -- Analog kanal 6 input&lt;br /&gt;
jansel_ans6 = true         -- Sæt kanal 6 som AD&lt;br /&gt;
adcon1_adcs = 0b_110       -- 16 us clock ved 4 MHz (176 us konvertering)&lt;br /&gt;
adcon0_vcfg = false        -- Vref til Vdd&lt;br /&gt;
adcon0_adfm = false        -- Venstre-justeret output&lt;br /&gt;
adcon0_chs = 0b_0110       -- Konverter kanal 6&lt;br /&gt;
adcon0_adon = true         -- Slå AD&amp;#039;en til&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Herefter ses det der skal til for at AD-konverteren interrupter:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;jal&amp;quot;&amp;gt;&lt;br /&gt;
PIR1_ADIF = false     -- Afstil interruptet&lt;br /&gt;
PIE1_ADIE = true      -- Aktiver AD interrupt&lt;br /&gt;
INTCON_PEIE = true    -- Aktiver ekstra interrupt (bl.a. seriel modtagelse)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For at teste sættes pin_c3 som output og der defineres en variabel til AD-konverterings resultatet. Som det sidste startes AD-konverteringen for at sætte gang i festen.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;jal&amp;quot;&amp;gt;&lt;br /&gt;
pin_c3_direction = output  -- til test&lt;br /&gt;
var byte ad_byte      -- Den modtagne byte&lt;br /&gt;
adcon0_go = true      -- Start konverteringen&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Selve interruptet aflæser AD-resultatet og vipper med pin_c3 til testen, og den næste konvertering sættes i gang.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;jal&amp;quot;&amp;gt;&lt;br /&gt;
-- Interruptrutine - kaldes automatisk&lt;br /&gt;
procedure serial_ad_interrupt is pragma interrupt&lt;br /&gt;
   if PIR1_ADIF then       -- Reager på AD interrupt&lt;br /&gt;
      PIR1_ADIF = false&lt;br /&gt;
      ad_byte = ADRESH     -- Hent den konverterede byte&lt;br /&gt;
      pin_c3 = ! pin_c3    -- Lav en indikation i hardwaren&lt;br /&gt;
      adcon0_go = true     -- Sæt en ny konvertering i gang&lt;br /&gt;
   end if&lt;br /&gt;
end procedure&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Som det kan ses her løber den rundt på 210 us. Grunden til at tiden er længere end 176 us er at interruptet skal reagere og der udføres lidt kode inde i interruptet inden den næste konvertering startes.&lt;br /&gt;
&lt;br /&gt;
[[fil:int-ad.png]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039; Illustration der viser at AD-interrupt sker med 210 us mellemrum &amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
===Compare/Capture Timer 1 interrupt===&lt;br /&gt;
Dette interrupt har mange forskellige indstillinger til timer 1 sammen med CCPR1 der er et sammenlignings-register, som kan udløse interrupt når registeret og timer 1 har samme værdi. Indstillingsmulighederne ligger på hvad der skal ske med timer 1 når der er lighed, og hvordan interruptet skal dannes (deling med 1, 4 eller 16).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang=&amp;quot;jal&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[fil:int-xx.png]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039; demo-program  interrupt &amp;#039;&amp;#039;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===EEPROM write operation interrupt===&lt;br /&gt;
En skrivning til EEPROM tager en vis tid. Dette interrupt anvendes til at registrere hvornår skrivningen er færdig, så man kan skrive næste byte.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang=&amp;quot;jal&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[fil:int-xx.png]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039; demo-program  interrupt &amp;#039;&amp;#039;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Comperator C1 interrupt===&lt;br /&gt;
Den analoge comperator C1 kan indstilles til sammenligning med en spænding enten eksternt eller internt. Ved enten positivt eller negativt skift kan det indstilles til at give et interrupt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang=&amp;quot;jal&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[fil:int-xx.png]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039; demo-program  interrupt &amp;#039;&amp;#039;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Comperator C2 interrupt===&lt;br /&gt;
Den analoge comperator C2 kan indstilles til sammenligning med en spænding enten eksternt eller internt. Ved enten positivt eller negativt skift kan det indstilles til at give et interrupt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang=&amp;quot;jal&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[fil:int-xx.png]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039; demo-program  interrupt &amp;#039;&amp;#039;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Oscillator fejl interrupt===&lt;br /&gt;
Der kan internt i PIC&amp;#039;en registreres om oscillatoren har fungeret korrekt (givet konstant frekvens). Hvis der har været en fejl kan der udløses et interrupt, men selvfølgelig først efter oscillatoren er kommet i gang igen, da det kræver oscillator at gennemføre kode, altså også et interrupt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang=&amp;quot;jal&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[fil:int-xx.png]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039; demo-program  interrupt &amp;#039;&amp;#039;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Kategori:JAL]]&lt;/div&gt;</summary>
		<author><name>Bar</name></author>
	</entry>
</feed>