İlk Soru
Mikrodenetleyicilerdeki kesintilerin ele alınması hakkında genel bir sorum var. MSP430 kullanıyorum, ancak sorunun diğer UC'lere genişletilebileceğini düşünüyorum. Kod boyunca sık sık kesintileri etkinleştirmek / devre dışı bırakmak için iyi bir uygulama olup olmadığını bilmek istiyorum. Yani, kesintilere karşı hassas olmayacak bir kod bölümüm varsa (veya daha da kötüsü, herhangi bir nedenle kesintileri dinlememelidir), daha iyi mi:
- Kesmeleri önce devre dışı bırakın ve ardından kritik bölümden sonra yeniden etkinleştirin.
- İlgili ISR'nin içine bir bayrak yerleştirin ve (kesmeyi devre dışı bırakmak yerine), kritik bölümden önce bayrağı false olarak ayarlayın ve hemen ardından sıfırlayın. ISR kodunun yürütülmesini önlemek için.
- Ne ikisi de, bu yüzden önerilerinizi bekliyoruz!
Güncelleme: Kesmeler ve Durum Grafikleri
Belirli bir durum sunacağım. 4 bloktan oluşan bir durum grafiği uygulamak istediğimizi varsayalım:
- Geçişler / Etkisi.
- Çıkış koşulları.
- Giriş etkinliği.
- Etkinlik yapın.
Bir profesörün bize üniversitede öğrettiği budur. Muhtemelen, bunu yapmanın en iyi yolu bu şemayı takip etmektir:
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;
(...)
}
}
Diyelim ki STATE_A
, bir dizi düğmeden gelen kesintiye karşı duyarlı olmak istediğimi varsayalım (debouce sistemi vb. İle). Birisi bu düğmelerden birine bastığında, bir kesme oluşturulur ve giriş bağlantı noktasıyla ilgili bayrak bir değişkene kopyalanır buttonPressed
. Geri dönme bir şekilde 200 ms'ye ayarlanmışsa (bekçi sayacı, zamanlayıcı, sayaç, ...), buttonPressed
200 ms'den önce yeni bir değerle güncellenemeyeceğinden eminiz . Sana sorduğum şey bu (ve kendimi :) tabii ki)
STATE_A
Ayrılmadan önce DO etkinliğinde kesintiyi etkinleştirmem ve devre dışı bırakmam gerekir mi?
/* 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;
(...)
}
Bir sonraki yinelemede blok 1'i (geçiş / efektler) bir daha yürüttüğümden emin olduğum bir şekilde, geçişler boyunca kontrol edilen koşulların, önceki değerinin üzerine yazılan bir sonraki kesmeden gelmediğinden buttonPressed
eminim. (250 ms geçmesi gerektiğinden bunun olması imkansız olsa da) gerekir.