{"id":3261,"date":"2024-07-30T22:32:55","date_gmt":"2024-07-30T17:32:55","guid":{"rendered":"https:\/\/yarat.uz\/?p=3261"},"modified":"2025-03-19T15:27:03","modified_gmt":"2025-03-19T10:27:03","slug":"uzilishlar-interrupts","status":"publish","type":"post","link":"https:\/\/yarat.uz\/?p=3261","title":{"rendered":"Apparatli uzilishlar (interrupts) [18+]"},"content":{"rendered":"<p style=\"text-align: center;\"><strong>Uzilishlar &#8211; o&#8217;zi nima degani?<\/strong><\/p>\n<p style=\"text-align: justify;\"><strong>uzilish<\/strong> (interrupts, internal ruptures &#8211; &#8220;Ichki uzilishlar&#8221;) &#8211; mikrokontrollerning yana bir muhim xususiyatlaridan biri bo&#8217;lib, u mikrokontroller asosiy dasturi tomonidan bajarilayotgan jarayonlarning ma&#8217;lum bir maxsus vazifani bajarish uchun vaqtincha to&#8217;xtatib turilishi hodisasi hisoblanadi. Tegishli &#8220;maxsus topshiriq&#8221; bajarilib bo&#8217;lgan zahoti mikrokontroller asosiy dasturni qolgan joyidan davom ettirib ketaveradi (ko&#8217;pincha bunday uzilishlar mikrokontroller piniga yuborilgan tashqi ta&#8217;sir oqibatida sodir bo&#8217;lganligi sababli, ularni umumiy nom bilan <strong>&#8220;tashqi uzilish&#8221;<\/strong> &#8211; &#8220;\u0432\u043d\u0435\u0448\u043d\u0435\u0435 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0435&#8221; deb ataladi, vaholanki, aslida uzilish mikrokontrollerning o&#8217;zida (ichida) amalga oshiriladi).<\/p>\n<p style=\"text-align: justify;\">Mazkur vazifani dastur davomida bajarish ham mumkin, lekin bunda mikrokontroller vazifani bajarish paytida dastur algoritmi asosida ishlaydi va uning navbati yetib kelishini kutadi. Uzilish hosil qilinganda esa, o&#8217;sha paytda mikrokontroller qanday vazifa bajarayotganidan qat&#8217;iy nazar, ularnig hammasini &#8220;yig&#8217;ishtirib qo&#8217;yib&#8221;, kerakli &#8220;maxsus topshiriq&#8221;ni bajarishga kirishadi. Ya&#8217;ni, uzilishni sodir qiluvchi signal qabul qilingan zahoti (atigi bir necha <strong>mikrosekund<\/strong>lar ichida) mikrokontroller belgilangan vazifani bajarishga o&#8217;tadi.<\/p>\n<p style=\"text-align: justify;\">Uzilishlar ularni keltirib chiqaruvchi ta&#8217;sirlarga ko&#8217;ra, 2 xil turga bo&#8217;linadi: apparatli (<strong>tashqi<\/strong>) va <strong>dasturiy<\/strong> uzilishlar.<\/p>\n<p style=\"text-align: justify;\">Uzilishlarning amalda keng qo&#8217;llaniladigan turi &#8211; <strong>apparatli uzilishlar<\/strong> hisoblanadi. Bunday deyilishiga sabab, uzilish mikrokontroller pinlaridan birida yuqori (HIGH, +5V) yoki quyi (LOW, 0V) elektr signali paydo bo&#8217;lishi natijasida yuzaga keladi. <strong>Dasturiy uzilishlar<\/strong> &#8211; foydalanuvchi tomonidan dasturiy yo&#8217;l bilan, mikrokontroller ichki taymerlari yordamida sodir etiladigan uzilish turi.<\/p>\n<p>Arduinoda uzilishlar bilan ishlashda quyidagi buyruqlardan foydalaniladi:<\/p>\n<p><strong>attachInterrupt(&lt;pin tartibi&gt;,&lt;funksiya&gt;,&lt;rejim&gt;) <\/strong>yoki <strong>attachInterrupt(&lt;digitalPinToInterrupt(pin)&gt;, &lt;ISR&gt;, &lt;mode&gt;);<\/strong> &#8211; uzilishni yo&#8217;lga qo&#8217;yish (boshlash);<br \/>\n<strong>detachInterrupt(&lt;pin tartibi&gt;);<\/strong> &#8211; uzilishni to&#8217;xtatish;<br \/>\n<strong>noInterrupts();<\/strong> &#8211; uzilish davrida bajarilayotgan funksiyaning bajarilishini to&#8217;xtatish;<br \/>\n<strong>interrupts();<\/strong> &#8211; to&#8217;xtatib qo&#8217;yilgan funksiya bajarilishini (uzilishni) davom ettirish;<\/p>\n<p style=\"text-align: justify;\">Bu yerda:<br \/>\n<strong>&lt;pin tartibi&gt;<\/strong> &#8211; uzilish hosil qilinadigan tartib raqami. Uzilish hosil qilish mumkin bo&#8217;lgan pinlar soni turli mikrokontrollerlarda turlicha bo&#8217;lishi mumkin. Tartib raqami &#8211; AVR mikrokontrollerlarida alohida tartiblanadi va aksariyat hollarda pin raqami bilan bir xil bo&#8217;lmaydi. ESP8266 mikrokontrollerlarida esa, pin (GPIO yoki D-pin) raqami bilan bir xil bo&#8217;ladi;<br \/>\n<strong>&lt;funksiya&gt; <\/strong>&#8211; uzilish sodir bo&#8217;lgan paytda bajarilishi zarur bo&#8217;lgan &#8220;maxsus vazifa&#8221; nomi. Uzilish sodir bo&#8217;lgan zahoti ushbu funksiya bajariladi; ESP8266\/32 da funksiya <strong><span class=\"enlighter\"><span class=\"enlighter-text\">IRAM_ATTR<\/span><\/span><\/strong><span class=\"enlighter\"><span class=\"enlighter-text\"> yoki\u00a0<\/span><\/span><strong><span class=\"enlighter\"><span class=\"enlighter-text\">ICACHE_RAM_ATTR<\/span><\/span><\/strong><span class=\"enlighter\"><span class=\"enlighter-text\"> <a href=\"https:\/\/alexgyver.ru\/lessons\/esp8266\/\">atributlari<\/a> bilan yaratiladi. Agar uzilish paytida bajarladigan funksiya kodida biron o&#8217;zgaruvchi qiymati foydalanuvchi kodi tomonidan o&#8217;zgartirilishi mumkin bo&#8217;lsa, global o&#8217;zgaruvchilar (asosiy dastur boshida) <strong>volatile<\/strong> spetsifikatori bilan e&#8217;lon qilingan bo&#8217;lishi kerak. Uzilish paytida bajariladigan funksiyaning kodi imkon qadar qisqa bo&#8217;lishi zarur, aksincha uzoq yoki tez-tez uzilishlar mikrokontrollerning to&#8217;xtalishlar bilan ishlashiga sabab bo&#8217;lishi mumkin.<br \/>\n<\/span><\/span><\/p>\n<p style=\"text-align: justify;\"><strong>&lt;rejim&gt;<\/strong> &#8211; pinning uzilishni keltirib chiqaradigan holati. U quyidagi holatlardan biri bo&#8217;lishi mumkin: &lt;<strong>LOW<\/strong>&gt;, &lt;<strong>RISING<\/strong>&gt;, &lt;<strong>FALLING<\/strong>&gt;, &lt;<strong>CHANGE<\/strong>&gt;.<\/p>\n<p style=\"text-align: justify;\"><strong>LOW<\/strong> rejimida uzilish tegishli pinda quyi signal (0V) paydo bo&#8217;lganda yuzaga keladi.<br \/>\n<strong>RISING<\/strong> rejimida uzilish pindagi signal LOW (oV) dan HIGH (+5V) ga o&#8217;zgarganda yuzaga keladi.<br \/>\n<strong>FALLING<\/strong> rejimida uzilish signal HIGH (+5V) dan LOW (0V) ga o&#8217;zgarganda yuzaga keladi.<br \/>\n<strong>CHANGE<\/strong> rejimida signal qarama-qarshi holatga (HIGH dan LOW ga yoki LOW dan HIGH ga) o&#8217;zgarganda yuzaga keladi.<\/p>\n<p style=\"text-align: justify;\">Xo&#8217;sh, uzilishlardan qanday maqsadlarda foydalanish mumkin?<\/p>\n<ul>\n<li style=\"text-align: justify;\">tugma bosilishiga yoki datchik ko&#8217;rsatkichi o&#8217;zgarishiga qarab, asosiy dastur o&#8217;sha paytda qaysi vazifani bajarayotganidan qat&#8217;iy nazar, uni to&#8217;xtatib, tugma holati yoki datchik ko&#8217;rsatkichini aniqlash, undan foydalanish uchun;<\/li>\n<li style=\"text-align: justify;\">tez o&#8217;zgaruvchi jarayonlarni hisoblash (sanash) uchun. Masalan, dvigatelning aylanish tezligini hisoblovchi datchik ko&#8217;rsatkichini yuqori aniqlikda hisoblash uchun;<\/li>\n<li style=\"text-align: justify;\">&#8220;chuqur uyqu&#8221; holatidagi mikrokontrollerni &#8220;uyg&#8217;otish&#8221; uchun. Mikrokontrollerning ushbu xususiyatidan ayniqsa, energiyani tejash maqsadlarida keng qo&#8217;llaniladi, chunki &#8220;uyqu&#8221; rejimida mikrokontroller deyarli elektr tokini sarf qilmaydi (faqat bir necha o&#8217;nlab mikroamperdan bir necha milliampergacha sarflaydi). Bunday holda mikrokontroller qisqa vaqtga uyg&#8217;otiladi va tegishli vazifani bajarib bo&#8217;lgach yana uyquga jo&#8217;natiladi. Masalan, mikrokontrollerni xonadagi haroratni har 30 sekundda o&#8217;lchash yoki kamera yordamida xonani suratga olish uchun uyg&#8217;otish, ularni kerakli qurilmaga jo&#8217;natish, shundan keyin yana uni uyquga jo&#8217;natish mumkin.<\/li>\n<\/ul>\n<p style=\"text-align: justify;\">Demak, qaysi vaziyatda uzilish hosil qilishni foydalanuvchi o&#8217;zi oldindan belgilab olishi mumkin. Asosiysi, dastlab qaysi mikrokontroller nechta uzilish hosil qiladigan pinlarga ega, ular aynan qaysilar, ularning pin tartibi qanday ekanligini aniqlab olish juda muhim.<\/p>\n<p style=\"text-align: justify;\"><em><strong>Eslatma.<\/strong> Uzilishlar hosil qilinganda mikrokontrollerning ichki taymerlari bilan bog&#8217;liq kodlarning bajarilishida <strong>uzilishlar yuz beradi<\/strong>. Masalan, uzilish funksiyasi kodida Arduinoning <strong>delay(), <\/strong><strong>millis() <\/strong>va <strong>micros() <\/strong>kabi funksiyalari <strong>noto&#8217;g&#8217;ri ishlaydi<\/strong>. Chunki ushbu funksiyalar mikrokontroller taymeri bilan bog&#8217;liq. Bundan tashqari, <strong>Serial.print()<\/strong><\/em> <em> funksiyasi ishlatilishida ham kamchiliklar kuzatiladi.<\/em><\/p>\n<p style=\"text-align: justify;\">Uzilishdan foydalanishga misollar:<\/p>\n<p style=\"text-align: justify;\">1-misol. Ushbu misolda 0-tartib raqamli pinda har safar <strong>0<\/strong> quyi signali hosil bo&#8217;lganda, hisobchi-o&#8217;zgaruvchi qiymati\u00a0 1 taga oshib boradi va portga chiqariladi.<\/p>\n<div class=\"su-spoiler su-spoiler-style-fancy su-spoiler-icon-plus su-spoiler-closed\" data-scroll-offset=\"0\" data-anchor-in-url=\"no\"><div class=\"su-spoiler-title\" tabindex=\"0\" role=\"button\"><span class=\"su-spoiler-icon\"><\/span>1-misol<\/div><div class=\"su-spoiler-content su-u-clearfix su-u-trim\">\nvolatile int <strong>counter = 0;<\/strong> \/\/ hisoblovchi o&#8217;zgaruvchi<br \/>\nvoid setup() {<br \/>\nSerial.begin(9600);<br \/>\n\/\/ Tugmani D2 va GND pinlari orasiga o&#8217;rnatiladi<br \/>\npinMode(2, INPUT_PULLUP); \/\/ 2-raqamli pin musbatga tortish rejimiga o&#8217;tkazilmoqda (bu tugma bosilmagan paytda uning bir kontaktida doimiy yuqori signal bo&#8217;lishini ta&#8217;minlaydi)<br \/>\n\/\/ FALLING &#8211; tugma bosilgandagi signal 0 bo&#8217;lishini hisobga olib shu uzilish rejimni tanlaymiz<br \/>\n<strong>attachInterrupt(0, btnIsr, FALLING);<\/strong> \/\/ Uzilish pini tartib raqami, uzilish hosil qilinganda bajarilishi kerak bo&#8217;lgan funksiya, uzilish rejimini e&#8217;lon qilib qo&#8217;yamiz.<br \/>\n}<br \/>\nvoid <strong>btnIsr()<\/strong> {\u00a0 \/\/ Uzilish paytida bajariladigan funksiya<br \/>\ncounter++; \/\/ tugma bosilganda, hisoblovchi qiymati oshadi<br \/>\n}<br \/>\nvoid loop() {<br \/>\nSerial.println(counter); \/\/ Hisoblovchi qiymatini portga chiqaramiz<br \/>\ndelay(1000);<br \/>\n}<\/div><\/div>\n<p style=\"text-align: justify;\">2-misol. Bu misolda, uzilish sodir bo&#8217;lganini uzilish funksiyasida o&#8217;zgaruvchi qiymati o&#8217;zgarishiga moslashtirib qo&#8217;yamiz. Asosiy dastur o&#8217;z ishini shu o&#8217;zgaruvchi qiymatiga mos holda davom ettirishimiz mumkin. Demak, bunda uzilish sodir bo&#8217;lganda ortiqcha kodlar bajarilmaydi, faqat o&#8217;zgaruvchi qiymati o&#8217;zgaradi xolos.<\/p>\n<div class=\"su-spoiler su-spoiler-style-fancy su-spoiler-icon-plus su-spoiler-closed\" data-scroll-offset=\"0\" data-anchor-in-url=\"no\"><div class=\"su-spoiler-title\" tabindex=\"0\" role=\"button\"><span class=\"su-spoiler-icon\"><\/span>2-misol<\/div><div class=\"su-spoiler-content su-u-clearfix su-u-trim\">\nvolatile bool intFlag = false; \/\/ &#8220;bayroq&#8221; o&#8217;zgaruvchisini e&#8217;lon qilamiz<br \/>\nvoid setup(){<br \/>\nSerial.begin(9600);<br \/>\npinMode(2, INPUT_PULLUP);<br \/>\nattachInterrupt(0, buttonTick, FALLING);<br \/>\n}<br \/>\nvoid <strong>buttonTick()<\/strong>{\u00a0 \/\/ Uzilish hosil qilinganda bajariladigan funksiya.<br \/>\nintFlag = true; \/\/ uzilish sodir bo&#8217;lganda &#8220;bayroqni ko&#8217;taramiz&#8221;<br \/>\n}<br \/>\nvoid loop(){<br \/>\nif(intFlag){ \/\/ Agar &#8220;bayroq ko&#8217;tarilgan&#8221; bo&#8217;lsa&#8230;<br \/>\nintFlag = false; \/\/ uni &#8220;tushiramiz&#8221;<br \/>\n\/\/ bu yerga kerakli vazifa kodini kiritish mumkin<br \/>\nSerial.println(&#8220;Uzilish sodir bo&#8217;ldi!&#8221;);<br \/>\n}<br \/>\n}<\/div><\/div>\n<p style=\"text-align: justify;\">3-misol. Ushbu misolda, uzilish datchik ulangan pindagi signalning qiymatida o&#8217;zgarish bo&#8217;lganda sodir bo&#8217;ladi. Bu yerdagi <em>millis()<\/em> funksiyasi qiymati, yuqorida aytilganidek, funksiya ichida o&#8217;zgarmaydi, lekin uzilishdan chiqilgan oraliqda o&#8217;zgarib qoladi.<br \/>\n<div class=\"su-spoiler su-spoiler-style-fancy su-spoiler-icon-plus su-spoiler-closed\" data-scroll-offset=\"0\" data-anchor-in-url=\"no\"><div class=\"su-spoiler-title\" tabindex=\"0\" role=\"button\"><span class=\"su-spoiler-icon\"><\/span>3-misol<\/div><div class=\"su-spoiler-content su-u-clearfix su-u-trim\">\nvoid setup(){<br \/>\n<strong>attachInterrupt(0, isr, CHANGE);<\/strong> Uzilish pini tartib raqami, uzilish hosil qilinganda bajarilishi kerak bo&#8217;lgan funksiya, pindagi signal o&#8217;zgarganida uzilish rejimi e&#8217;lon qilinmoqda.<br \/>\n}<br \/>\nvolatile uint32_t debounce;<br \/>\nvoid <strong>isr()<\/strong>{ \/\/ Uzilish funksiyasi<br \/>\n\/\/ digitalRead funksiyasi yordamida datchik pini holatini aniqlaymiz, tugma bosilgandagi stabillikni ta&#8217;minlash uchun 100 millisekundlik pauza o&#8217;rnatilmoqda.<br \/>\nif(millis() &#8211; debounce &gt;= 100 &amp;&amp; digitalRead(2)){<br \/>\ndebounce = millis();<br \/>\n\/\/ datchik qiymati HIGH ga o&#8217;zgarganda bajarilishi kerak bo&#8217;lgan ixtiyoriy qisqa kod joyi<br \/>\n}<br \/>\n}<br \/>\nvoid loop(){<br \/>\n}<\/div><\/div>\n","protected":false},"excerpt":{"rendered":"<p>Uzilishlar &#8211; o&#8217;zi nima degani? uzilish (interrupts, internal ruptures &#8211; &#8220;Ichki uzilishlar&#8221;) &#8211; mikrokontrollerning yana bir muhim xususiyatlaridan biri bo&#8217;lib, u mikrokontroller asosiy dasturi tomonidan bajarilayotgan jarayonlarning ma&#8217;lum bir maxsus vazifani bajarish uchun vaqtincha to&#8217;xtatib turilishi hodisasi hisoblanadi. Tegishli &#8220;maxsus topshiriq&#8221; bajarilib bo&#8217;lgan zahoti mikrokontroller asosiy dasturni qolgan joyidan davom ettirib ketaveradi (ko&#8217;pincha bunday uzilishlar [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12],"tags":[],"class_list":["post-3261","post","type-post","status-publish","format-standard","hentry","category-qollanmalar"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/yarat.uz\/index.php?rest_route=\/wp\/v2\/posts\/3261","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/yarat.uz\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/yarat.uz\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/yarat.uz\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/yarat.uz\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3261"}],"version-history":[{"count":22,"href":"https:\/\/yarat.uz\/index.php?rest_route=\/wp\/v2\/posts\/3261\/revisions"}],"predecessor-version":[{"id":4536,"href":"https:\/\/yarat.uz\/index.php?rest_route=\/wp\/v2\/posts\/3261\/revisions\/4536"}],"wp:attachment":[{"href":"https:\/\/yarat.uz\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3261"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/yarat.uz\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3261"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/yarat.uz\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3261"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}