Atmel AVR स्टुडिओमधील AVR कंट्रोलरवर व्यत्यय. प्रशिक्षण अभ्यासक्रम. व्यत्यय संकल्पना. आम्ही मायक्रोकंट्रोलरला आवाज देतो ______________________________ व्यत्यय ___________________________

AVR मायक्रोकंट्रोलरमध्ये मोठ्या प्रमाणात परिधीय उपकरणे (ADC, Timer/Counters, EXTI, Analog Comparator, EEPROM, USART, SPI, I2C, इ.) समाविष्ट आहेत, ज्यापैकी प्रत्येक डेटा/सिग्नल आणि इतर माहितीवर विशिष्ट क्रिया करू शकतात. AVR मायक्रोकंट्रोलरवर आधारित सर्व प्रकारची उपकरणे विकसित करताना अनुप्रयोगाची कार्यक्षमता सुधारण्यासाठी आणि खर्च कमी करण्यासाठी ही उपकरणे मायक्रोकंट्रोलरमध्ये समाकलित केली जातात.

प्रोसेसर आय/ओ रजिस्टर्सद्वारे परिधीय उपकरणांशी संप्रेषण/नियंत्रण करतो, जे डेटा मेमरीमध्ये असतात, त्यांना नियमित व्हेरिएबल्सप्रमाणे वापरण्याची परवानगी देतात. प्रत्येक उपकरणाचे स्वतःचे I/O रजिस्टर असतात.

सर्व I/O नोंदणी तीन गटांमध्ये विभागली जाऊ शकतात: डेटा रजिस्टर्स, कंट्रोल रजिस्टर्स आणि स्टेटस रजिस्टर्स.

कंट्रोल रजिस्टर्सचा वापर करून, डिव्हाइस विशिष्ट वारंवारता, अचूकता इत्यादीसह एका किंवा दुसऱ्या मोडमध्ये ऑपरेट करण्यासाठी कॉन्फिगर केले जाते आणि डेटा रजिस्टर्स वापरून, या डिव्हाइसच्या ऑपरेशनचे परिणाम वाचले जातात (एनालॉग-टू-डिजिटल रूपांतरण, प्राप्त झाले डेटा, टाइमर/काउंटर मूल्य इ.). असे दिसते की येथे काहीही क्लिष्ट नाही (खरं तर, येथे खरोखर काहीही क्लिष्ट नाही :)), डिव्हाइस चालू केले, इच्छित ऑपरेटिंग मोड दर्शविला आणि नंतर फक्त कूपन क्लिप करणे, तयार डेटा वाचा. आणि गणनामध्ये त्यांचा वापर करा. हा डेटा "केव्हा" वाचायचा हा संपूर्ण प्रश्न आहे (डिव्हाइसने त्याचे कार्य पूर्ण केले आहे किंवा अद्याप डेटावर प्रक्रिया केली आहे), कारण सर्व परिधीय उपकरणे मायक्रोकंट्रोलर कोरच्या समांतरपणे कार्य करतात आणि संप्रेषणाची अंमलबजावणी करण्याचा प्रश्न उद्भवतो आणि प्रोसेसर आणि पेरिफेरल्स डिव्हाइस दरम्यान सिंक्रोनाइझेशन.

तुम्ही कदाचित आधीच अंदाज लावला असेल की, डिव्हाइस आणि प्रोसेसर यांच्यातील संप्रेषण आणि सिंक्रोनाइझेशन लागू करण्यासाठी, "स्थिती नोंदणी" वापरली जातात, जी विशिष्ट डिव्हाइसची सध्याची ऑपरेटिंग स्थिती संग्रहित करते ज्यामध्ये डिव्हाइस "बिट इन" शी संबंधित असू शकते नोंदणी स्थिती" (ध्वज), ज्याचे वर्तमान मूल्य या डिव्हाइसच्या वर्तमान स्थितीबद्दल किंवा त्याच्या वैयक्तिक कार्याबद्दल "बोलते" (काम पूर्ण झाले/पूर्ण झाले नाही, डेटा प्रक्रियेदरम्यान त्रुटी, रिक्त नोंदणी इ.).

प्रोसेसर आणि परिधीय उपकरण यांच्यातील संप्रेषण यंत्रणा ध्वज मतदानाद्वारे कार्यान्वित केली जाते, जी या उपकरणाच्या विशिष्ट कार्यासाठी जबाबदार असतात. विशिष्ट ध्वज (डिव्हाइस स्थिती) च्या मूल्यावर अवलंबून, आपण प्रोग्राम अंमलबजावणीचा प्रवाह (शाखा बनवणे) बदलू शकता. उदा:

ठराविक ध्वज सेट केला आहे का ते तपासत आहे (काही घटना घडली आहे):

जर (RegX आणि (1<< Flag) ) // जर RegX रजिस्टरमधील ध्वज सेट केला असेल
{
// काहीतरी कर
}

काही क्रिया (इव्हेंट) पूर्ण होण्याची प्रतीक्षा करत आहे:

तेव्हा(!(RegX & (1<

ध्वजांची क्वेरी करणे हे एक ऐवजी संसाधन-केंद्रित कार्य आहे, प्रोग्राम आकार आणि प्रोग्राम गती या दोन्ही दृष्टीने. एव्हीआर मायक्रोकंट्रोलरमधील एकूण ध्वजांची संख्या बरीच मोठी (एक फायदा) असल्याने, मतदान ध्वजाद्वारे प्रोसेसर आणि डिव्हाइसमधील संप्रेषणाची अंमलबजावणी केल्याने तुम्ही लिहिलेल्या प्रोग्रामची कार्यक्षमता (कोड गती / कोड आकार) कमी होते, याव्यतिरिक्त, प्रोग्राम खूप गोंधळात टाकणारा बनतो, जो कोडच्या तपशीलवार डीबगिंगसह देखील शोधणे कठीण असलेल्या त्रुटी दिसण्यास योगदान देतो.

AVR मायक्रोकंट्रोलरसाठी प्रोग्राम्सची कार्यक्षमता वाढवण्यासाठी, तसेच हे प्रोग्राम तयार करणे आणि डीबग करण्याची प्रक्रिया सुलभ करण्यासाठी, विकासकांनी सर्व परिधीय उपकरणे "इंटरप्ट सोर्स" ने सुसज्ज केली आहेत ( व्यत्यय स्त्रोत), काही उपकरणांमध्ये एकाधिक व्यत्यय स्रोत असू शकतात.

व्यत्यय स्त्रोत वापरून, ते लागू केले जाते सिंक्रोनाइझेशन यंत्रणा, प्रोसेसर आणि पेरिफेरल डिव्हाइसमध्ये, म्हणजे, प्रोसेसर पेरिफेरल डिव्हाइसवर डेटा, पोलिंग ध्वज आणि इतर क्रिया प्राप्त करण्यास सुरुवात करेल, जेव्हा डिव्हाइस यासाठी तयार असेल (ते डेटा प्रोसेसिंग पूर्ण केल्याची तक्रार करेल, दरम्यान त्रुटी डेटा प्रोसेसिंग, रजिस्टर रिकामे आहे, इ.) इ.), "इंटरप्ट रिक्वेस्ट" व्युत्पन्न करून ( व्यत्यय विनंती), काही ध्वजाच्या मूल्यावर अवलंबून (डिव्हाइस/फंक्शन/इव्हेंट स्थिती).

साहित्यात, बऱ्याचदा, “इंटरप्ट रिक्वेस्ट” (IRQ) पासून “इंटरप्ट सर्व्हिस प्रोसिजर” (ISR) पर्यंतच्या घटनांची संपूर्ण साखळी एक व्यत्यय म्हणून संक्षिप्त केली जाते ( व्यत्यय आणणे).

व्यत्यय म्हणजे काय?


व्यत्यय हा एक सिग्नल आहे जो इव्हेंटच्या घटनेबद्दल प्रोसेसरला सूचित करतो. या प्रकरणात, आदेशांच्या वर्तमान क्रमाची अंमलबजावणी निलंबित केली जाते आणि या इव्हेंटशी संबंधित व्यत्यय हाताळणी प्रक्रियेवर नियंत्रण हस्तांतरित केले जाते, त्यानंतर कोडची अंमलबजावणी ज्या ठिकाणी व्यत्यय आणली होती तिथूनच चालू राहते (नियंत्रण परत येणे). (विकी)

नित्यक्रमात व्यत्यय आणा(इंटरप्ट सर्व्हिस रूटीन) हे फंक्शन/सबरुटीनपेक्षा अधिक काही नाही जे एखादी विशिष्ट घटना घडल्यावर अंमलात आणले पाहिजे. इतर सर्व फंक्शन्सच्या फरकावर जोर देण्यासाठी आम्ही "प्रक्रिया" हा शब्द वापरू.

प्रक्रिया आणि साध्या फंक्शन्समधील मुख्य फरक असा आहे की नेहमीच्या “रिटर्न फ्रॉम फंक्शन” (असेंबली कमांड RET) ऐवजी, तुम्ही “रिटर्न फ्रॉम इंटरप्ट” (असेंबलर कमांड RETI) - " वापरावे. इंटरप्ट वरून परत या".

AVR व्यत्यय गुणधर्म:

  • AVR मायक्रोकंट्रोलरचा भाग असलेल्या प्रत्येक परिधीय उपकरणामध्ये किमान एक व्यत्यय स्त्रोत असतो. या सर्व व्यत्ययांमध्ये, रीसेट व्यत्यय देखील समाविष्ट केला पाहिजे, ज्याचा उद्देश इतर सर्वांपेक्षा वेगळा आहे.
  • प्रत्येक व्यत्ययाला एक काटेकोरपणे नियुक्त केलेला वेक्टर (लिंक) असतो जो व्यत्यय सेवा दिनचर्याकडे निर्देश करतो. सर्व व्यत्यय वेक्टर प्रोग्राम मेमरीच्या अगदी सुरुवातीला स्थित असतात आणि एकत्रितपणे "इंटरप्ट वेक्टर टेबल" तयार करतात.
  • प्रत्येक व्यत्यय विशिष्ट "इंटरप्ट सक्षम बिट" शी संबंधित आहे अशा प्रकारे, विशिष्ट व्यत्यय वापरण्यासाठी, तुम्ही त्याच्या "इंटरप्ट सक्षम बिट" - लॉगवर लिहावे. युनिट पुढे, तुम्ही काही व्यत्यय सक्षम केले आहेत की नाही याची पर्वा न करता, SREG स्थिती नोंदवहीमध्ये "ग्लोबल इंटरप्ट इनेबल बिट" वर लॉजिकल लिहिले जात नाही तोपर्यंत मायक्रोकंट्रोलर या व्यत्ययांवर प्रक्रिया करणे सुरू करणार नाही (यासाठी अनिश्चित काळ), सामान्य इंटरप्ट सक्षम बिटवर लॉग शून्य लिहिला जावा.

रीसेट व्यत्यय, इतर सर्व विपरीत, अक्षम केले जाऊ शकत नाही. अशा व्यत्ययांना नॉन-मास्क करण्यायोग्य व्यत्यय देखील म्हणतात.

  • प्रत्येक व्यत्ययाला काटेकोरपणे परिभाषित प्राधान्य असते. व्यत्ययाची प्राथमिकता "इंटरप्ट वेक्टर टेबल" मधील त्याच्या स्थानावर अवलंबून असते, जेवढे कमी व्हेक्टर संख्या असते, तितकेच इंटरप्टचे प्राधान्य असते, जे प्रथम स्थित असते टेबल, आणि त्यानुसार मेमरी प्रोग्राम्समध्ये, "इंटरप्ट व्हेक्टर टेबल" मध्ये रिसेट इंटरप्टच्या अनुषंगाने बाह्य व्यत्यय INT0 ची प्राथमिकता रीसेटपेक्षा कमी आहे, परंतु इतर सर्व व्यत्ययांपेक्षा जास्त आहे.

रिसेट वेक्टर व्यतिरिक्त इंटरप्ट वेक्टर टेबल, जीआयसीआर रजिस्टरमध्ये IVSEL बिट सेट करून फ्लॅश मेमरीच्या बूट सेक्शनच्या सुरुवातीला हलवता येते. रीसेट व्हेक्टर फ्यूज बिट - BOOTRST प्रोग्रामिंग करून फ्लॅश मेमरीच्या बूट विभागाच्या सुरूवातीस देखील हलविला जाऊ शकतो.



Fig.1 ATmega16 इंटरप्ट वेक्टर टेबल

रुटीन प्रोटोटाइप व्यत्यय आणा


फंक्शनला इंटरप्ट हँडलिंग रूटीन म्हणून घोषित करण्यासाठी, तुम्ही विशिष्ट प्रोटोटाइपिंग नियमांचे पालन केले पाहिजे जेणेकरून कंपायलर/लिंकर तुम्हाला आवश्यक असलेला व्यत्यय त्याच्या हँडलिंग रूटीनसह योग्यरित्या ओळखू शकेल आणि संबद्ध करू शकेल.

प्रथम, व्यत्यय सेवा दिनचर्या कोणत्याही गोष्टीला वितर्क म्हणून स्वीकारू शकत नाही (रिकामा), आणि काहीही परत करू शकत नाही (रिकामा). हे या वस्तुस्थितीमुळे आहे की AVR मधील सर्व व्यत्यय असिंक्रोनस आहेत, त्यामुळे प्रोग्रामच्या अंमलबजावणीमध्ये कुठे व्यत्यय येईल, कोणाकडून प्राप्त करावे आणि कोणाला मूल्य परत करावे, तसेच प्रवेशाची वेळ कमी करण्यासाठी हे माहित नाही आणि व्यत्ययातून बाहेर पडा.

void isr(void)

दुसरे म्हणजे, फंक्शन प्रोटोटाइप करण्यापूर्वी, तुम्ही हे सूचित केले पाहिजे की ही एक व्यत्यय हाताळणी प्रक्रिया आहे. तुम्हाला माहिती आहे की, C भाषेत फक्त मुख्य फंक्शनमध्ये वापरलेला कोड कार्यान्वित केला जातो. मुख्य फंक्शनमधील व्यत्यय हाताळण्याची प्रक्रिया कुठेही वापरली जात नसल्यामुळे, कंपाइलर अनावश्यक म्हणून "फेकून" देत नाही, प्रक्रियेच्या नमुना आधी हे सूचित केले पाहिजे की हे कार्य एक व्यत्यय हाताळणी प्रक्रिया आहे.

AVR स्टुडिओ वातावरणात व्यत्यय हाताळणी प्रक्रियेचा नमुना

#समाविष्ट करा

ISR (XXX_vect)
{

}

AVR स्टुडिओ (AVR GCC) मध्ये, प्रत्येक व्यत्यय दिनचर्या ISR मॅक्रो व्याख्येने सुरू होते, त्यानंतर कंसात खालील रचना असते:

XXX_vect

जेथे "XXX" हे व्यत्यय वेक्टरचे नाव आहे, विशिष्ट AVR मायक्रोकंट्रोलरसाठी सर्व वेक्टर नावे मायक्रोकंट्रोलरच्या डेटाशीटच्या "इंटरप्ट वेक्टर टेबल" मध्ये किंवा त्याच्या शीर्षलेख फाइलमध्ये आढळू शकतात. उदाहरणार्थ, ATmega16 मायक्रोकंट्रोलरसाठी "इंटरप्ट व्हेक्टर टेबल" चित्र 1 मध्ये दाखवले आहे, जेथे स्त्रोत कॉलममध्ये इंटरप्ट व्हेक्टरची सर्व नावे या मायक्रोकंट्रोलरच्या हेडर फाइलमध्ये देखील आढळू शकतात :\Program Files\Atmel\AVR Tools\AVR Toolchain\avr\include\avr\iom16.h), चित्र 2 पहा. आपल्याला फक्त टेबलमध्ये आवश्यक असलेल्या वेक्टरचे नाव शोधायचे आहे आणि प्रत्यय जोडायचा आहे. त्याला “_vect”.


Fig.2 AVR स्टुडिओसाठी ATmega16 शीर्षलेख फाइल

उदाहरणार्थ, USART (USART, Rx Complete) द्वारे बाइट प्राप्त करण्यासाठी व्यत्यय हाताळण्याची प्रक्रिया लिहू:

ISR (USART_RXC_vect)
{
// इंटरप्ट हँडलर बॉडी
}

तसे: AVR स्टुडिओमध्ये कोणताही व्यत्यय वापरण्यापूर्वी, तुम्ही प्रोजेक्टमध्ये हेडर फाइल्स io.h आणि interrupt.h समाविष्ट करा:

#समाविष्ट करा
#समाविष्ट करा

AVR स्टुडिओ (AVR GCC) मधील इंटरप्ट हँडलर्सबद्दल तुम्ही avr-libc च्या इंटरप्ट हँडलिंग विभागाच्या परिचयात अधिक वाचू शकता.

इमेजक्राफ्ट वातावरणात व्यत्यय हाताळणी प्रक्रियेचा नमुना

#pragma interrupt_handler : iv_XXX
शून्य< handler_name>(रिकामा)
{
// इंटरप्ट हँडलर बॉडी
}

इमेजक्राफ्ट वातावरणात, प्रोटोटाइप इंटरप्ट रूटीन असे दिसते:

शून्य< handler_name>(रिकामा)

कुठे , तुम्हाला या व्यत्यय हँडलरला कोणतेही नाव द्यायचे आहे. व्यत्यय हाताळण्याची प्रक्रिया घोषित करण्यासाठी आवश्यक असलेली एक अशी आहे की फंक्शन प्रोटोटाइपच्या आधी ते एक व्यत्यय हँडलर असल्याचे सूचित केले पाहिजे. हे प्राग्मा निर्देश वापरून केले जाते interrupt_handler :

#pragma interrupt_handler : iv_XXX

कुठे हे फंक्शनचे नाव आहे जो इंटरप्ट हँडलर म्हणून वापरला जाईल आणि "iv_XXX" हे इंटरप्ट व्हेक्टरचे नाव आहे (XXX) AVR स्टुडिओच्या बाबतीत, सर्व वेक्टर नावे विशिष्ट AVR मायक्रोकंट्रोलरसाठी दिलेल्या मायक्रोकंट्रोलरच्या डेटाशीटच्या “इंटरप्ट वेक्टर टेबल” मध्ये किंवा त्याच्या शीर्षलेख फाइलमध्ये आढळू शकते (चित्र 3 पहा).


Fig.3 ImageCraft IDE साठी ATmega16 शीर्षलेख फाइल

उदाहरणार्थ, इमेजक्राफ्ट वातावरणात USART (USART, Rx Complete) द्वारे बाइट प्राप्त करण्यासाठी व्यत्यय हाताळण्याची प्रक्रिया यासारखी दिसेल:

#pragma interrupt_handler usart_rxc_isr: iv_USART_RXC
void usart_rxc_isr(void)
{
// इंटरप्ट हँडलर बॉडी
}

इमेजक्राफ्ट IDE मधील व्यत्यय हाताळण्याच्या प्रक्रियेबद्दल अधिक माहिती हेल्प->प्रोग्रामिंग द AVR->इंटरप्ट हँडलर्स मेनूमध्ये आढळू शकते.

काहीवेळा, जर अनेक इंटरप्ट हँडलर्सना एकच गोष्ट करायची असेल, तर प्रोग्राम मेमरी सेव्ह करण्यासाठी, तुम्ही अनेक इंटरप्ट वेक्टर्सना एकाच इंटरप्ट रूटीनमध्ये निर्देशित करू शकता.

AVR स्टुडिओमध्ये हे असे दिसते:

ISR (INT0_vect)
{
// काहीतरी कर
}
ISR(INT1_vect, ISR_ALIASOF(INT0_vect) );

प्रथम विशिष्ट वेक्टरसाठी व्यत्यय प्रक्रिया प्रक्रिया येते, या प्रकरणात INT0. इतर सर्व प्रक्रिया कन्स्ट्रक्ट वापरून कोणत्याही व्यत्यय हँडलरचा संदर्भ घेऊ शकतात:

ISR (YYY_vect, ISR_ALIASOF(XXX_vect) );

जेथे YYY हे व्यत्यय वेक्टरचे नाव आहे जे व्हेक्टर XXX साठी पूर्वी घोषित केलेल्या व्यत्यय हँडलरचा संदर्भ देते.

इमेजक्राफ्टमध्ये हे असे दिसते:

#pragma interrupt_handler : iv_XXX : iv_YYY
शून्य< handler_name>(रिकामा)
{
// इंटरप्ट हँडलर बॉडी
}

#pragma interrupt_handler : iv_XXX
#pragma interrupt_handler : iv_YYY
शून्य< handler_name>(रिकामा)
{
// इंटरप्ट हँडलर बॉडी
}

जेथे वेक्टर XXX आणि YYY समान इंटरप्ट हँडलरचा संदर्भ घेतात .

AVR मायक्रोकंट्रोलरमध्ये व्यत्यय कसा कार्य करतो?

1. गृहीत धरूया " व्यत्यय विनंती” (IRQ).

तसे: व्यत्यय प्रक्रियेसाठी अनेक विनंत्या एकाच वेळी आल्यास, सर्वोच्च प्राधान्य असलेल्या व्यत्ययावर प्रथम प्रक्रिया केली जाईल, उच्च-प्राधान्य व्यत्यय पूर्ण झाल्यानंतर इतर सर्व विनंत्यांवर प्रक्रिया केली जाईल.

2. परीक्षा.

जर या व्यत्ययासाठी सक्षम बिट सेट केले असेल (इंटरप्ट सक्षम बिट), आणि प्रोसेसर स्टेटस रजिस्टर (एसआरईजी) चा आय-बिट (सामान्य इंटरप्ट सक्षम बिट) सेट केला असेल, तर प्रोसेसर इंटरप्ट सर्व्हिस रूटीन तयार करण्यास सुरवात करतो, तर सामान्य इंटरप्ट सक्षम बिट (रजिस्टर एसआरईजीचा आय-बिट) रीसेट केला जातो, त्यामुळे इतर सर्व व्यत्यय अक्षम होतो. हे असे घडते की इतर कोणतीही घटना वर्तमान व्यत्ययाच्या प्रक्रियेत व्यत्यय आणू शकत नाही.

तसे: जर व्यत्यय हाताळणी प्रक्रियेत तुम्ही I-bit ला लॉग स्थितीत सेट केले असेल. युनिट्स, नंतर कोणताही सक्रिय व्यत्यय चालू व्यत्ययाच्या प्रक्रियेत व्यत्यय आणू शकतो. अशा व्यत्ययांना नेस्टेड इंटरप्ट्स म्हणतात.

3. तयारी.

प्रोसेसर सध्याच्या असेंबली निर्देशांची अंमलबजावणी पूर्ण करतो आणि नंतर पुढील सूचनांचा पत्ता स्टॅकवर ठेवतो (PC->STACK). पुढे, प्रोसेसर तपासतो की कोणत्या व्यत्यय स्त्रोताने "इंटरप्ट रिक्वेस्ट" (IRQ) सबमिट केली आहे, त्यानंतर, व्हेक्टर टेबलवरून या स्त्रोताचा (लिंक) वेक्टर वापरून (जो प्रत्येक व्यत्यय स्त्रोताला निश्चितपणे नियुक्त केला आहे), तो पुढे जातो. इंटरप्ट प्रोसेसिंग प्रक्रिया (जेएमपी निर्देश) इतकेच, प्रोसेसर कमीतकमी 4 घड्याळ चक्रे खर्च करतो (विनंती दिसण्याच्या क्षणावर आणि वर्तमान निर्देशांच्या अंमलबजावणीच्या कालावधीवर अवलंबून). इतर उत्पादकांकडून मायक्रोकंट्रोलर.

तसे: मायक्रोकंट्रोलर स्लीप मोडमध्ये असताना IRQ उद्भवल्यास, IRQ ला प्रतिसाद वेळ आणखी चार घड्याळ चक्रांनी वाढतो, तसेच फ्यूज बिट्स SUT1 आणि SUT0 (स्टार्ट-अप टाइम) मध्ये साठवलेला वेळ.

स्टॅक हे मेमरीचे क्षेत्र आहे जे CPU सबरूटीनमधून परतीचे पत्ते संचयित आणि पुनर्संचयित करण्यासाठी वापरते.
जवळजवळ सर्व AVR मायक्रोकंट्रोलरमध्ये SRAM मध्ये स्टॅक असतो. वर्तमान घटक (स्टॅकच्या शीर्षस्थानी) संबोधित करण्यासाठी, स्टॅक पॉइंटर एसपी (स्टॅक पॉइंटर) वापरला जातो. 256 बाइट्स पर्यंत डेटा मेमरी क्षमता असलेल्या मॉडेलसाठी हा एक-बाइट RVV SPL आहे, किंवा दोन-बाइट SPH:SPL (SPH - उच्च बाइट, SPL - कमी बाइट).

जेव्हा मायक्रोप्रोसेसरला rcall/call/ecall/icall/eicall या कॉल निर्देशांपैकी एक आढळतो, तेव्हा प्रोग्राम मेमरीमधील पुढील शब्दाचा पत्ता हार्डवेअरद्वारे स्टॅकवर कॉपी केला जातो. जेव्हा ret कमांड सबरूटीनमधून बाहेर पडते, तेव्हा परतीचा पत्ता स्टॅकवरून प्रोग्राम काउंटरवर पुनर्संचयित केला जातो. 128 आणि 256 किलोवर्ड्सच्या प्रोग्राम मेमरी क्षमतेच्या मॉडेल्समध्ये, पीसीला स्टॅकवर सेव्ह करण्यासाठी 3 बाइट्स आवश्यक असतील, इतर सर्वांसाठी - 2 बाइट्स. प्रत्येक बाइट संचयित करताना, एसपीची सामग्री एकाने कमी केली जाते आणि पुनर्संचयित केल्यावर, त्यानुसार वाढविली जाते.

Fig.9 डेटा मेमरी मध्ये स्टॅक स्थान

प्रोग्रामरने प्रोग्रामच्या अगदी सुरुवातीला स्टॅकचे स्थान स्वतंत्रपणे निर्धारित केले पाहिजे. त्याच्या कमाल खोलीच्या दृष्टिकोनातून, आकृती 9 मध्ये दर्शविल्याप्रमाणे, स्टॅकचा वरचा भाग SRAM च्या अगदी शेवटी ठेवला पाहिजे:

"m8def.inc" ldi temp,low(RAMEND) समाविष्ट करा ;SP = RAMEND बाहेर SPL,तापमान सेट करा ;ATmega8 SP = 0x045F ldi temp साठी, SPH पेक्षा उच्च(RAMEND) तापमान,तापमान

मानक m8def.inc शीर्षलेख फाइलमधील RAMEND स्थिरांकामध्ये शेवटच्या SRAM सेलच्या पत्त्याचे मूल्य आहे.

ऍप्लिकेशन प्रोग्राम व्हेरिएबल्स RBB आणि सध्याच्या SP स्थिती दरम्यान SRAM ॲड्रेस रेंजमध्ये स्थित आहेत. म्हणून, प्रथम जास्तीत जास्त स्टॅक आकाराचा (स्टॅक डेप्थ) अंदाज लावणे फार महत्वाचे आहे. असे होऊ शकते की स्टॅकचा वरचा भाग खूप उंचावतो आणि वापरकर्ता डेटा "ओव्हरराइट" करण्यास सुरवात करतो आणि ही सर्वात कठीण त्रुटींपैकी एक आहे!

AVR स्टॅक, रिटर्न पत्ते संग्रहित करण्याव्यतिरिक्त, आणखी एक महत्त्वाचा उद्देश आहे. हे तुम्हाला पुश आरआर (स्टॅकवर लोड) आणि पॉप आरडी (स्टॅकमधून अनलोड) कमांडचा वापर करून कोणताही डेटा जतन करण्याची परवानगी देते. प्रत्येक वेळी पुश आरआर कार्यान्वित केल्यावर, आरआरची सामग्री स्टॅकवर कॉपी केली जाते, त्यानंतर एसपी एकाने कमी केला जातो. पॉप Rr कार्यान्वित केल्यावर, SP द्वारे निर्देशित केलेल्या स्टॅक सेलची सामग्री Rr वर पुनर्संचयित केली जाते आणि SP चे मूल्य स्वतःच वाढवले ​​जाते. या प्रकारच्या स्टॅकमध्ये लास्ट इन फर्स्ट आउट संस्था असते: शेवटच्या पुश कमांडद्वारे सेव्ह केलेले रजिस्टर पहिल्या पॉप कमांडद्वारे पुनर्संचयित केले जाईल:

; पुश कमांड R16 नंतर SP स्टॅक पातळी ;R16 0x045F R16 जतन करा ? ? R17 पुश करा ;R17 0x045E R16 R17 वाचवा? R18 पुश करा ;R18 0x045D R16 R17 R18 ̣̣̣̣̣̣̣̣ pop R18 ;R18 0x045D R16 R17 पुनर्संचयित करा ? पॉप R17 ; R17 0x045E R16 पुनर्संचयित करा ? ? पॉप R16 ; R16 0x045F पुनर्संचयित करा? ? ?

स्टॅकचा वापर करून, तुम्ही रजिस्टर्सची सामग्री अगदी सहजपणे स्वॅप करू शकता:

; एक्सचेंज R16<->पुश कमांड R16 नंतर R17 SP स्टॅक पातळी ;R16 0x045F R16 जतन करा ? R17 पुश करा ;R17 0x045E R16 R17 पॉप R16 जतन करा ;R16 0x045E R16 पुनर्संचयित करा ? पॉप R17 ; R17 0x045F पुनर्संचयित करा? ?


अंजीर. 10 स्टॅक ऑपरेशनचे उदाहरण

आकृती 10 कोडचा एक छोटासा तुकडा दर्शवितो जो टॉगल सबरूटीनमध्ये प्रवेश करताना आणि बाहेर पडताना आणि नोंदणी R17 जतन आणि पुनर्संचयित करताना स्टॅक बदलण्याची चरण-दर-चरण प्रक्रिया दर्शवितो. हे एक सामान्य उदाहरण आहे जेथे पुश/पॉप सूचना आवश्यक असू शकतात. टॉगल सबरूटीन त्याच्या गरजेसाठी R17 RON वापरते, परंतु हेच रजिस्टर मुख्य कार्यक्रमादरम्यान देखील वापरले जाऊ शकते. म्हणून, डेटा करप्शन टाळण्यासाठी, R17 बदल करण्यापूर्वी स्टॅकवर लोड केले जाते आणि ret कमांडच्या आधी ते पुनर्संचयित केले जाते.


व्यत्ययाबद्दल बोलूया.व्यत्यय हा शब्द स्वतःसाठी बोलतो; अतिरिक्त क्रिया करण्यासाठी प्रक्रिया काही काळ थांबविली जाते. व्यत्यय बाह्य किंवा अंतर्गत असू शकतात. मी माझ्या मित्राकडून ऐकलेले एक साधे उदाहरण देतो...

तो स्वयंपाकघरात भांडी धुण्यासाठी तयार झाला, उत्साहाने सुरुवात केली, बाही गुंडाळली... पण भांडी स्निग्ध निघाली आणि त्याला स्वयंपाकघरातील एका कपाटावर स्निग्ध भांडी धुण्यासाठी डिटर्जंट शोधण्यासाठी थांबवावे लागले. , त्यानंतर त्याने पुन्हा आपले कार्य चालू ठेवले. पण काही वेळात फोन वाजला, आणि त्याने पुन्हा त्याच्या कामाला विराम दिला, फोन उचलला, त्याच्या सासूने फोन केला आणि सांगितले की ती भेटायला येत आहे, म्हणून तिला तिच्या आधी किराणा सामान घेण्यासाठी दुकानात जावे लागेल. पोहोचले मी दुकानात गेलो आणि मगच भांडी धुतली.

हे उदाहरण दोन प्रकारचे व्यत्यय दर्शविते, पहिले मुख्य कामाच्या अंमलबजावणीशी संबंधित आहे - स्निग्ध पदार्थांसाठी डिटर्जंट शोधणे - अंतर्गत व्यत्यय, दुसरा - एक फोन कॉल - बाह्य व्यत्यय.
मायक्रोकंट्रोलरमध्ये, बाह्य व्यत्यय इतर स्त्रोतांकडून येणाऱ्या सिग्नलमुळे उद्भवतात, अंतर्गत व्यत्यय मायक्रोकंट्रोलरमध्येच तयार केलेल्या उपकरणांमुळे उद्भवतात. व्यत्यय इतके आकर्षक का आहेत?
पहिली म्हणजे आपण मुख्य प्रक्रिया थांबवू शकतो आणि दुसरे कार्य करण्यासाठी ही प्रक्रिया सुरू ठेवू शकतो.
दुसरा, आणि कदाचित बऱ्याच प्रकरणांमध्ये मुख्य म्हणजे, अंतर्गत अतिरिक्त उपकरणांमुळे सर्व कार्ये करण्याच्या प्रक्रियेचा प्रवेग. चला आपल्या उदाहरणाकडे परत जाऊया. समजा माझ्या मित्राने त्याची बायको घरी आल्यावर भांडी धुवायला सुरुवात केली. स्निग्ध भांडी पाहून, तो तिला डिशवॉशिंग द्रव शोधण्यास सांगतो, आणि तो धुत असताना, ती त्याला आधीच हे द्रव आणेल. पण नंतर फोन वाजला, माझ्या पत्नीने फोन उचलला, तिच्या आईशी बोलले आणि दुकानात गेली. एकत्र, सर्वकाही खूप लवकर केले गेले!
आणि अडकणे आणखी सोपे आहे - उदा. कोणताही मुख्य कार्यक्रम नाही.
माझा मित्र सोफ्यावर बसतो आणि काहीही करत नाही, घरातील मालक गलिच्छ भांडी पाहतो, त्याला त्याबद्दल सांगतो आणि परवानगी मिळाल्यानंतर स्वत: ला धुण्यास सुरुवात करतो. फोन वाजल्यावर तो बायकोला फोन उचलायला सांगतो, बायको फोनवर बोलत असते आणि संवाद किराणा दुकानात जातो... सौंदर्य! या प्रकरणात, मायक्रोकंट्रोलरमध्ये अनेक I/O उपकरणे एकाच वेळी कार्य करतात (आधुनिक मायक्रोकंट्रोलरमध्ये त्यापैकी बरेच असू शकतात) आणि एकूण प्रोसेसर कार्यप्रदर्शन अनेक वेळा वाढते, परंतु डिव्हाइसेसमधील व्यत्ययांवर एकामागून एक क्रमाने प्रक्रिया केली जाते (एकाच वेळी नाही. ), प्राधान्यावर अवलंबून (आमच्या उदाहरणात, बायकोला घरकाम करणाऱ्यापेक्षा जास्त प्राधान्य आहे).

व्यत्यय व्यवस्थापित करण्यासाठी अनेक रजिस्टर जबाबदार असतात
SREG - स्टेटस रजिस्टर(राज्ये). आम्ही इनपुट-आउटपुट उपकरणांचे टेबल पाहतो. SREG रजिस्टरचा सातवा बिट आहे I (इंटरप्ट) ध्वज, ज्याला ग्लोबल इंटरप्ट सक्षम ध्वज म्हणतात.जर ध्वज वगळला असेल (सातवा बिट शून्य असेल), तर सर्व व्यत्यय अक्षम केले जातात. ध्वज उंचावल्यास (1 वर सेट करा), आम्ही व्यत्यय सक्षम करतो.

I ध्वज सेट केला आहे आणि कमांडसह रीसेट केला आहे:
SEI - व्यत्यय सक्षम करा
CLI - व्यत्यय अक्षम करा
कोणते व्यत्यय कार्य करतील हे रजिस्टर वापरून सेट केले जाते - व्यत्यय मुखवटे.
इंटरप्ट मास्क खालीलप्रमाणे नियुक्त केले आहेत:
TIMSK,..,..,.. – टाइमर आणि इतर अंगभूत उपकरणांमधून व्यत्ययांचे व्यवस्थापन.
GIMSK (मेगा कुटुंबातील GIKR) - सर्व बाह्य व्यत्ययांचे व्यवस्थापन.
व्यत्यय मुखवटे यामधून व्यत्यय ध्वजांवर अवलंबून असतात:
TIFR आणि GIFR अनुक्रमे(ग्लोबल इंटरप्ट सक्षम ध्वज सह गोंधळून जाऊ नका).

व्यत्यय अंमलबजावणी क्रम:
मायक्रोकंट्रोलर चालू केल्यावर, सर्व व्यत्यय ध्वज 0 वर रीसेट केले जातात. व्यत्यय सक्षम करण्यासाठी, प्रोग्रामने SREG रजिस्टरचा ध्वज I 1 वर सेट केला पाहिजे. यानंतर, स्थानिक व्यत्यय सेटसह मास्क रजिस्टरची नोंदणी करा (आम्हाला आवश्यक असलेले व्यत्यय) .
जेव्हा एखादी व्यत्यय विनंती (सिग्नल) येते, तेव्हा ते व्यत्यय ध्वज उंचावते (जरी व्यत्यय अक्षम केला असेल, नेस्टेड व्यत्यय आणि भिन्न व्यत्ययांमध्ये प्राधान्य व्यवस्थापित करण्यासाठी). जर व्यत्यय अक्षम केला नसेल, तर नियंत्रक योग्याशी संपर्क साधेल (इंटरप्ट वेक्टर) - इंटरप्ट वेक्टर, वर्तमान प्रोग्रामला विराम देत आहे.
व्यत्यय वेक्टरप्रोग्राम क्षेत्रातील एक निश्चित रेषा आहे जिथे व्यत्यय येतो तेव्हा प्रोग्राम जातो.
व्यत्यय वेक्टरची संपूर्ण यादी म्हणतात व्यत्यय वेक्टर सारणी, जे स्थित आहे प्रोग्राम कोडच्या सुरूवातीस.
त्यामुळे, ज्या क्षणी व्यत्यय वेक्टरमध्ये प्रवेश केला जातो, त्या क्षणी, SREG रजिस्टरचा I ध्वज आणि व्यत्यय आणणारा ध्वज 0 वर रीसेट केला जातो, इतर व्यत्यय अक्षम करतो. व्यत्यय कार्यान्वित होत असताना इतर व्यत्यय विनंत्या आढळल्यास, त्या व्यत्ययांसाठी ध्वज उंचावले जातात. वर्तमान व्यत्यय पूर्ण झाल्यावर, SREG रजिस्टरचा I ध्वज उंच केला जातो, जो पुढील कार्यान्वित करण्यास अनुमती देतो. जर अनेक विनंत्या आल्या आणि त्यांचे ध्वज उंचावले, तर ज्या व्यत्ययाचा वेक्टर टेबलमधील पत्त्यावर लहान आहे, मेमरीच्या सुरुवातीच्या जवळ आहे, तो प्रथम कार्यान्वित केला जाईल. दुसरा फॉलो करतो, वगैरे. याव्यतिरिक्त, जेव्हा इंटरप्ट प्रोग्रामच्या अंमलबजावणीदरम्यान दुसरा व्यत्यय येतो तेव्हा प्रोग्रामर तथाकथित नेस्टेड इंटरप्ट आयोजित करू शकतो. मग वर्तमान व्यत्ययची अंमलबजावणी थांबविली जाते आणि एक नवीन कार्यान्वित केले जाते, त्यानंतर थांबलेल्या व्यत्ययाची अंमलबजावणी पुन्हा सुरू केली जाते.

उदाहरण म्हणून, ATtiny2313 साठी व्यत्यय वेक्टरची सारणी दिली आहे

Atmega16 साठी व्यत्यय वेक्टर सारणी खालीलप्रमाणे आहे:

तुलना केली असता, सारण्या अजिबात जुळत नाहीत.
एटीटीनी फॅमिलीमध्ये, इंटरप्ट वेक्टर लाइन 16 बिट्स व्यापते आणि मेगा फॅमिलीमध्ये 32 बिट्स लागतात (इंटरप्ट वेक्टरच्या पत्त्यांकडे लक्ष द्या; मी तुम्हाला आठवण करून देतो की प्रोग्राम एरियामधील ॲड्रेस लाइन 16 द्वारे दर्शविली जाते. - बिट शब्द).

ATtiny2313 साठी प्रोग्राम कोड यासारखा दिसू शकतो:
.cseg .org 0 rjmp rjmp INT_0 rjmp INT_1 rjmp टाइमर1_capt1 rjmp टाइमर1_comp1 rjmp टाइमर1_OVF1 rjmp टाइमर0_OVF0 rjmp UART_RX rjmp UART_UDART_COMPrjmp UART_UDRE jmp Timer1_compB rjmp Timer0_compA r jmp Timer0_compB rjmp USI_START rjmp USI_OVERFLOW rjmp EE_READY rjmp WDT_ OVERFLOW

तुम्ही बघू शकता, इंटरप्ट वेक्टर इंटरप्ट प्रोग्राम लेबल्सवर सापेक्ष उडी तयार करतो. खालील तक्ता पर्याय दाखवते; 1. कोणतेही व्यत्यय नसताना; 2, 3. इनपुट INT_1 वर बाह्य व्यत्ययासह.
जर लेबले "रिक्त" असतील (लेबलखाली कोणताही प्रोग्राम नसेल), तर काहीही होत नाही आणि प्रोग्राम अनुक्रमे उर्वरित लेबलांवर "चालतो" आणि सुरक्षितपणे कमांडपर्यंत पोहोचतो. RETI- इंटरप्ट रिटर्न - इंटरप्ट हँडलरमधून बाहेर पडासारणीच्या पहिल्या स्तंभात दाखवल्याप्रमाणे.

इंटरप्ट प्रोग्राम कार्यान्वित करण्यासाठी, उदाहरणार्थ, INT_1 इनपुटवर, तुम्हाला सूचीमधून INT_1: लेबल काढण्याची आवश्यकता आहे. हे सारणीच्या दुसऱ्या स्तंभात योजनाबद्धपणे दर्शविले आहे.
परंतु, प्रत्येक वेळी सर्व व्यत्यय आणि त्यांच्यासाठी स्वतंत्र लेबले लिहिणे प्रोग्रामरसाठी गैरसोयीचे आहे, विशेषत: नवीनतम मॉडेल्समध्ये, जेथे टेबल खूप मोठे असेल तर इंटरप्ट व्हेक्टर लाइनमध्ये त्वरित RETI कमांड लिहिणे सोपे आहे; व्यत्यय वापरला जात नाही. नंतर टेबलच्या तिसऱ्या कॉलममध्ये दाखवल्याप्रमाणे प्रोग्राम दिसेल.

AVR नियंत्रक, मॉडेलवर अवलंबून, 1 ते 8 इनपुट असू शकतात बाह्य व्यत्यय.
चला बाह्य व्यत्यय व्यवस्थापन प्रणालीचा विचार करूया. या उद्देशासाठी, मॉडेलवर अवलंबून I/O नोंदणीचे खालील संयोजन प्रदान केले आहेत (संबंधित डेटाशीट पहा):
- GIMSK, EIFR, PCMSK, MCUCR;
- GIKR, GIFR, MCUCR;
- EIMSK, EICR, EIFR;
GIMSK, GIKR, EIMSK - व्यत्यय मुखवटे,
EIFR, PCMSK, GIFR, EIFR – व्यत्यय झेंडे
परवानगी किंवा मनाई साठी बाह्य व्यत्ययकंट्रोल रजिस्टर्सचा हेतू आहे: GIMSK-(जनरल इंटरप्ट मास्क रजिस्टर)(लघु), GICR- (जनरल इंटरप्ट कंट्रोल रजिस्टर)(मेगा), MCUCR - (MCU कंट्रोल रजिस्टर)




EIFR- बाह्य व्यत्यय ध्वज नोंदणी: 1 - सक्षम, 0 - अक्षम. प्रत्येक बिट (ध्वज) संबंधित पिनला व्यत्यय स्रोत म्हणून कार्य करण्यास अनुमती देतो.

GIMSK रजिस्टर कंट्रोल बिट्स:
बिट 7 – INT1: बाह्य व्यत्यय विनंती 1 सक्षम करा – INT1 व्यत्यय सक्षम करा बिट: 1 – सक्षम, 0 – अक्षम. जरी INT1 पिन आउटपुट म्हणून कॉन्फिगर केला असला तरीही व्यत्यय निर्माण केला जाईल. INT1 बिट EIFR ध्वज नोंदणीमध्ये व्यत्यय आणण्यासाठी सेट आहे. INT1 पिन घड्याळ जनरेटरसह समक्रमित केला जातो.

बिट 6 – INT0: बाह्य व्यत्यय विनंती 0 सक्षम करा - व्यत्यय सक्षम करा बिट INT0: 1 – सक्षम, 0 – अक्षम. जरी INT0 पिन आउटपुट म्हणून कॉन्फिगर केला असला तरीही व्यत्यय निर्माण केला जाईल. INT0 बिट EIFR ध्वज नोंदणीमध्ये व्यत्यय आणण्यासाठी सेट आहे. INT10 पिन घड्याळ जनरेटरसह समक्रमित केला जातो.

बिट 5 - PCIE: पिन चेंज इंटरप्ट सक्षम करा – PCINT0 वर इंटरप्ट सक्षम बिट करा…7 पिन: 1 – सक्षम, 0 – अक्षम. कोणत्याही PCINT0...7 पिनवर कोणताही बदल केल्यास व्यत्यय निर्माण होईल. पिन PCINT0...7 वैयक्तिकरित्या, PCMSK फ्लॅग रजिस्टरमधील बिट्सद्वारे व्यत्ययासाठी कॉन्फिगर केले जातात.

PCMSK- पिन चेंज मास्क रजिस्टर - ध्वज नोंदणी PCMSK: 1 - अनुमत, 0 - अक्षम. प्रत्येक बिट (ध्वज) संबंधित पिनला व्यत्यय स्रोत म्हणून कार्य करण्यास अनुमती देतो. PCINT0...7 पिन घड्याळ जनरेटरसह समक्रमित केलेले नाहीत, उदा. जेव्हा कोणत्याही पिनवर बदल होतो तेव्हा व्यत्यय येतो.

मेगा8

आणि संबंधित ध्वज नोंदणी


बिट 7

बिट 6 – INT0: बाह्य व्यत्यय विनंती 0 सक्षम करा - व्यत्यय सक्षम करा बिट INT0: 1 – सक्षम, 0 – अक्षम. जरी INT0 पिन आउटपुट म्हणून कॉन्फिगर केला असला तरीही व्यत्यय निर्माण केला जाईल. INT0 बिट GIFR ध्वज नोंदणीमध्ये व्यत्यय आणण्यासाठी सेट केले आहे



GIFR – जनरल इंटरप्ट फ्लॅग रजिस्टर: 1 – सक्षम, 0 – अक्षम. प्रत्येक बिट (ध्वज) संबंधित पिनला व्यत्यय स्रोत म्हणून कार्य करण्यास अनुमती देतो.

GICR रजिस्टर कंट्रोल बिट्स:
बिट 7- : बाह्य व्यत्यय विनंती 1 सक्षम करा - इंटरप्ट सक्षम बिट INT1: 1 – अनुमत, 0 – प्रतिबंधित. जरी INT1 पिन आउटपुट म्हणून कॉन्फिगर केला असला तरीही व्यत्यय निर्माण केला जाईल. INT1 बिट GIFR ध्वज नोंदणीमध्ये व्यत्यय आणण्यासाठी सेट केले आहे

बिट 6 – INT0: बाह्य व्यत्यय विनंती 0 सक्षम करा - इंटरप्ट सक्षम बिट INT0: 1 – अनुमत, 0 – प्रतिबंधित. जरी INT0 पिन आउटपुट म्हणून कॉन्फिगर केला असला तरीही व्यत्यय निर्माण केला जाईल. INT0 बिट GIFR ध्वज नोंदणीमध्ये व्यत्यय आणण्यासाठी सेट केले आहे

बिट 5 – INT2: बाह्य व्यत्यय विनंती 2 सक्षम करा - इंटरप्ट सक्षम बिट INT2: 1 – अनुमत, 0 – प्रतिबंधित. जरी INT2 पिन आउटपुट म्हणून कॉन्फिगर केला असला तरीही व्यत्यय निर्माण केला जाईल. INT2 बिट GIFR ध्वज नोंदणीमध्ये व्यत्यय आणण्यासाठी सेट केले आहे

सर्व नियंत्रकांमधील INT0 आणि INT1 इनपुटची कार्ये MCUCR रजिस्टरच्या लो-ऑर्डर बिट्सद्वारे नियंत्रित केली जातात.

MCUCR- MCU कंट्रोल रजिस्टर
नियंत्रण बिट्स:
बिट्स 1, 0 – ISC01, ISC00 (इंटरप्ट सेन्स कंट्रोल 0 बिट 1 आणि बिट 0) – या बिट्सची स्थिती INT0 पिनवरील इव्हेंट निर्धारित करते, जे INT0 व्यत्यय निर्माण करते:
ISC01=0, ISC00=0 – तार्किक शून्य पातळी;
ISC01=0, ISC00=1 – तार्किक स्थितीतील कोणताही बदल;
ISC01=1, ISC00=0 – पडत्या काठावर;
ISC01=1, ISC00=1 – वाढत्या काठावर.

बिट्स 3, 2 – ISC11, ISC10 (इंटरप्ट सेन्स कंट्रोल 1 बिट 1 आणि बिट 0) – या बिट्सची स्थिती INT1 पिनवर सिग्नल पातळी निर्धारित करते, ज्यामुळे INT1 व्यत्यय निर्माण होतो:
ISC11=0, ISC10=0 – तार्किक शून्य पातळी;
ISC11=0, ISC10=1 – तार्किक स्थितीतील कोणताही बदल;
ISC11=1, ISC10=0 – पडत्या काठावर;
ISC11=1, ISC10=1 – वाढत्या काठावर.

बरं, असे दिसते की आम्ही बाह्य व्यत्ययांबद्दल कमीतकमी बोललो आहोत.
हे स्पष्ट आहे की कामात व्यत्यय येण्यासाठी, त्यांना त्यानुसार नोंदणी करणे आवश्यक आहे.
सिग्नलच्या वाढत्या काठावर लहान साठी सुरू झालेल्या INT1 वरील व्यत्ययाचे आरंभीकरण जोडूया:

Ldi r16.0x80 ; r16 मध्ये 0b10000000 ldi r17.0x0C क्रमांक लिहा; r17 मध्ये MCUCR,r17 मधील 0b00001100 क्रमांक लिहा; वाढत्या काठावर व्यत्यय निर्माण केला जाईल ISC11=1, ISC10=1 GIMSK,r16 ; मास्क INT0 sei वर सेट करा
तसे, तुम्ही tiny2313 वर व्यत्यय निर्माण करू शकता कोणत्याही PCINT0…7 पिनवर, मेगा पर्यंत सीरिज 48 वर ही वैशिष्ट्ये उपलब्ध नाहीत...
अशी ऑपरेशन्स आहेत ज्या दरम्यान व्यत्यय येऊ शकतो ज्यामुळे प्रोग्राम क्रॅश होऊ शकतो. अशा परिस्थितीत, ऑपरेशन सुरू करण्यापूर्वी आम्ही CLI लिहितो आणि SEI नंतर. अशा ऑपरेशन्स म्हणतात - अणू.
इंटरप्ट प्रोग्राम्स कॉम्पॅक्ट आणि जास्तीत जास्त वेगाने अंमलात आणणे इष्ट आहे, कारण कोणत्याही व्यत्ययाचा उद्देश इव्हेंट कॅप्चर करणे आहे. जर विविध कारणास्तव प्रोग्राम हळू चालत असेल, तर इव्हेंट रेकॉर्ड करणे आणि थोड्या वेळाने त्यावर प्रक्रिया करणे पुरेसे आहे.

सादर केलेली सामग्री अनावश्यक माहितीसह गोंधळात टाकू नये म्हणून, मी शिफारस करतो की वाचकांनी डेटाशीट वापरावे आणि सर्वकाही स्पष्ट नसल्यास, मंचांवर अधिक वेळा प्रश्न विचारा.
पुढे, आम्ही अंगभूत टाइमरवर आधारित अंतर्गत व्यत्ययांचा तपशीलवार विचार करू. वाचक मतदानात सहभागी होण्यासाठी, नोंदणी करा आणि तुमचे वापरकर्तानाव आणि पासवर्डसह साइटवर लॉग इन करा.

व्यत्यय प्रणाली कोणत्याही नियंत्रण प्रणालीचा एक महत्त्वाचा भाग आहे.

मायक्रोप्रोसेसर प्रणाली किती कार्यक्षमतेने त्याचे कार्य करते हे मुख्यत्वे त्याच्या ऑपरेशनवर अवलंबून असते. MK-51 व्यत्यय प्रणालीची सामान्य रचना अंजीर मध्ये दर्शविली आहे. १४.३.

MK-51 कुटुंबातील मायक्रोकंट्रोलर पाच व्यत्यय स्त्रोतांसाठी समर्थन प्रदान करतात:

* दोन बाह्य व्यत्यय इनपुट INT0 आणि INT1 (अनुक्रमे P3: P3.2 आणि P3.3 पोर्ट लाइन्स) द्वारे येत आहेत;

* टाइमर/काउंटर T/C0 आणि T/C1 कडून दोन व्यत्यय;

* सीरियल पोर्ट व्यत्यय.

व्यत्यय विनंत्या मायक्रोकंट्रोलरच्या विशेष फंक्शन रजिस्टरमध्ये रेकॉर्ड केल्या जातात: IE0, IE1, TF0, TF1 इंटरप्ट विनंत्या INT0, INT1, T/C0 आणि T/C1 या TCON कंट्रोल रजिस्टरमध्ये (टेबल 14.4) आणि ध्वज RI मध्ये असतात. आणि TI सीरियल पोर्ट वरून व्यत्यय आणण्यासाठी विनंती करतो - सीरियल पोर्ट नियंत्रित करण्यासाठी SCON रजिस्टरमध्ये.

तक्ता 14.4. TCON नोंदणी स्वरूप

0 IT0 व्यत्यय INT0 प्रकार सेट करणे

1 IE0 व्यत्यय विनंती ध्वज INT0

2 IT1 इंटरप्ट INT1 चा प्रकार सेट करणे

3 IE1 व्यत्यय विनंती ध्वज INT1

4 TR0 टाइमर/काउंटर 0 सक्षम करा

5 TF0 ओव्हरफ्लो ध्वज (व्यत्यय विनंती) टाइमर/काउंटर 0

6 TR1 टाइमर/काउंटर सक्षम करा 1

टाइमर/काउंटर 1 चा 7 TF1 ओव्हरफ्लो ध्वज (व्यत्यय विनंती).

जेव्हा संबंधित टायमर/काउंटर ओव्हरफ्लो होतो तेव्हा फ्लॅग TF0 आणि TF1 हार्डवेअरद्वारे सेट केले जातात (अधिक तंतोतंत, जेव्हा T/Cx “सर्व” स्थितीतून “सर्व शून्य” स्थितीत संक्रमण होते).

ध्वज IE0 आणि IE1 हे अनुक्रमे बाह्य व्यत्यय IT0 आणि IT1 पासून हार्डवेअरद्वारे सेट केले जातात. बाह्य विनंतीमुळे एकतर संबंधित इनपुटवरील सिग्नल पातळी कमी असताना किंवा जेव्हा हा सिग्नल उच्च ते निम्न स्तरावर स्विच होतो तेव्हा ध्वज सेट केला जाऊ शकतो (फ्रिक्वेंसी MK च्या बाह्य घड्याळाच्या निम्म्यापेक्षा जास्त नाही).

TCON कंट्रोल रजिस्टरमध्ये IT0 आणि IT1 बिट्स सेट करून सॉफ्टवेअरद्वारे विनंती प्रकार कॉन्फिगर केला जातो. ITx = 0 सेट करणे कमी सिग्नल पातळीची विनंती करण्यासाठी इंटरप्ट सिस्टम कॉन्फिगर करते, ITx = 1 - कमी सिग्नल पातळीची विनंती करण्यासाठी व्यत्यय सेट करते.

TI आणि RI ध्वज अनुक्रमे ट्रान्समिशनच्या समाप्तीनंतर किंवा रिसेप्शनच्या समाप्तीनंतर सीरियल इंटरफेस हार्डवेअरद्वारे सेट केले जातात.

सर्व निर्दिष्ट व्यत्यय विनंती ध्वज सेटिंग आणि रीसेट करण्यासाठी प्रोग्रामॅटिकरित्या उपलब्ध आहेत. सॉफ्टवेअरमध्ये इंटरप्ट रिक्वेस्ट फ्लॅग सेट केल्याने मायक्रोकंट्रोलरकडून हार्डवेअरमध्ये समान ध्वज सेट केल्याप्रमाणेच प्रतिसाद मिळतो.

फ्लॅग्ज TF0 आणि TF1 हार्डवेअरद्वारे रीसेट केले जातात जेव्हा नियंत्रण संबंधित व्यत्यय दिनचर्यामध्ये हस्तांतरित केले जाते.

IEx ध्वज रीसेट करणे हार्डवेअरमध्ये इंटरप्ट सर्व्हिसिंग करताना केले जाते फक्त जर व्यत्यय INTx सिग्नलचा पडणे समजण्यासाठी कॉन्फिगर केले असेल. विनंती सिग्नलची पातळी समजण्यासाठी व्यत्यय कॉन्फिगर केला असल्यास, IEx ध्वज रीसेट करणे व्यत्यय सेवा प्रोग्रामद्वारे केले जाणे आवश्यक आहे, विनंती काढून टाकण्यासाठी व्यत्यय स्त्रोतावर कार्य करणे.

TI आणि RI ध्वज फक्त सॉफ्टवेअरद्वारे रीसेट केले जाऊ शकतात.

प्रत्येक प्रकारचा व्यत्यय IE इंटरप्ट सक्षम रजिस्टरचे संबंधित बिट सेट करून किंवा साफ करून वैयक्तिकरित्या सक्षम किंवा अक्षम केला जातो. या रजिस्टरमध्ये सर्व व्यत्ययांसाठी सामान्य अक्षम बिट देखील समाविष्ट आहे. IE रजिस्टरचे स्वरूप टेबलमध्ये दिलेले आहे. १४.५.

तक्ता 14.5. IE रजिस्टर बिट्सची नियुक्ती

नोंदणी स्थिती

बिट नेमोनिक्स

कार्य

सर्व स्त्रोतांकडून व्यत्यय अक्षम करा

न वापरलेले

न वापरलेले

पासून व्यत्यय अक्षम करा सिरियल पोर्ट

T/C1 टाइमर/काउंटर व्यत्यय अक्षम करा

बाह्य स्रोत INT1 वरून व्यत्यय अक्षम करा

टायमर/काउंटर इंटरप्ट T/C0 अक्षम करा

बाह्य स्रोत INT0 वरून व्यत्यय अक्षम करा

प्रत्येक प्रकारच्या व्यत्ययाला दोन संभाव्य प्राधान्यांपैकी एक प्रोग्रामॅटिकरित्या नियुक्त केले जाऊ शकते: 0 - सर्वात कमी किंवा 1 - सर्वोच्च.

IP इंटरप्ट प्रायॉरिटी रजिस्टरमध्ये संबंधित बिट सेट करून किंवा साफ करून प्राधान्यक्रम कॉन्फिगर केले जातात. या रजिस्टरचे स्वरूप तक्त्यामध्ये दिलेले आहे. १४.६.

जेव्हा भिन्न प्राधान्यक्रम असलेल्या स्त्रोतांकडून एकाच वेळी व्यत्यय विनंत्या प्राप्त होतात, तेव्हा उच्च प्राधान्य स्त्रोताकडून आलेल्या विनंतीवर प्रथम प्रक्रिया केली जाते.

समान प्राधान्याने अनेक व्यत्यय विनंत्या एकाच वेळी मिळाल्याच्या बाबतीत, त्यांच्या प्रक्रियेचा क्रम मायक्रोकंट्रोलर हार्डवेअरद्वारे निर्धारित केला जातो आणि सॉफ्टवेअरद्वारे बदलला जाऊ शकत नाही. हा क्रम मतदान व्यत्यय विनंती ध्वजांच्या क्रमाशी संबंधित आहे, जे यासारखे दिसते:

IT0 -> TF0 -> IT1 -> TF1 -> (RI, TI)

तक्ता 14.6. आयपी रजिस्टर बिट असाइनमेंट

नोंदणी स्थिती बिट मेमोनिक फंक्शन

7 - वापरलेले नाही

6 - वापरलेले नाही

5 - वापरलेले नाही

4 PS सीरियल पोर्ट व्यत्यय प्राधान्य

3 PT1 टाइमर/काउंटर इंटरप्ट प्राधान्य T/C1

बाह्य स्रोत INT1 वरून 2 PX1 व्यत्यय प्राधान्य

1 PT0 टाइमर/काउंटर इंटरप्ट प्राधान्य T/C0

बाह्य स्रोत INT0 वरून 0 PX0 व्यत्यय प्राधान्य

हार्डवेअर-अंमलबजावणी केलेल्या इंटरप्ट हँडलर कॉलमध्ये खालील क्रिया असतात:

* स्टॅकवरील प्रोग्राम काउंटरचे मूल्य वाचवणे;

प्रत्येक व्यत्यय स्त्रोतासाठी इंटरप्ट हँडलर एंट्री पॉइंट हार्डवेअरमध्ये निश्चित केले आहेत. त्यांची मूल्ये टेबलमध्ये दिली आहेत. १४.७.

तक्ता 14.7. हँडलरला व्यत्यय आणण्यासाठी एंट्री पॉइंटचे पत्ते

व्यत्यय स्त्रोत

हँडलरला व्यत्यय आणण्यासाठी एंट्री पॉइंटचे पत्ते

बाह्य व्यत्यय( ITO)

टाइमर-काउंटर (TFO)

बाह्य व्यत्यय (IT1)

टाइमर-काउंटर(TF1)

सिरीयल पोर्ट (R1 किंवा T1)

इंटरप्ट हँडलरची पहिली कमांड निर्दिष्ट पत्त्यावर स्थित असावी. नियमानुसार, अशी आज्ञा म्हणजे हँडलर प्रत्यक्षात स्थित असलेल्या प्रोग्राममधील ठिकाणी बिनशर्त उडी मारण्याची आज्ञा आहे.

इंटरप्ट हँडलिंग रूटीनवर स्विच करताना, आपोआप, IE रजिस्टरची स्थिती विचारात न घेता, सर्व्हिस केलेल्या व्यत्ययाच्या प्राधान्य पातळीच्या समान प्राधान्य स्तर असलेले सर्व व्यत्यय अक्षम केले जातात - म्हणजेच समान प्राधान्य पातळीसह नेस्टेड इंटरप्ट अक्षम केले जातात. . अशा प्रकारे, कमी-प्राधान्य व्यत्यय (आयपी रजिस्टरच्या संबंधित बिटमध्ये "0" असणे) उच्च-प्राधान्य व्यत्यय (आयपी रजिस्टरच्या संबंधित बिटमध्ये "1" असणे) द्वारे व्यत्यय आणू शकतो, परंतु नाही. कमी-प्राधान्य एक. उच्च प्राधान्य व्यत्यय सेवा करणे दुसर्या स्त्रोताद्वारे व्यत्यय आणू शकत नाही.

इंटरप्ट हँडलरकडून रिटर्निंग RETI सूचना वापरून पूर्ण केले जाते, जे स्टॅकमधून इंटरप्ट हँडलरला कॉल केल्यावर तेथे संग्रहित पीसी प्रोग्राम काउंटरचे मूल्य आणि इंटरप्ट प्रायोरिटी लॉजिक पुनर्संचयित करते.

बाह्य व्यत्यय कशासाठी वापरले जातात?

व्यत्यय ही एक घटना आहे ज्याद्वारे मुख्य प्रोग्राम कोडची अंमलबजावणी (उदाहरणार्थ, मुख्य कार्य) व्यत्यय आणली जाते आणि नियंत्रण फंक्शनच्या इंटरप्ट हँडलरकडे हस्तांतरित केले जाते. त्यानुसार, बाह्य व्यत्यय हे काही बाह्य घटना आहेत जे मुख्य प्रोग्राम कोडच्या अंमलबजावणीमध्ये व्यत्यय आणतात.

बाह्य व्यत्यय आपल्याला बाह्य कार्यक्रमांना जलद, हमी दिलेला प्रतिसाद मिळविण्यास अनुमती देतात. म्हणून, बाह्य व्यत्ययांचा सर्वात सामान्य वापर म्हणजे पल्स काउंटरची अंमलबजावणी, वारंवारता किंवा पल्स कालावधीचे मोजमाप, uart, एक-वायर, i2c, spi चे सॉफ्टवेअर अंमलबजावणी, तसेच बाह्य परिधीय उपकरणांमधून सिग्नलवर प्रक्रिया करणे.

AVR मध्ये बाह्य व्यत्ययांच्या ऑपरेशनचे सिद्धांत

मायक्रोकंट्रोलरला बाह्य घटनांबद्दल जाणून घेण्यासाठी, स्वतंत्र इनपुट INT0 INT1, इत्यादी वापरल्या जातात. स्वतंत्र म्हणजे ते तार्किक स्तरांसह कार्य करतात: 0 आणि 1.
इनपुटवर 0 हा व्होल्टेज नाही
1 - इनपुटवर व्होल्टेजची उपस्थिती, जी मायक्रोकंट्रोलरच्या पुरवठा व्होल्टेजच्या समान आहे.

बाह्य व्यत्यय दोन प्रकारांमध्ये विभागले जाऊ शकतात:

  • पातळीनुसार बाह्य व्यत्यय
  • बाह्य धार व्यत्यय

स्तरानुसार बाह्य व्यत्यय

बाह्य व्यत्यय ट्रिगर कमी किंवा उच्च करण्यासाठी कॉन्फिगर केले जाऊ शकते. उदाहरणार्थ, जर व्यत्यय लॉजिक लो वर सेट केला असेल, तर जेव्हा INT इनपुटवरील व्होल्टेज शून्य असेल तेव्हा असे होते. जर व्यत्यय उच्च स्तरावर सेट केला असेल, तर इनपुट लॉजिकल 1 असेल तेव्हा असे घडते.
स्तर-आधारित व्यत्ययांसह कार्य करताना, तुम्ही हे लक्षात ठेवले पाहिजे की जोपर्यंत INT इनपुटमध्ये योग्य स्तर आहे, तोपर्यंत व्यत्यय सतत येत राहील. त्या. जर एखादा व्यत्यय आला, उदाहरणार्थ निम्न स्तरावर, आणि प्रोग्राम त्यावर प्रक्रिया करतो, परंतु, इंटरप्ट हँडलरमधून बाहेर पडताना, इनपुट कमी राहिल्यास, इंटरप्ट पुन्हा सुरू होईल, आणि इंटरप्ट हँडलरला पुन्हा कॉल केला जाईल, आणि हे इनपुट उच्च पातळी दिसेपर्यंत सुरू राहील. हे होण्यापासून रोखण्यासाठी, तुम्हाला हँडलरमध्ये या प्रकारचा व्यत्यय अक्षम करणे आवश्यक आहे किंवा ते दुसऱ्या स्तरावर पुन्हा कॉन्फिगर करणे आवश्यक आहे.

बाह्य धार व्यत्यय

वाढत्या काठावर एक व्यत्यय, किंवा, जसे ते म्हणतात, वाढता सिग्नल, जेव्हा INT इनपुटवरील सिग्नल पातळी 0 ते 1 पर्यंत बदलते तेव्हा उद्भवते. घसरत्या काठावर व्यत्यय येतो (पडणारा सिग्नल) जेव्हा सिग्नल पातळी INT इनपुट 1 ते 0 बदलते.
व्यत्यय कॉन्फिगर करणे देखील शक्य आहे जेणेकरून ते INT इनपुटवरील कोणत्याही बदलावर प्रतिक्रिया देईल, म्हणजे. हे दोन्ही अग्रभागी आणि मागच्या कडांवर होईल.

AVR मध्ये बाह्य व्यत्यय कॉन्फिगर करणे

मध्ये बाह्य व्यत्यय avr atmega8 बिट्स वापरून कॉन्फिगर केले ISCxx नोंदणी करा MCUCR .

avr atmega8 मध्ये MCUCR रजिस्टरच्या ISC0x बिटवर बाह्य व्यत्यय INT0 च्या ट्रिगरिंग स्थितीचे अवलंबन

बाह्य व्यत्यय साठी INT1 , सेटअप त्याच प्रकारे केले जाते, फक्त बिट वापरले जातात ISC11 ISC10 .

उदाहरणavr atmega8 साठी बाह्य व्यत्यय सेटिंग्ज:

//सर्व ISCxx बिट्स रीसेट करा MCUCR &= ~( (1 <<ISC11) | (1<<ISC10) | (1<< ISC01) | (1<< ISC00) ) MCUCR |= (1 << ISC01) | (1 << ISC00);

//सर्व बिट्स रीसेट करा ISCxx MCUCR &= ~((1<

avr atmega मध्ये बाह्य व्यत्यय सक्षम करा

बाह्य व्यत्यय कार्य करण्यासाठी, ते रजिस्टरमधील संबंधित बिट्स 1 वर सेट करून सक्षम केले पाहिजेत. जीआयसीआर .

बिट INT0 बाह्य व्यत्यय सक्षम/अक्षम करण्यासाठी जबाबदार INT0 , आणि बिट INT1 , अनुक्रमे, बाह्य व्यत्ययासाठी INT1 .

ग्लोबल इंटरप्ट सक्षम ध्वज सेट करणे देखील आवश्यक आहे.

avr atmega8 साठी बाह्य व्यत्यय INT0 सक्षम करण्यासाठी उदाहरण कोड:

//बाह्य व्यत्यय सक्षम करा INT0 GICR |= (1<

AVR atmega मध्ये बाह्य व्यत्यय वापरण्याचे उदाहरण

उदाहरण म्हणून, मी एक नाडी काउंटर प्रोग्राम देईन. प्रोग्राम INT0 इनपुटवर डाळींची संख्या मोजतो आणि सेकंदात एकदा uart मध्ये मोजणीचा परिणाम प्रदर्शित करतो.

#समाविष्ट करा #समाविष्ट करा #समाविष्ट करा #समाविष्ट करा //काउंटर व्हेरिएबलअस्थिर अस्वाक्षरित लांब int0_cnt = 0 ; //बाह्य व्यत्यय INT0 सेट करणे void int0_init( void ) ( // वाढत्या काठावर INT0 ट्रिगर करण्यासाठी सेट MCUCR |= (1 << ISC01) | (1 << ISC00); //बाह्य व्यत्यय INT0 सक्षम करा GICR |= (1 <<INT0); ) // फंक्शन बाह्य व्यत्यय हँडलर INT0 ISR( INT0_vect) ( int0_cnt++; ) //UART सेटअप void uart_init( void ) ( // विनिमय गती सेट करणे UBRRH = 0 ; UBRRL = 3 ; //115200 क्वार्ट्ज 7.3728 MHz वर //8 डेटा बिट, 1 स्टॉप बिट, समानता नाही UCSRC = ( 1 << URSEL ) | ( 1 << UCSZ1 ) | ( 1 << UCSZ0 ); //डेटा रिसेप्शन आणि ट्रान्समिशनला परवानगी द्या UCSRB = ( 1 << TXEN ) | ( 1 << RXEN ); ) // UART द्वारे बाइट हस्तांतरण int uart_putc( char c, FILE * file ) ( // मागील बाइटच्या प्रसारणाच्या समाप्तीची प्रतीक्षा करातर ( ( UCSRA आणि ( 1 << UDRE ) ) == 0 ); UDR = c; परतावा 0; ) FILE uart_stream = FDEV_SETUP_STREAM(uart_putc, NULL, _FDEV_SETUP_WRITE ); इंट मुख्य() ( // तात्पुरते व्हेरिएबलस्वाक्षरी न केलेले लांब tmp; stdout = & uart_stream; int0_init(); uart_init(); sei(); तर (१) ( // काउंटर मूल्य कॉपी केले जात असताना व्यत्यय अक्षम करा cli(); tmp = int0_cnt; // व्यत्यय सक्षम करा sei(); printf("int0_cnt = %lu \r\n", tmp ); //विराम 1 सेकंद _delay_ms( 1000 ); ) परतावा 0 ; )

#समाविष्ट करा #समाविष्ट करा #समाविष्ट करा #समाविष्ट करा //काउंटर व्हेरिएबल volatile unsigned long int0_cnt = 0; //बाह्य इंटरप्ट कॉन्फिगर करणे INT0 void int0_init(void) ( //वाढत्या काठावर MCUCR ट्रिगर करण्यासाठी INT0 कॉन्फिगर करणे |= (1<