December 5, 2021

Blogna Kang U-2 Man

STM32, Embedded System, Microcontroller, ARM Cortex-M, RTOS, FreeRTOS

Blue Pill + STM32CubeIDE: GPIO Sebagai Interupsi

7 min read

بِسْمِ اللَّهِ الرَّحْمَنِ الرَّحِيم

Pada tutorial sebelumnya telah dijelaskan bagaimana memfungsikan GPIO sebagai port input untuk membaca saklar. Di tutorial kali ini akan dijelaskan bagaimana memfungsikan GPIO sebagai sumber interupsi eksternal. GPIO ini kemudian digunakan juga untuk membaca saklar. Pin yang digunakan masih sama yaitu PB9.

GPIO EXT9

Semua GPIO STM32 bisa diprogram sebagai sumber interupsi eksternal. Cuma ada 1 hal yang perlu diperhatikan. Layanan interupsi (ISR) ditentukan berdasarkan no pin, artinya PA1 dan PB1 akan mempunyai ISR yang sama, walaupun beda port. Ketika PA1 di-set sebagai pin interupsi, maka PB1 tidak bisa dijadikan sebagai pin interupsi. Oleh karena itu berhati-hatilah ketika merancang sistem dengan banyak menggunakan interupsi dari GPIO. Selalu pilih nomor pin yang berbeda.

Sebuah GPIO yang difungsikan sebagai interupsi, bisa diatur untuk membangkitkan interupsi saat ada transisi dari logika LOW ke HIGH (rising edge) atau saat logika HIGH ke LOW (falling edge) atau bahkan kedua kondisi tersebut (saat falling atau rising). Untuk pembacaan saklar digunakan kondisi falling, karena saat saklar tidak ditekan, kondisi logikanya akan HIGH. Sebenarnya bisa juga diatur untuk kondisi rising, hanya saja interupsinya akan dipicu ketika saklar dilepas. Di pengaturan juga pull-up digunakan karena tidak ada pull up eksternal.

Pengaturan Mode Interupsi

Interupsinya sendiri diaktifkan di tab NVIC (Nested Vectored Interrupt Controller).

Enable Interrupt

Di gambar terlihat EXT line [9:5] Interrupt. Ini artinya interupsi untuk pin 5-9 mempunya kendali pengaktifan yang sama. Setiap STM32 akan mempunyai port dengan jumlah pin maksimal 16 (pin 0 – pin 15). Dan semuanya bisa dijadikan interupsi, dengan ketentuan seperti yang telah dijelaskan di atas. Namun STM32 tidak semua pin akan mempunya ISR masing-masing, hanya pin 0 – pin 4 yang mempunyai ISR tersendiri, pin 5-9 digabung jadi 1 ISR, dan 10-15 juga digabung dalam satu ISR. Berikut nama-nama ISR handler seperti yang ada di file startup.

Ketika pin yang tergabung dalam satu ISR diaktifkan interupsinya, misal pin 9 dan pin 8, maka ketika terjadi interupsi harus dicek dulu, pin mana yang sebenarnya membangkitkan interupsi. Karena pastinya setiap pin akan mempunyai fungsi yang berbeda.

Prioritas Interupsi

Setelah diaktifkan, satu hal lagi yang perlu diatur yaitu prioritas interupsi, walaupun dalam tutorial ini, di-set di nilai default yaitu nol. Prosesor ARM Cortex-M3 mempunyai kendali interupsi yang dinamakan dengan NVIC. NVIC merupakan bagian dari core Cortex-M3, artinya semua prosesor Cortex-M3 akan mempunyai NVIC yang sama, walaupun beda pabrik pembuat. NVIC ini bisa menangani sampai 256 sumber interupsi, 240 di antaranya adalah sumber interupsi eksternal. Maksud eksternal di sini adalah di luar core CPU Cortex-M3, dalam hal ini GPIO dan periperal internal. Internal CPU sendiri bisa membangkitkan interupsi/eksepsi, yang bisa berasal dari Hard fault, Memory Management Fault, bus fault atau Usage Fault. Hard fault secara default akan selalu diaktifkan, karena bisa melayani semua eksepsi internal, artinya ketika misal terjadi bus fault, tetapi eksepsi bus fault tidak diaktifkan, maka hard fault yang akan melayani.

Struktur Interupsi Cortex-M3

Tidak semua dari 240 interupsi digunakan, hal ini tergantung kepada pabrik yang memproduksi mikrokontroler. ARM Company yang merancang prosesor ARM Cortex-M3 tidak memproduksi silikon chip, dia hanya menjual lisensi dari arsitektur yang dikembangkannya ke pabrikan semikonduktor, seperti ST, TI, NXP dan lain-lain. Pabrikan semikonduktor inilah yang kemudian menambahkan fitur-fitur tambahan (periperal) kepada CPU sesuai dengan target pasar mereka. Termasuk berapa interupsi eksternal yang diaktifkan.

Tabel Vektor Interupsi

Interupsi sebenarnya bekerja dengan cara polling juga, hanya saja pollingnya dilakukan secara hardware. Urutan polling berdasarkan nomor interupsi (IRQ Number). Polling dimulai dari nomor interupsi yang terkecil. Di prosesor ARM Cortex, interupsi yang berasal dari CPU diberi nomor negatif, sedangkan yang dari luar CPU dimulai dari angka nol. Ketika terjadi interupsi yang bersamaan, misal IRQ0 dengan IRQ1, maka CPU akan melayani IRQ0 terlebih dahulu baru kemudian IRQ 1. Apakah hal ini bisa diubah? Bisa, yaitu dengan mengubah level prioritas interupsinya. Level prioritas rendah akan mempunyai prioritas lebih tinggi.

ARM Cortex-M3 mempunya level prioritas sampai 256 (8 bit), kecuali NMI, Reset, dan Hard fault yang hanya mempunyai 3 level prioritas. Bandingkan dengan mikrokontroler keluarga 8051 yang hanya mempunyai 2 level prioritas (1 bit). Walaupun demikian setiap pabrik silikon yang memproduksi prosesor ARM Cortex-M3 akan menerapkan prioriotas interupsi yang berbeda-beda. Bisa menerapkan 8 level prioritas (3 bit), 16, 32 dan seterusnya. Level minimal adalah 8 level prioritas (3 bit). Lebih banyak level prioritas interupsi yang diterapkan, maka lebih banyak jumlah gerbang-gerbang digital yang harus dibuat di dalam core ARM Cortex-M3, artinya akan lebih banyak mengkonsumsi daya. Selain itu juga, akan berdampak ke harga jual prosesor.

Lalu apa yang dimaksud dengan Nested Vectored Interrupt? Nested artinya bersarang,, artinya sebuah interupsi bisa dilayani walaupun saat itu CPU sedang melayani sebuah interupsi, asalkan interupsi yang baru mempunyai prioritas interupsi lebih tinggi (level interupsinya lebih rendah). Di Cortex-M3, level prioritas interupsi dibagi menjadi 2 bagian, yaitu level prioritas preempt  dan level subpriority. Level prioritas preempt menentukan apakah sebuah interupsi bisa mendahului atau menunda interupsi yang sekarang sedang dikerjakan oleh prosesor (interupsi bersarang), di mana level prioritas preempt yang lebih kecil akan mempunya nilai prioritas yang lebih besar. Sedangkan level subprioritas digunakan ketika ada 2 interupsi dengan level prioritas preempt yang sama terjadi secara bersamaan di mana interupsi dengan nilai sub-prioritas yang lebih kecil akan didahulukan.

Secara sederhana aturan prioritas ARM Cortex-M3 adalah sebagai berikut:

  1. Ketika terjadi sebuah interupsi atau eksepsi, maka level prioritas preempt dari interupsi tersebut akan dibandingkan dengan prioritas preempt dari interupsi yang sedang dieksekusi, jika prioritasnya lebih tinggi, interupsi yang sedang dieksekusi akan ditunda dan prosesor akan melayani interupsi yang baru. Jika prioritasnya lebih rendah, interupsi yang baru tersebut akan ditunda.
  2. Jika terjadi 2 atau lebih interupsi dengan level preempt yang sama, maka prosesor akan melihat level sub-prioritas. Interupsi dengan level sub-prioritas lebih tinggi (nilai sub-prioritas lebih rendah) akan didahulukan.
  3. Jika level sub-prioritasnya sama, maka prosesor akan melihat nomor eksepsi/interupsi tersebut, nomor eksepsi lebih rendah akan didahulukan. IRQ0 akan mempunyai prioritas lebih tinggi dari IRQ1.

Kembali ke tutorial.

Tutorial ini akan mempunyai fungsi yang sama dengan contoh tutorial pembacaan saklar. Hanya saja saklar tidak di-polling, tetapi akan membangkitkan interupsi saat ditekan. Saat interupsi terjadi akibat ada penekanan saklar, program akan menjalankan fungsi ISR (EXfTI9_5_IRQHandler()), terdapat di file stm32f1xx_it.c. Fungsi ini kemudian memanggil fungsi HAL_GPIO_EXTI_IRQHandler() di file stm32f1xx_hal_gpio.c.

Fungsi IRQHandler akan meng-clear bit status interupsi yang bersangkutan kemudian akan memanggil fungsi callback (HAL_GPIO_EXTI_Callback()). Fungsi callback ini diberi atribut __weak. Artinya fungsi ini akan di-override jika ada fungsi dengan nama yang sama tetapi tanpa atribut. Ketika proses kompilasi, ketika program memanggil sebuah fungsi, maka compiler akan mencari fungsi tersebut, jika tidak ketemu maka compiler akan mencari nama fungsi yang sama dengan atribut __weak, jika tidak ketemu juga, compiler akan memberikan pesan error. Dalam contoh tutorial ini, fungsi callback hanya akan memberikan sebuah status, bahwa interupsi telah terjadi.

Sebenarnya bisa juga langsung dilakukan di fungsi layanan interupsi, namun variabel int_state harus dideklarasikan sebagai extern,agar bisa dipanggil oleh file stm32f1xx_it.c

Fungsi main akan mempolling variabel ini, dan jika di-set artinya ada penekanan saklar. Program selanjutnya hampir sama dengan program pembacaan secara polling. Sebuah pin GPIO yang telah diprogram sebagai interupsi, tetap masih bisa dibaca status logikanya.

Perhatikan bahwa, semua fungsi yang melayani interupsi GPIO, selalu mempunyai parameter GPIO_Pin. Ini seperti yang telah disebutkan di atas, ada pin GPIO yang mempunyai fungsi layanan interupsi yang sama. Selain itu di dalam struktur program STM32CubeMX, semua interupsi GPIO akan memanggil fungsi IRQ Handler dan callback yang sama, walaupun fungsi layanan interupsinya berbeda. Misalkan ketika pin 9 dan pin 8 dijadikan interupsi, maka di fungsi layanan atau callback interupsi harus dicek, pin mana yang sebenarnya membangkitkan interupsi.

Semoga bermanfaat…

Visits: 8 Visits: 98015

Leave a Reply

Your email address will not be published. Required fields are marked *

Copyright © All rights reserved. | Newsphere by AF themes.