uy - Internetni sozlash
Atmega8 da uzilishlar. Trening kursi

ATmega8 mikrokontrollerining afzalliklaridan biri uning turli xil uzilishlarning keng doirasi hisoblanadi.

Interrupt bu hodisa ro'y berganda asosiy dasturning bajarilishi to'xtatiladi va ma'lum turdagi uzilishni boshqaradigan funksiya chaqiriladi.

Interruptlar ichki va tashqi bo'linadi. Ichki uzilishlar manbalariga o'rnatilgan mikrokontroller modullari (taymerlar, USART qabul qiluvchisi va boshqalar) kiradi. Tashqi uzilishlar tashqi signallar mikrokontroller pinlariga kelganda sodir bo'ladi (masalan, RESET va INT pinlaridagi signallar). Uzilishning paydo bo'lishiga olib keladigan signallarning tabiati nazorat registrida o'rnatiladi MCUCR, xususan, bitlarda - INT 0 kiritish uchun ISC00 (bit 0) va ISC01 (bit 1); INT1 kiritish uchun ISC10 (bit2) va ISC11 (bit3).

ATmega8 mikrokontrollerida har bir uzilishning o'ziga xos xususiyati bor uzilish vektori(belgilangan uzilish tartibiga o'tish buyrug'i saqlanadigan dastur xotirasi maydonining boshidagi manzil). Mega8-da barcha uzilishlar bir xil ustuvorlikka ega. Agar bir vaqtning o'zida bir nechta uzilishlar sodir bo'lsa, birinchi navbatda pastki vektor raqamiga ega bo'lgan uzilish qayta ishlanadi.

Atmega8 da uzilish vektorlari

Manzil Uzilish manbai Tavsif
0x0000 QAYTA O'RNATISH Qayta tiklash signali
0x0001 INT0 INT0 kiritishda tashqi uzilish so‘rovi
0x0002 INT1 INT1 kiritishda tashqi uzilish so‘rovi
0x0003 T/C1 T/C1 taymerini yozib olish
0x0004 T/C1 Match T/C1 taymer solishtiring Registr A
0x0005 T/C1 T/C1 taymerining B solishtirma registriga mos keling
0x0006 T/C1 T/C1 hisoblagich to'lib toshgan
0x0007 T/C0 T/C0 hisoblagich to'lib toshgan
0x0008 SPI SPI maʼlumotlarini uzatish tugallandi
0x0009 UART UART qabul qiluvchisi ma'lumotlarni qabul qilishni tugatdi.
0x000A UART UART ma'lumotlar registri bo'sh
0x000B UART UART qabul qiluvchi orqali ma'lumotlarni uzatish tugallandi
0x000C ANA_COMP Analog komparatordan uzilish

Interruptni boshqarish

ATmega8-da uzilishlarni boshqarish uchun 4 ta registr javobgar:

GIMSK(aka GICR) - INT0, INT1 kirishlaridagi signallarga asoslangan uzilishlarni taqiqlash/yoqish

GIFR- barcha tashqi uzilishlarni boshqarish

TIMSK, TIFR- taymerlar/hisoblagichlardan uzilishlarni boshqarish

Roʻyxatdan oʻtish GIMSK (GICR)

INTFx=1: INTx kirishida uzilish yuz berdi. Uzilishlarni qayta ishlash tartibiga kirishda INTFx avtomatik ravishda jurnal holatiga qaytariladi. 0

Roʻyxatdan oʻtish TIMSK

7 6 5 4 3 2 1 0
TOIE1
OCIE1A
OCIE1B
-
TICIE
-
TOIE0
-

TOIE1=1: T/C1 to'lib ketish uzilishi yoqilgan

OCIE1A=1: taqqoslash registr A T/C1 hisoblagichi tarkibiga mos kelganda uzilish yoqilgan

OCIE1B=1: taqqoslash registri B T/C1 hisoblagichi tarkibiga mos kelganda uzilish yoqilgan

TICIE=1: suratga olish sharti bajarilganda uzilish yoqiladi

TOIE0=1: T/C0 to'lib ketish uzilishi yoqilgan

Roʻyxatdan oʻtish TIFR

7 6 5 4 3 2 1 0
TOV1
OCF1A
OCF1B
-
ICF1
-
TOV0
-

TOV1=1: T/C1 to'lib ketdi

OCF1A=1: taqqoslash registr A ruxsat etilgan T/C1 hisoblagichining mazmuniga to'g'ri keldi

OCF1B=1: solishtirish registri B ruxsat berilgan T/C1 hisoblagichining mazmuniga mos keladi

ICF=1: qo'lga olish shartlari bajarildi

TOV0=1: T/C0 oshib ketdi

Interruptni qayta ishlash quyi dasturiga kirishda uzilishga mos keladigan TIFR registr bayrog'i avtomatik ravishda jurnal holatiga qaytariladi. 0

Uzilishlar faqat SREG holat registrida umumiy uzilishlar yoqilganda ishlaydi (bit 7 = 1). Uzilish sodir bo'lganda, bu bit avtomatik ravishda 0 ga qayta o'rnatiladi va keyingi uzilishlarni o'chiradi.

Ushbu misolda, INT0 pinini tortib olish usulida kiritish yoqilgan. Tugma yordamida pinni yerga qisqartirganda, unga mantiqiy 0 o'rnatiladi (signalning qirrasi ta'minot kuchlanishidan 0 ga tushadi) va portning nol piniga ulangan lampochkani yoqib, uzilishni qayta ishlash moslamasi ishga tushadi. B

bekor lampON()
{
PORTB.0=1;
DDRB.0=1;
}

interrupt void ext_int0_isr (void)
{
lampON();
}

DDRD.2=0;
PORTD.2=1;

SREG|= (1 vaqt(1) (

Yuqoridagi misol, shuningdek, Code Vision AVR (interrupt void ext_int0_isr(void)) da uzilish vektorlari qanday o'rnatilishini ko'rsatadi. Boshqa holatlar uchun uzilish vektorlari xuddi shunday o'rnatiladi:

EXT_INT0 2
EXT_INT1 3
TIM2_COMP 4
TIM2_OVF 5
TIM1_CAPT 6
TIM1_COMPA 7
TIM1_COMPB 8
TIM1_OVF 9
TIM0_OVF 10
SPI_STC 11
USART_RXC 12
USART_DRE 13
USART_TXC 14
ADC_INT 15
EE_RDY 16
ANA_COMP 17
TWI 18
SPM_READY 19

Avvalo, uzilish nima?
Interrupt - bu boshqaruvchi kirishiga signal kelganda bajariladigan funksiyaning bir turi.
AVR Studio da ishlaganda uzilishlar makroslar yordamida yaratiladi ISR() , SIGNAL() Va UZISH (). Ular ba'zi funksiyalarni uzilish ishlovchisi sifatida belgilaydilar. Ularning farqi shundaki UZISH () Va ISR() Umumiy uzilish yoqilgan holatda ishlov beruvchi funksiyasini aniqlang (ishlovchi uzilishi mumkin) va SIGNAL() umumiy uzilish o'chirilgan hol uchun.

Bu bilan, keling, nazariyani tugatamiz va amaliyotga o'tamiz (garchi quyida ko'proq nazariya bo'ladi).
Keling, IShIDda quyidagi diagrammani tuzamiz:

Ehtimol, siz allaqachon taxmin qilganingizdek, biz diodani yondiradigan va o'chiradigan uzilishni (tugma tomonidan yaratilgan) yozamiz.
Shunday qilib, studiyani oching va standart loyiha yarating.
Uzilishlardan foydalanish uchun sarlavha faylini kiriting:

#o'z ichiga oladi

Keling, rozi bo'laylik, uzilish (jismoniy) boshqaruvchi oyog'idagi quvvatni yoqmaydi yoki o'chirmaydi (men buni allaqachon amalga oshirilgan deb hisoblaganimdek), faqat bayroqni o'zgartiradi. Muayyan qiymatlarda diyot yoqiladi va o'chiriladi.
Keling, ushbu bayroqni global miqyosda o'rnatamiz:

Int soni = 1;

Endi uzilishni e'lon qilamiz:

ISR(SIG_INTERRUPT1)( agar (num == 1) num = 0; boshqa raqam = 1; )

Ko'rib turganingizdek, uzilish vektori makro qavslarda ko'rsatilgan. Bu vektor kompilyatorga qaysi kirish uchun uzilish yaratilishini bildiradi. INT1 uchun bu SIG_INTERRUPT1. ADC uchun, masalan, bu SIG_ADC. (butun ro'yxat "Shpak Yu.A. AVR va PIC mikrokontrollerlari uchun C da dasturlash" kitobida mukammal tasvirlangan.)
Endi "dasturimiz" ning asosiy funktsiyasiga o'tamiz.
Umuman olganda, INT1 uchun uzilishlarni yoqishimiz kerak:

Sei(); // umuman GIMSK |= (1<

Bu bajarilgandan so'ng, siz uzilish xatti-harakatini sozlashingiz kerak. U turli yo'llar bilan yaratilishi mumkin.
Ma'lumotlar jadvalini yuklab oling (loyihani yaratishda havola mavjud) va uzilishlar bo'limida quyidagi jadvalni toping:

Buni qanday tarjima qilishni tushunasiz deb o'ylayman.
Har bir "INT1 ga mantiqiy o'zgartirish" uchun uzilishni yaratish holatini o'rnatamiz.

MCUCR = (0<

Keling, butun C portini chiqish sifatida o'rnatamiz:

DDRC = 0xff; // port C - chiqish

Xo'sh, bu allaqachon aniq bo'lishi kerak:

Holbuki (1)( agar (num == 1) PORTC |= 1; // birinchi chiqishni yoqing C aks holda PORTC &= ~1; // birinchi chiqishni o'chiring C _delay_ms(100); // 100ms kuting)

Kutishning hojati yo'q. Bundan tashqari, bu samaradorlikni pasaytiradi. Lekin men buni shunday xohlayman.
To'liq dastur:

#define F_CPU 8000000UL // 8MHz #include #o'z ichiga oladi #o'z ichiga oladi int soni = 1; ISR(SIG_INTERRUPT1)( if (num == 1) num = 0; else num = 1; ) int main (void)( sei(); GIMSK |= (1)<

Biz hexni tuzamiz va Proteusda sxemani yig'amiz. Tugma o'rnini o'zgartirganda biz uzilish funksiyasidan rohatlanamiz.

Ko'pincha mikrosxema jimgina ishlashi va ishlashi kerak, ammo biron bir hodisa uchun hamma narsani tashlab, boshqa biror narsa qiling. Va keyin - yana asl vazifaga qayting ... Bu soatga o'xshaydi, masalan - budilnik vaqti kelguncha vaqtni ko'rsatadi. Va tashqi ta'sirlar yo'qdek tuyuladi - tugmani bosish, qayta o'rnatish - va mikrosxema o'zini o'zi o'zgartiradi.

Buni uzilishlar yordamida amalga oshirish mumkin - protsessorga voqea sodir bo'lganligi haqida xabar beradigan signallar.

Kundalik hayotdan bir misol - siz oshxonada malina murabbosi va mazali taomlar bilan choy ichib, mehmonlarni kutasiz. Biror kishi kelganini qanday bilasiz? Ikkita variant bor: yoki murabbodan tanaffus qilamiz, men choyni aytmoqchiman, har besh daqiqada va eshik oldida kimdir turibdimi yoki yo'qligini bilish uchun yuguramiz yoki eshik qo'ng'irog'ini sotib olib, kimdir jiringlaguncha tinchgina issiq joyda kutamiz.

Shunday qilib, mehmon chaqirganda, bu voqea. Shunga ko'ra, biz sindirib, eshikka shoshilamiz.

Shunday qilib, mikrosxemada uzilishlar mavjud. Va faqat bitta emas. Uzilishlar tashqi qismlarga bo'linadi - ular mikrosxemaning ba'zi pinlarida (INT0, INT1 va ba'zan butun PCINT portida) ma'lum bir kuchlanishda ishga tushiriladi - va ichki - hisoblagich to'lib ketganda, kuzatuvchi taymer ishga tushiriladi, USART-dan foydalanganda, analog komparator, ADC va boshqa tashqi qurilmalar uzilib qolganda.

Shunga ko'ra, ustuvor muammo paydo bo'ladi. Go'yo biz hali ham o'tirib, choy ichamiz, lekin ular nafaqat bizning eshik qo'ng'irog'ini jiringlaydilar, balki telefonda ham ... Va sizni parchalab bo'lmaydi, birinchi navbatda biror narsa qilish kerak. Shuning uchun ma'lumotlar varaqasi uzilish vektorlari jadvalini o'z ichiga oladi. Interrupt soni qancha past bo'lsa, u shunchalik yuqori ustuvorlikka ega.

Bu erda bir nechta nozikliklar mavjud ...

Voqea sodir bo'ldi - uzilish so'rovi yuborildi, ya'ni "uzilish so'rovi bayrog'i" o'rnatildi. Har bir narsa yaxshi bo'lsa, uzilish hal qilinadi, keyin hayot ajoyib va ​​u qayta ishlanadi.

Ammo agar uzilish o'chirilgan bo'lsa - masalan, yuqoriroq darajadagi uzilish allaqachon qayta ishlanayotgan bo'lsa - bu so'rov bayrog'i uzilishlar yoqilgunga qadar osilgan holda qoladi. Shundan so'ng, chip so'rovlar registrini ustuvorlik tartibida tekshiradi va agar bayroq mavjud bo'lsa, uni qayta ishlaydi.

LEKIN! Ma’lum bo‘lishicha, uzilish qayta ishlansa ham, unga sabab bo‘lgan voqea tirikligi haqiqat emas... Bu xuddi eshik qo‘ng‘irog‘i va telefon bir vaqtda jiringlagandek, siz telefonga javob berdingiz, mehmonlar esa allaqachon. uyda hech kim yo'qligiga qaror qildi va ketdi. Va go'yo voqea sodir bo'ldi - eshik qo'ng'irog'i jiringladi, lekin eshik ortida hech kim yo'q edi.

Yana bir muammo shundaki, boshqa uzilish qayta ishlanayotganda va so'rov bayrog'i allaqachon ko'tarilgan bo'lsa, hodisa yana bir necha marta sodir bo'lishi mumkin. Biz qo'ng'iroqqa javob berdik, eshikni ochdik - va u erda allaqachon ko'plab mehmonlar bor edi! Qo'rqinchlimi? Qo'rqinchli...

Interruptlardan foydalanishning yana bir xususiyati - va nafaqat uzilishlar: qayta kirish (yoki qayta kirish).

Qayta kiruvchi dastur - bu bir nechta foydalanuvchilar (yoki jarayonlar) tomonidan chaqirilishi mumkin bo'lgan dastur bo'lib, hech bo'lmaganda xatoga yo'l qo'ymaydi va maksimal hisob-kitoblarni behuda sarflamaydi, masalan, boshqa foydalanuvchi kodni qayta ishga tushirishi shart emas.

Boshqacha qilib aytadigan bo'lsak, oshxonada mehmonlarni kutib olayotganda, hech kim shirinliklarni o'g'irlamasa, hamma narsa qayta tiklanadi)

Umuman olganda, bu jiddiy narsa - agar siz buni hisobga olmasangiz, "nega ishlamayapti?!" bilan uzoq vaqt azob chekishingiz mumkin. Buni hisobga olish kerak, masalan, bir nechta uzilishlar qayta ishlansa va ularning har biri global o'zgaruvchini o'zgartirsa...

Tanaffuslar odatda qayta kiritilmaydi. Ya'ni, uzilish ishlayotgan vaqtda, siz yana bir xil uzilishni chaqira olmaysiz.Bu ishlov beruvchiga qayta-qayta kirishdan himoya qilish uchun, uni qayta ishlash vaqtida uzilishlar avtomatik ravishda taqiqlanadi (agar siz uzilishda uzilishlarni yoqmoqchi bo'lsangiz). ishlov berish tartibi, bunday shoshilinch qadam tashlashdan oldin o'n, yigirma marta o'ylab ko'rishingiz kerak).

Keling, tashqi uzilishlar bilan ishlashni ko'rib chiqaylik: birinchidan, qaysi hodisa uzilishni keltirib chiqarishini sozlashimiz kerak, ikkinchidan, chipga aynan shu uzilishni umuman qayta ishlashga ruxsat berishimiz kerak.

MCUCR registri ATmega8 chipidagi birinchi - INT1 uchun javobgar ISC11-ISC10 bitlari va INT0 uchun javobgar ISC01-ISC00 uchun javobgardir.

Jadval 1. INT1 orqali uzilish hosil qilish hodisalari ta'rifi

Shunga ko'ra, INT0 bilan bir xil.

Endi bizga kerak bo'lgan pinda uzilishlarni yoqish qoladi - GIGR registrida INT0 va INT1 bitlari mavjud; kerakli "1" ga o'rnating - va tashqi uzilish yoqilgan! Ammo xursand bo'lishga hali erta - tashqi uzilishlarga qo'shimcha ravishda, umuman uzilishlar yoqilgan bo'lishi kerak - SREG registrining eng chap I bitini "1" ga qo'ying. Assembler buyrug'i bilan ham shunday qilish mumkin: asm sei;

Oddiy misolni ko'rib chiqaylik: ATmega8 chipining INT0 (D.2) piniga (pinga va nolga) tugma biriktirilgan; bosing - uzilish sodir bo'ladi va B.0 pinidagi LED yonadi. Shunga ko'ra, LED oyoqqa va jihozga ulangan:

//INT0 (D.2) pinidagi tugmani bosganingizda ATmega8 uchun dastur - 0 ga ulangan - //tashqi uzilish orqali B.0 pinidagi LEDni yoqadi - 1 ga ulangan //turlarni qayta aniqlang typedef unsigned char bayt; ddD2_bit da sbit ddrButton; //generatsiya tugmasi sbit pinButton pinD2_bit da; sbit portD2_bit portidagi tugma; ddB0_bit da sbit ddrLight; // LED uchun chiqish, tortishish chiqishiga, portB0_bit da portLight sbit tugmachasida 0 ni aylantiring; bayt bayroqButton = 0; //tugmachani bosish belgisi; bosilgan - 1 void INT0_interrupt() org IVT_ADDR_INT0 //hech bo'lmaganda bo'sh funksiya yozishingiz kerak - //chunki kompilyator uni o'zi yaratmaydi. Aks holda u ishlamaydi ( flagButton = 1; ) //tugmachani bosish qayta ishlanmoqda - sakrashni hisobga olgan holda void buttonLight() ( if(flagButton) //agar tugma bosilsa ( portLight = 0; // LEDni yoqing) delay_ms(500); portLight = 1; //LED bayrog'ini o'chirishButton = 0; ) ) void main() ( //barcha foydalanilgan portlarni ishga tushirish ddrB = 0; portB = 0; ddrD = 0; portD = 0; // tugmani ishga tushirish - tortish porti bilan kiritish uchunButton = 1; ddrButton = 0; // 0 da yonadigan LEDni ishga tushirish va tugmani bosish - chiqish va 1 portLight = 1; ddrLight = 1; / /tashqi uzilishlarni sozlash MCUCR.ISC00 = 0; //uzilish INT0 da mantiqiy 0 orqali hosil qilinadi MCUCR.ISC01 = 0; GICR.INT0 = 1; //tashqi uzilishni yoqish INT0 asm sei;//SREG.B7 = 1; / / printsipial ravishda uzilishlarni yoqish (bit I); buyruqlar while(1) ga o'xshaydi ( buttonLight() ; ) )

Sintaksis haqida bir oz. Uzilish funksiyasi quyidagicha yoziladi: void function_name() org IVT_ADDR_INT0.

org kalit so'zi ma'lumotlar jadvalidagi uzilish manzili keyingi kelishini bildiradi. Biz kutubxonadan uzilish nomini oldik: biz IVT ni kiritamiz va keyin Ctrl + Space tugmalarini bosamiz (men bunday narsalarni yaxshi ko'raman ˆˆ). Siz kompilyator yordamiga ko'ra, org so'zi o'rniga iv dan ham foydalanishingiz mumkin.

Yana bir kichik eslatma: birinchidan, uzilish hech qachon og'ir bo'lmasligi kerak - bir nechta satr va hammasi. Buning sababi shundaki, uzilishni qayta ishlashda mikrosxemani boshqa hech narsa chalg'itishi mumkin emas, ya'ni agar bizda bir nechta uzilishlar bo'lsa, unda biz biron bir hodisaning paydo bo'lishini o'tkazib yuborishimiz mumkin.

Bundan tashqari, bizga ishlov berishni to'xtatish kerak emasligi aniqlanishi mumkin - masalan, kontaktlarning zanglashiga olib, uyqu rejimidan uyg'onishi kifoya. Ammo bu holda siz hali ham bo'sh funktsiyani - "stub" deb ataladigan uzilish funktsiyasini yozishingiz kerak. Aslida, ba'zi kompilyatorlar har bir uzilish uchun avtomatik ravishda bo'sh funktsiyalarni yozadilar, ammo bu bizning holatimizda emas - biz buni qo'lda qilishimiz kerak.

Bugun biz uzilish tushunchasini va undan qanday foydalanishni ko'rib chiqamiz. Tabiiyki, biz o'quv dasturisiz qilmaymiz, lekin bu safar biz LEDlarni o'chirmaymiz. Allaqachon yaxshi. Keling, eshik qo'ng'irog'iga o'xshash narsa yasaymiz.

Vazifa: tugmani bosganingizda mikrokontrollerning ovozli signalini chiqaradi.
Bizning misolimiz uchun diagramma. Loyiha fayllari.

Biz eski ish joyida halqa loyihasini yaratamiz.
Release konfiguratsiyasi uchun loyiha sozlamalarini o'rnating:

Mikrokontroller turini tanlang.
Umumiy parametrlar > Maqsad > Protsessor konfiguratsiyasi
Menda bu ATmega8535 bor.

Sarlavha faylida belgilangan bit nomlaridan foydalanishga ruxsat bering
Umumiy parametrlar > Tizim bo'limida I/U-Include fayllarida bit ta'riflarini yoqish katagiga belgi qo'ying
Biz hozirgacha bit nomlarini ishlatmadik, ammo bugun bizga kerak bo'ladi.

Chiqish fayli turini o'zgartiring.
Bog'lovchi > Chiqish.
Chiqish fayli maydonida "Oddiy belgilash" katagiga belgi qo'ying va d90 kengaytmasini hex bilan almashtiring
"Format" maydonida "Boshqa" ni va "Chiqish formati" ochiladigan menyusida intel-standart fayl turini tanlang.

Loyihani va ish joyini saqlang.

____________________________ To'xtatib qo'yish ___________________________

Vaziyatni tasavvur qiling. Siz ishda o'tirib, yana bir mikrokontroller dasturini ko'rib chiqyapsiz. Xo'jayin sizning oldingizga keladi va aytadi: "Eshiting, Pash, biz bo'limimizga osiloskoplar sotib oldik - Tektronix, to'rt kanalli. Vasyaga ularni sudrab borishga yordam bering." Siz shunday deb o'ylaysiz: "Xo'sh, azizim, faqat fikr xalaqit berdi ... va sizga." Rahbar esa sizga shunday qaraydi, uning ko'zlari juda mehribon, juda mehribon. Qanday qilib uni rad eta olasiz? Xo'sh, siz hamma narsani tashlab, osiloskoplarni sotib olish uchun do'stingiz bilan borasiz. Ular olib kelishdi. Biz xabar berdik. Va ular yana o'z dasturlariga o'tirishdi. Bu uzilish mexanizmi taxminan shunday ko'rinadi.

Juda oddiy, ammo bir qator asosiy fikrlar mavjud.
Birinchidan:
- ishingni qilding
- bir vaqtning o'zida kimdir osiloskop sotib olayotgan edi
- "sotib olingan osiloskoplar" hodisasi sodir bo'lganda - siz ishingizni to'xtatasiz
- Bir muncha vaqtdan beri siz boshqa ish bilan shug'ullanasiz - osiloskoplarni olib yurish
- keyin ish joyingizga qaytasiz va ishingizni to'xtagan joydan davom ettirasiz

Ikkinchidan:
- xo'jayiningizni osongina jo'natib, hech qayoqqa ketolmaysiz
- osiloskoplarga ketganingizdan so'ng, siz u erda uzoq vaqt qolishingiz yoki umuman qaytmasligingiz mumkin
- Ish joyingizga qaytganingizda, ajoyib g'oyalaringizni allaqachon unutgan bo'lishingiz mumkin

Bularning barchasi mikrokontrollerda sodir bo'ladigan narsaga juda o'xshaydi. AVR mikrokontrollerlari qator periferik qurilmalarni o'z ichiga oladi (taymerlar/hisoblagichlar, analog-raqamli konvertor, analog komparator, asinxron qabul qiluvchi... va boshqalar). Mikrokontrollerning kuchi shundaki, bu qurilmalarning barchasi parallel va bir-biridan mustaqil ravishda, shuningdek, bajarilayotgan dasturga parallel ravishda ishlashi mumkin. Har bir periferik qurilma ma'lum bir hodisa sodir bo'lganda uzilishni keltirib chiqarishi mumkin. Uzilish faqat yoqilgan bo'lsa sodir bo'ladi. Har bir qurilma uchun uzilishni yoqish alohida o'rnatiladi. Bundan tashqari, barcha uzilishlar uchun global yoqish/o'chirish bayrog'i mavjud - bu SREG registridagi I bayrog'i. Uzilish sodir bo'lganda, mikrokontroller ShK dasturi hisoblagichining tarkibini stekda saqlaydi, ya'ni u uzilgan joyni eslab qoladi. Tegishli uzilish vektorining manzilini dastur hisoblagichiga yuklaydi va shu manzilga o'tadi. U shartsiz o'tish buyrug'ini uradi, bu uzilishni qayta ishlash pastki dasturiga o'tadi. I bayrog'ini qayta o'rnatish orqali uzilishlarni o'chiradi, pastki dasturni bajaradi. Uzilishlarni qayta ishlash tartibini bajargandan so'ng, mikrokontroller I bayrog'ini o'rnatish orqali uzilishlarni yoqadi va dastur hisoblagichining tarkibini tiklaydi, ya'ni u to'xtatilgan dasturning o'sha joyiga qaytadi.

Nazariy jihatdan uzilish ishlovchisi mikrokontroller registrlari tarkibiga zarar yetkazmasligi kerak, chunki ularda shu vaqtda bajarilayotgan dasturdan ma’lumotlar bo‘lishi mumkin. Buning uchun uzilishlarni qayta ishlash kichik dasturining boshida mikrokontroller registrlarining tarkibi stekda saqlanadi va pastki dastur oxirida ular tiklanadi. Shunday qilib, uzilishdan chiqqandan so'ng, mikrokontroller hech narsa bo'lmagandek dasturni bajarishni davom ettira oladi. Assemblerda dasturlashda dasturchining o'zi registrni saqlashni buyuradi, C tilida esa bu kompilyator tomonidan amalga oshiriladi.

_______________________________________________________________

Endi taymer haqida gapiraylik. ATmega8535 bortida uchta taymer/hisoblagich mavjud - ikkita sakkiz bitli (T0, T2) va bitta o'n olti bitli (T1). Biz sakkiz bitli taymer/taymer T0 dan foydalanamiz. Bu taymer uchta registrdan iborat - boshqaruv registrlari TCCR0, hisoblash registrlari TCNT0 va taqqoslash registrlari OCR0. Taymer ishga tushganda TCNT0 hisoblagich registr har bir soat chekkasi uchun o'z qiymatini bittaga oshiradi. Takt chastotasi TCCR0 boshqaruv registridagi bir nechta mumkin bo'lgan qiymatlardan tanlanadi. Shuningdek, ushbu registr yordamida taymerning ishlash rejimi o'rnatiladi. T0 taymeri "toshib ketish" hodisasi sodir bo'lganda uzilishni keltirib chiqarishi mumkin - bu TCNT0 hisoblash registrining to'lib ketishi va "tasodif" hodisasi sodir bo'lganda - bu TCNT0 hisoblash registrining qiymatiga teng bo'lganda. taqqoslash registrining qiymati OCR0. Ushbu uzilishlarga ruxsat beruvchi bayroqlar TIMSK registrida joylashgan.
Biz T0 taymerini/taymerini 5 kHz chastotada “mos” hodisasi uzilishini ishga tushirish uchun sozlaymiz. Ishlovchi funktsiyasida biz piezo dinamik ulangan mikrokontroller chiqishi holatini o'zgartiramiz. Shunday qilib, piezo tovush chastotasi 2,5 kHz ga teng bo'ladi. (Bu ulangan piezodinamik! Uni chalkashtirmang. Piezodinamikning qarshiligi chastotaga bog'liq va 2,5 KHzda u odatda Com birliklari bo'ladi, shuning uchun u mikrokontroller chiqishiga to'g'ridan-to'g'ri, cheklovchi qarshiliksiz ulanishi mumkin) .

Endi dastur haqida. Dasturni satr bo'yicha yozish endi mumkin emas, shuning uchun men darhol uning matnini beraman. Quyida biz uning barcha satrlarini birma-bir tahlil qilamiz va hamma narsa aniq bo'ladi. Men ataylab makroslardan foydalanmadim; dastur kichik va men uni chalkashtirib yuborishni xohlamayman.

int asosiy( bekor )
{
//Kirish/chiqarish portlarini sozlang
DDRD = (0<PORTD = (1<

//T0 taymerini sozlang
TCCR0 = (1<TCNT0 = 0;
OCR0 = 0xc8;

// uzilishlarni yoqish
__enable_interrupt();

// asosiy dastur tsikli - tugmani so'rash
esa(1){
agar((PIND & (1<TIMSK = (1<boshqa
TIMSK = 0;
}
qaytish 0;
}

//T0 taymeri uchun uzilish ishlovchisi

__ uzilish bekor Timer0CompVect( bekor)
{
PORTD ^= (1<}

Port sozlamalari

Bizning sxemamizda tugma va piezo dinamik D portiga ulangan. Tugma ulangan pin kirish sifatida sozlanishi va tortishish qarshiligini yoqish kerak. Piezo karnay ulangan pin chiqishga o'rnatilishi kerak.

DDRD = (0<PORTD = (1<

Taymerni sozlash

T0 taymerining ish rejimi CTC (tasodifda qayta o'rnatiladi), soat signali clk/8. Biz buni TCCR0 registrida aks ettiramiz

TCCR0 = (1<

Har holda, biz TCNT0 hisoblash registrini tiklaymiz

OCR0 taqqoslash registriga 0xc8 yozing. Nega? Chunki men buni hisoblaganman kalkulyator. Xo'sh, qog'ozda bu hisob shunday ko'rinadi.
Mikrokontrollerning soat chastotasi 8 MGts
Taymerning soat signali 8000000 Hz/8 = 1000000 Hz.
Bir taymer soatining vaqti 1/1000000 = 1 mks
Bizga kerak bo'lgan chastotaning bir siklining vaqti 1/5000 Gts = 200 mks.
200 mks ga qancha taymer belgilari to'g'ri keladi? 200/1 = 200 belgi
200 o'n oltilik tizimda = 0xs8

T0 taymerining batafsil tavsifi uchun ATMega8535 hujjatlariga qarang.

Biz taymerni sozladik va o'rnatilgan funksiyadan foydalanib umumiy uzilishni yoqdik.

__enable_interrupt();

So‘rovnoma tugmasi

Tugma bosilmaganda, mikrokontrollerning chiqishi ichki tortish rezistori orqali quvvatga ulanadi, ya'ni chiqishda bitta mavjud; tugma bosilganda, chiqish erga qisqaradi, ya'ni u erda chiqishda nolga teng. Tugma bosilmaganligini aniqlash uchun siz PIND registrining mazmunini o'qib chiqishingiz va nol bitning qiymatini tekshirishingiz kerak (tugma PD0 ga ulangan). Tugmani cheksiz tsiklda so'raymiz.

esa (1)
{
agar((PIND & (1<//agar tugma bosilsa, mikrokontroller chiyillashi kerak
}
boshqa {
//bo'lmasa, baliqdek jim bo'l
}
}

Unutmang == tayinlash operatori = emas.

Ishlov berish tugmachasini bosing/qo'yib yuboring

Tugmani bosish orqali biz T0 taymerining uzilishini yoqamiz va uni qo'yib yuborish orqali biz uni o'chirib qo'yamiz. Buning uchun biz TIMSK registrining OCIE0 bitini manipulyatsiya qilamiz

TIMSK = (1<// tasodif hodisasi tufayli T0 taymerining uzilishiga ruxsat bering

TIMSK = 0; // uzilishni o'chirish

Biz faqat bitta taymerdan foydalanayotganimiz sababli, alohida bitlarni o'rnatish yoki tiklashning hojati yo'q.

Interrupt funktsiyasi

_____________________ Interrupt funktsiyasi sintaksisi _____________________

Interrupt funktsiyasi #pragma vektor= direktivasi va funktsiya so'zi yordamida aniqlanadi __ uzilish. Funktsiya void tipida bo'lishi va hech qanday parametrlarni qabul qilmasligi kerak.

#pragma vektor = Manzil
__ uzilish bekor ism( bekor)
{
//kodimiz shu yerda joylashgan
}

Ism– funksiya nomi, bizning ixtiyorimiz bilan tanlang
Manzil– uzilish vektori manzili, raqam yoki mikrokontroller sarlavhasi faylida belgilangan nomlar bilan belgilanishi mumkin (iom8535.h – Interrupt vektor ta’riflari bo‘limi)

______________________________________________________________

Bizning vazifamiz uchun uzilishni qayta ishlash funktsiyasi quyidagicha ko'rinadi

#pragma vektori = TIMER0_COMP_vect
__ uzilish bekor Timer0CompVect( bekor)
{
PORTD ^= (1<// PD1 pinidagi signalni o'zgartiring
}

Xo'sh, hammasi shu. Umid qilamanki, hamma narsa aniq.
Keyingi maqolada biz mikrokontrollerni ohang o'ynashga majbur qilamiz.

Interrupt - protsessordan darhol javob talab qiladigan hodisa. Javob shundan iboratki, protsessor joriy dasturni qayta ishlashni to'xtatadi ( to'xtatilgan dastur) va boshqa dasturni bajarishga kirishadi ( dasturni to'xtatish), ushbu tadbir uchun maxsus ishlab chiqilgan. Ushbu dastur tugagach, protsessor uzilgan dasturni bajarishga qaytadi.

Har bir uzilishni talab qiladigan hodisa bilan birga keladi uzilish signali, bu haqda kompyuterni xabardor qilish va qo'ng'iroq qilish to'xtatish so'rovi.

Dastur holati vaqtning tegishli nuqtasida (masalan, oxirgi buyruq bajarilgandan keyin) barcha saqlash elementlarining holatlar to'plamini ifodalaydi. Uzilish sodir bo'lganda, mikrokontroller dastur hisoblagichining tarkibini stekda saqlaydi va unga mos keladigan uzilish vektorining manzilini yuklaydi. To'xtatish tartibining oxirgi buyrug'i asosiy dasturga qaytadigan va avval saqlangan dastur hisoblagichini tiklaydigan buyruq bo'lishi kerak. Interrupt ishlov beruvchisi bajarilayotganda, ba'zi ma'lumotlar o'zgarishi mumkin. Shuning uchun, uzilish ishlovchisiga o'tishda, o'zgartirilayotgan elementlarni saqlash kerak. Bunday elementlarning to'plami dastur holati vektori. Bunday holda, xotira hujayralarining holati haqidagi boshqa ma'lumotlar muhim emas yoki dasturiy jihatdan tiklanishi mumkin.

Boshlang'ich holat vektori dasturni dastlabki ishga tushirish uchun barcha kerakli ma'lumotlarni o'z ichiga oladi. Ko'pgina hollarda, boshlang'ich holat vektori faqat bitta elementni o'z ichiga oladi - ishga tushirilayotgan dasturning boshlang'ich manzili.

Uzilish vektori to'xtatuvchi dasturning (ishlovchi) boshlang'ich holatining vektori bo'lib, ishlov beruvchiga o'tish uchun barcha kerakli ma'lumotlarni, shu jumladan uning boshlang'ich manzilini o'z ichiga oladi. Har bir uzilish turi o'z uzilish vektoriga ega bo'lib, tegishli ishlov beruvchining bajarilishini boshlaydi. Odatda, uzilish vektorlari qisqa manzillar bilan maxsus ajratilgan sobit xotira joylarida saqlanadi. uzilish vektor jadvali. Tegishli uzilish dasturiga o'tish uchun protsessorda uzilish vektori va bu vektorning manzili bo'lishi kerak. Ushbu manzilda, qoida tariqasida, uzilishlarni qayta ishlash quyi dasturiga shartsiz o'tish buyrug'i mavjud.

Qoidaga ko'ra, saqlash va qaytarishni boshqarish uzilishni ishlov beruvchiga yuklanadi. Bunda ishlov beruvchi uch qismdan - tayyorgarlik (prolog) va yakuniy (epilog)dan iborat bo'lib, ular dastur almashinuvini ta'minlaydi va so'rov bo'yicha so'ralgan amallarni bajaradigan haqiqiy uzilish dasturi. Javob berish vaqti uzilish so'rovi olingan paytdan boshlab to'xtatuvchi dastur bajarilishini boshlagunga qadar bo'lgan vaqt oralig'i sifatida aniqlanadi.


tp- tizimning uzilishga javob berish vaqti;
t z– uzilgan dastur holatini saqlash vaqti;
t ppr– amaldagi uzilish dasturining vaqti;
t in– uzilgan dasturning holatini tiklash vaqti

Agar so'rovlarning bir nechta manbalari mavjud bo'lsa, kiruvchi so'rovlarga xizmat ko'rsatishning ma'lum bir tartibi belgilanishi kerak. ustuvor munosabatlar yoki xizmat intizomi. Protsessorning barcha mumkin bo'lgan uzilish turlari to'plami uzilish tizimi mikrokontroller. Xizmat intizomi bir vaqtning o'zida olingan bir nechta so'rovlardan qaysi biri birinchi bo'lib ko'rib chiqilishini va u yoki bu uzilishni qayta ishlovchi ushbu so'rovni to'xtatish huquqiga ega ekanligini aniqlaydi.
Agar uzilish qayta ishlanayotganda yuqoriroq ustunlikdagi uzilish so'rovi olinsa, boshqaruv yuqori ustuvorlikdagi uzilish ishlovchisiga o'tkaziladi va pastroq ustunlikdagi uzilish ishlovchisi to'xtatiladi. Turadi uy qurishni to'xtatish. Bir-birini to'xtata oladigan dasturlarning maksimal soni deyiladi uzilishlar chuqurligi.

Agar bir xil manbadan (bir xil ustuvorlik) yangi so'rov kelgan vaqtgacha uzilish so'roviga xizmat ko'rsatilmasa, u holda tizimning to'yinganligini to'xtatish. Bunday holda, ba'zi uzilish so'rovlari yo'qoladi, bu mikrokontrollerning normal ishlashi uchun qabul qilinishi mumkin emas.

Interrupt tizimining xususiyatlari quyidagilar:

  • uzilish so'rovlarining umumiy soni uzilish so'rovlari manbalari soni;
  • uzilishni ko'rsatish turi - qoida tariqasida, uzilish so'rovi mantiqiy signal darajasi bilan ifodalanadi;
  • uzilish ustuvorligi - har bir uzilish so'rovini qayta ishlash tartibini belgilaydi; ustuvorlik qanchalik yuqori bo'lsa, uning uchun uzilish dasturining bajarilishidagi kechikish shunchalik qisqaroq bo'ladi;
  • javob vaqti - uzilish so'rovining paydo bo'lishi va to'xtatuvchi dasturning bajarilishini boshlash o'rtasidagi vaqt oralig'i;
  • uzilishning kechikishi - dasturni saqlash va tiklash uchun umumiy vaqt bilan belgilanadi;
  • chuqurlik, odatda uzilishlar tizimidagi ustuvor darajalar soniga to'g'ri keladi;
  • tizimning to'yinganligini to'xtatish;
  • dasturni to'xtatishning ruxsat etilgan daqiqalari (odatda keyingi buyruq bajarilishining tugashi).

Maskalashni to'xtatish mikrokontrollerga har bir uzilish turiga javob berishni yoki unga e'tibor bermaslikni aytish uchun ishlatiladi. Uzilish maskasi ikkilik kodni ifodalaydi, uning bitlari uzilish so'rovi manbalariga tayinlanadi. Ikkilik koddagi bir bit mikrokontrollerga ushbu turdagi uzilishlarni boshqarishni aytadi. Nol bit, aksincha, mikrokontrollerga ko'rsatilgan turdagi uzilishlarni qayta ishlashga o'tishga imkon bermaydi.
Qoida tariqasida, uzilishlarni maskalashdan tashqari, global uzilishni yoqish biti ham mavjud bo'lib, uning nol qiymati barcha uzilishlar ishlov beruvchilarini o'chirib qo'yadi (apparatni qayta o'rnatish va bajarilayotgan dasturning boshiga o'tishdan tashqari).
Interrupt maskasi ikkilik kodidan tashqari, ikkilik kod ham mavjud bayroqlarni to'xtatish, bu mikrokontrollerda ko'rsatilgan so'rov bilan bir nechta manbalar mavjud bo'lsa, uzilish manbasini o'rnatishga imkon beradi.



 


O'qing:



Sotib olgandan keyin iPhone-ni sozlash Sotib olgandan keyin iPhone se-ni qanday sozlash mumkin

Sotib olgandan keyin iPhone-ni sozlash Sotib olgandan keyin iPhone se-ni qanday sozlash mumkin

Apple gadjetlari butun sayyorani to'ldirgandek tuyulganiga qaramay, yangi iPhone foydalanuvchilari soni kundan-kunga ortib bormoqda. Shunga qaramay...

YouTube kanalingiz uchun chiroyli fon yaratishning eng yaxshi usullari

YouTube kanalingiz uchun chiroyli fon yaratishning eng yaxshi usullari

Siz qiziqarli video kontent yaratyapsizmi? Kanalingizni chiroyli loyihalashni unutmang! Kanalni loyihalashda eng muhim rolni sarlavha deb ataladigan narsa o'ynaydi...

Samsung smartfonlarini zavod sozlamalariga qaytaring

Samsung smartfonlarini zavod sozlamalariga qaytaring

Ko'pincha Android telefoningizni qayta o'rnatishga ehtiyoj bor. Ushbu protsedura juda oddiy. Bir necha marta ekranga teging...

Power BI nima va u bilan qanday ishlash kerak?

Power BI nima va u bilan qanday ishlash kerak?

Assalomu alaykum, aziz do'stlar, Anton Buduev siz bilan. Ushbu maqola bilan men har birimiz uchun juda chuqur va muhim mavzuni ko'rib chiqishni boshlayman ...

tasma tasviri RSS