Pertanyaan awal
Saya punya pertanyaan umum tentang penanganan interupsi dalam mikrokontroler. Saya menggunakan MSP430, tapi saya pikir pertanyaannya dapat diperluas ke UC lainnya. Saya ingin tahu apakah praktik yang baik untuk mengaktifkan / menonaktifkan interupsi sering sepanjang kode. Maksud saya, jika saya memiliki bagian kode yang tidak akan sensitif terhadap interupsi (atau lebih buruk lagi, tidak boleh mendengarkan interupsi, karena alasan apa pun), apakah lebih baik untuk:
- Nonaktifkan interupsi sebelum dan kemudian aktifkan kembali setelah bagian kritis.
- Letakkan bendera di dalam ISR masing-masing dan (alih-alih menonaktifkan interupsi), atur bendera ke false sebelum bagian kritis dan atur ulang menjadi true, setelahnya. Untuk mencegah kode ISR dieksekusi.
- Tak satu pun dari keduanya, jadi saran dipersilahkan!
Pembaruan: menyela dan grafik negara
Saya akan memberikan situasi tertentu. Mari kita asumsikan kita ingin mengimplementasikan bagan negara, yang terdiri dari 4 blok:
- Transisi / Efek.
- Kondisi keluar.
- Aktivitas masuk.
- Lakukan aktivitas.
Inilah yang diajarkan seorang profesor kepada kita di universitas. Mungkin, bukan cara terbaik untuk melakukannya adalah dengan mengikuti skema ini:
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;
(...)
}
}
Mari kita juga berasumsi bahwa dari, katakanlah STATE_A
, saya ingin peka terhadap gangguan yang datang dari serangkaian tombol (dengan sistem debouce, dll.). Ketika seseorang menekan salah satu tombol ini, interupsi dibuat dan bendera yang terkait dengan port input disalin ke dalam variabel buttonPressed
. Jika debounce diatur ke 200 ms dalam beberapa cara (pengawas waktu, pengatur waktu, penghitung, ...) kami yakin bahwabuttonPressed
tidak dapat diperbarui dengan nilai baru sebelum 200 ms. Inilah yang saya tanyakan kepada Anda (dan saya sendiri :) tentu saja)
Apakah saya perlu mengaktifkan interupsi dalam aktivitas DO STATE_A
dan menonaktifkan sebelum pergi?
/* 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;
(...)
}
Dengan cara yang saya yakin bahwa waktu berikutnya saya mengeksekusi blok 1 (transisi / efek) pada iterasi berikutnya saya yakin bahwa kondisi yang diperiksa sepanjang transisi tidak datang dari interupsi berikutnya yang telah menimpa nilai sebelumnya dari buttonPressed
yang saya perlu (walaupun tidak mungkin hal ini terjadi karena 250 ms harus berlalu).