प्रारंभिक प्रश्न
माइक्रोकंट्रोलर में व्यवधानों से निपटने के बारे में मेरा एक सामान्य प्रश्न है। मैं MSP430 का उपयोग कर रहा हूं, लेकिन मुझे लगता है कि प्रश्न को अन्य यूसीएस तक बढ़ाया जा सकता है। मैं जानना चाहूंगा कि कोड के साथ-साथ बार-बार बाधित / अक्षम करने के लिए एक अच्छा अभ्यास है या नहीं। मेरा मतलब है, अगर मेरे पास कोड का एक हिस्सा है जो हस्तक्षेप करने के लिए संवेदनशील नहीं है (या इससे भी बदतर, किसी भी कारण से, बीच में नहीं सुनना चाहिए), क्या यह बेहतर है:
- पहले इंटरप्ट को अक्षम करें और फिर महत्वपूर्ण अनुभाग के बाद उन्हें फिर से सक्षम करें।
- संबंधित ISR के अंदर एक ध्वज लगाएं और (व्यवधान को निष्क्रिय करने के बजाय), ध्वज को महत्वपूर्ण खंड से पहले झूठे पर सेट करें और इसे सही पर रीसेट करें, बस के बाद। ISR के कोड को निष्पादित होने से रोकने के लिए।
- दोनों में से कोई भी, इसलिए सुझावों का स्वागत है!
अपडेट: इंटरप्ट और स्टेट चार्ट
मैं एक विशिष्ट स्थिति प्रदान करूंगा। आइए हम मान लें कि हम एक राज्य चार्ट को लागू करना चाहते हैं, जो 4 ब्लॉकों से बना है:
- संक्रमण / प्रभाव।
- शर्तों से बाहर निकलें।
- प्रवेश गतिविधि।
- गतिविधि करें।
यह वही है जो एक प्रोफेसर ने हमें विश्वविद्यालय में पढ़ाया था। संभवतः, इस योजना का पालन करने का सबसे अच्छा तरीका यह नहीं है:
while(true) {
/* Transitions/Effects */
//----------------------------------------------------------------------
next_state = current_state;
switch (current_state)
{
case STATE_A:
if(EVENT1) {next_state = STATE_C}
if(d == THRESHOLD) {next_state = STATE_D; a++}
break;
case STATE_B:
// transitions and effects
break;
(...)
}
/* Exit activity -> only performed if I leave the state for a new one */
//----------------------------------------------------------------------
if (next_state != current_state)
{
switch(current_state)
{
case STATE_A:
// Exit activity of STATE_A
break;
case STATE_B:
// Exit activity of STATE_B
break;
(...)
}
}
/* Entry activity -> only performed the 1st time I enter a state */
//----------------------------------------------------------------------
if (next_state != current_state)
{
switch(next_state)
{
case STATE_A:
// Entry activity of STATE_A
break;
case STATE_B:
// Entry activity of STATE_B
break;
(...)
}
}
current_state = next_state;
/* Do activity */
//----------------------------------------------------------------------
switch (current_state)
{
case STATE_A:
// Do activity of STATE_A
break;
case STATE_B:
// Do activity of STATE_B
break;
(...)
}
}
आइए हम यह भी मान लें कि STATE_A
मैं, बटन के एक सेट (डिबौस सिस्टम, आदि) के साथ आने वाली एक बाधा के प्रति संवेदनशील होना चाहता हूं। जब कोई इनमें से एक बटन दबाता है, तो एक अवरोध उत्पन्न होता है और इनपुट पोर्ट से संबंधित ध्वज को एक चर में कॉपी किया जाता है buttonPressed
। यदि बहस किसी तरह से 200 एमएस पर सेट है (वॉचडॉग टाइमर, टाइमर, काउंटर, ...) हमें यकीन है कि buttonPressed
200 एमएस से पहले एक नए मूल्य के साथ अपडेट नहीं किया जा सकता है। यह वही है जो मैं आपसे पूछ रहा हूं (और खुद :) निश्चित रूप से)
क्या मुझे STATE_A
छोड़ने से पहले डीओ गतिविधि को बाधित करने और अक्षम करने की आवश्यकता है?
/* Do activity */
//-------------------------------------
switch (current_state)
{
case STATE_A:
// Do activity of STATE_A
Enable_ButtonsInterrupt(); // and clear flags before it
// Do fancy stuff and ...
// ... wait until a button is pressed (e.g. LPM3 of the MSP430)
// Here I have my buttonPressed flag ready!
Disable_ButtonsInterrupt();
break;
case STATE_B:
// Do activity of STATE_B
break;
(...)
}
एक तरीका है कि मुझे यकीन है कि अगले चरण में अगली बार मैं execxute ब्लॉक 1 (संक्रमण / प्रभाव) मुझे यकीन है कि स्थिति बदलाव के साथ जाँच कर रहा हूँ बाद में एक बाधा के पिछले मूल्य होता है ओवरराइट से नहीं आ रहे हैं रहा हूँ में buttonPressed
है कि मैं जरूरत है (हालांकि यह असंभव है कि ऐसा होता है क्योंकि 250 एमएस को समाप्त होना चाहिए)।