This is an old revision of the document!


Table of Contents

Periodic interrupt

Vajalikud teadmised: [HW] Controller module, [HW] User Interface Module, [AVR] Interrupts, [AVR] Counters/Timers, [LIB] Pins, [LIB] Delay, [LIB] Timers, [PRT] Software delay

Teooria

Käesoleva praktilise harjutuse eesmärk on demonstreerida katkestuste kasutamist loendurite näitel. Katkestused on mikrokontrolleris esinevatele sündmustele reageerivad programmilõigud. Katkestusi kasutatakse tavaliselt kiiresti sündmusele reageerimiseks, kuid neid võib kasutada ka mitme paralleelse protsessi täitmiseks, täpselt ajastatud tegevuseks ning voolu säästmiseks. Näiteks on katkestuste abil võimalik panna vilkuma LED, mille vilkumise sagedus ei sõltu sellest, mis programmis parasjagu toimub.

Praktika

Järgnev programm näitab, kuidas seadistada loendurit katkestust tekitama. Programmis on kasutusel 2 digitaalse mooduli LED-i, millest punase olekut muudetakse perioodiliselt tarkvaralise viitega ja roheline, mille olekut muudetakse katkestuse tekkimisel. Tarkvaralise viitega LED-i vilgutamise kohta on olemas eraldi harjutus ja seda siinkohal selgitatud pole. Põhieesmärk on selgitada loendurite teegi ja katkestuste kasutamist.

Programmi alguses toimub 16-bitise loendur/taimer 1 seadistamine funktsiooniga timer1_init_ctc. Selle funktsiooni abil seatakse loendur CTC (inglise keeles clear timer on compare match) režiimi, kus taimeri maksimaalseks väärtuseks pole mitte 216 - 1, vaid see on valitav. Antud juhul määratakse maksimaalseks väärtuseks ICR1 registri väärtus. Loenduri jaguriks on 1024 ja ICR1 väärtuseks 14400, mille tulemusena 14,7456 Mhz taktsageduse puhul on loenduri perioodiks täpselt 1 sekund. Seda on lihtne arvutada valemist:

f = 14745600 Hz / 1024 / 14400 = 1

Pärast loendur 1 maksimaalse väärtuse saavutamise katkestuse lubamist tuleb katkestuse tekkimine lubada ka globaalselt, ehk siis üle kogu mikrokontrolleri. Globaalseks katkestuste lubamiseks on funktsioon sei ja keelamiseks cli. Nende funktsioonide ja katkestuste programmilõigu defineerimiseks peab programmi kaasama ka avr/interrupt.h päisefaili. Katkestuse programmilõik defineeritakse makrofunktsiooniga ISR, mille parameetriks on katkestuse vektori nimi. Loendur 1 väärtuse saavutamise katkestuse vektori nimi on TIMER1_CAPT_vect.

//
// Kodulabori loenduri katkestusega vilkuva LED näide.
// Võrdluseks katkestusega vilkuvale LED-ile
// töötab paralleelselt ka tarkvaralise viitega vilkuv LED.
//
#include <homelab/pin.h>
#include <homelab/delay.h>
#include <homelab/timer.h>
#include <avr/interrupt.h>
 
//
// LED-ide viikude määramine
//
pin led_red   = PIN(C, 5);
pin led_green = PIN(C, 3);
 
//
// Katkestus
//
ISR(TIMER1_CAPT_vect)
{
	// Rohelise LED oleku muutmine
	pin_toggle(led_green);
}
 
//
// Põhiprogramm
//
int main(void)
{
	// LED-ide viikude väljundiks seadmine
	pin_setup_output(led_red);
	pin_setup_output(led_green);
 
	// Taimeri seadistamine CTC režiimi	
	timer1_init_ctc(
		TIMER1_PRESCALE_1024,
		TIMER1_CTC_TOP_ICR);
 
	// Taimeri maksimaalne väärtus 14400 mis
	// teeb perioodi pikkuseks 1s
	// Valem: 14,7456Mhz / 1024 = 14400
	timer1_set_input_capture_value(14400);
 
	// Väärtuse saavutamise katkestuse lubamine
	timer1_input_capture_interrupt_enable(true);
 
	// Globaalne katkestuste lubamine
	sei();
 
	// Lõputu tsükkel
	while (true)
	{
		// Tarkvaraline paus 1000 millisekundit
		sw_delay_ms(1000);
 
		// Punase LED oleku muutmine
		pin_toggle(led_red);
	}
}

Programmi käivitades on näha, et hoolimata sellest, mida mikrokontroller põhiprogrammis teeb, toimuvad katkestused ja roheline LED vilgub.

Kui programmil lasta töötada mõni minut, tuleb välja oluline aspekt, mida tarkvaralise viite harjutuses nii lihtsalt näha polnud. Kuigi punast LEDi vilgutavas tsüklis olev viide on 1000 ms, siis tegelik aeg, mis kulub iga tsükli täitmiseks, on natukese suurem. Põhjus on selles, et ka LED-i oleku muutmine, viite funktsiooni väljakutsumine ja tsükli täitmine võtavad protsessoril mõned taktid täitmise aega. Tulemusena jääb punase LED-i vilkumine rohelise LED-i vilkumisest pidevalt maha. Just sel põhjusel ei ole soovitatav ka kellaaja loendureid ja muid täpselt ajastatud tegevusi teha viitega, vaid loenduri katkestustega.

en/examples/timer/periodic_interrupt.1265633919.txt.gz · Last modified: 2020/07/20 09:00 (external edit)
CC Attribution-Share Alike 4.0 International
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0