1. Home
  2. Docs
  3. ESP-IDF / ESP32
  4. Giriş
  5. ESP-IDF ile GPIO Kullanımı ve Kesmeler (Interrupts)

ESP-IDF ile GPIO Kullanımı ve Kesmeler (Interrupts)

Print

ESP32 projelerinde harici sensörler, butonlar veya göstergelerle iletişim kurmanın en temel yolu Genel Amaçlı Giriş/Çıkış (GPIO) pinlerini yönetmektir. Bu yazıda modern ESP-IDF (v5.x) standartlarında gpio_config_t yapısını kullanarak çıkış pini sürmeyi ve butona basıldığında işlemciyi meşgul etmeden çalışan donanımsal kesme (ISR) mekanizmasını inceleyeceğiz.

1. GPIO Yapılandırma Yaklaşımı (gpio_config)

Eski yöntemlerde her pin için tek tek gpio_set_direction veya gpio_set_pull_mode çağrılırken, ESP-IDF’in önerdiği modern yaklaşım tüm parametreleri tek bir gpio_config_t struct yapısında toplayıp gpio_config() fonksiyonuna iletmektir.

  • pin_bit_mask: Yapılandırılacak pinlerin 64-bitlik bit maskesi.
  • mode: Pin yönü (GPIO_MODE_OUTPUT, GPIO_MODE_INPUT vb.).
  • pull_up_en / pull_down_en: Dahili pull-up veya pull-down dirençlerinin durumu.
  • intr_type: Kesme tetikleme türü (GPIO_INTR_NEGEDGE, GPIO_INTR_POSEDGE, GPIO_INTR_ANYEDGE).

2. Örnek Senaryo: Buton Kesmesi ile LED Kontrolü

Senaryomuzda GPIO 2 pinine bağlı dahili LED’i çıkış, GPIO 4 pinine bağlı butonu ise pull-up dirençli giriş olarak tanımlayacağız. Butona basıldığında (Düşen Kenar / Negative Edge) bir kesme tetiklenecek ve bu olay FreeRTOS kuyruğu (Queue) üzerinden ana göreve aktarılacaktır.

#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "driver/gpio.h"
#include "esp_log.h"

#define LED_PIN       GPIO_NUM_2
#define BUTTON_PIN    GPIO_NUM_4
#define ESP_INTR_FLAG_DEFAULT 0

static const char *TAG = "GPIO_INTR";
static QueueHandle_t gpio_evt_queue = NULL;

// Kesme Hizmet Rutini (ISR Handler)
// IRAM_ATTR: Fonksiyonun flash yerine hizli erisim icin dahili RAM'de tutulmasini saglar.
static void IRAM_ATTR gpio_isr_handler(void* arg) {
    uint32_t gpio_num = (uint32_t) arg;
    xQueueSendFromISR(gpio_evt_queue, &gpio_num, NULL);
}

// Buton olaylarini isleyen FreeRTOS gorevi
static void button_task(void* arg) {
    uint32_t io_num;
    static int led_state = 0;

    for (;;) {
        if (xQueueReceive(gpio_evt_queue, &io_num, portMAX_DELAY)) {
            led_state = !led_state;
            gpio_set_level(LED_PIN, led_state);
            ESP_LOGI(TAG, "Buton tetiklendi (GPIO %lu). LED durumu: %d", io_num, led_state);
        }
    }
}

void app_main(void) {
    // 1. Cikis Pini Yapilandirmasi (LED)
    gpio_config_t io_conf = {
        .pin_bit_mask = (1ULL << LED_PIN),
        .mode = GPIO_MODE_OUTPUT,
        .pull_up_en = GPIO_PULLUP_DISABLE,
        .pull_down_en = GPIO_PULLDOWN_DISABLE,
        .intr_type = GPIO_INTR_DISABLE
    };
    gpio_config(&io_conf);

    // 2. Giris Pini ve Kesme Yapilandirmasi (Buton)
    io_conf.pin_bit_mask = (1ULL << BUTTON_PIN);
    io_conf.mode = GPIO_MODE_INPUT;
    io_conf.pull_up_en = GPIO_PULLUP_ENABLE;
    io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
    io_conf.intr_type = GPIO_INTR_NEGEDGE; // Butona basildiginda tetiklenir (Active-Low)
    gpio_config(&io_conf);

    // 3. Kesme kuyrugunu olustur
    gpio_evt_queue = xQueueCreate(10, sizeof(uint32_t));

    // 4. Olayi dinleyecek FreeRTOS gorevini baslat
    xTaskCreate(button_task, "button_task", 2048, NULL, 10, NULL);

    // 5. ISR servisini kur ve pini bagla
    gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT);
    gpio_isr_handler_add(BUTTON_PIN, gpio_isr_handler, (void*) BUTTON_PIN);

    ESP_LOGI(TAG, "GPIO yapilandirmasi basariyla tamamlandi.");
}

3. Dikkat Edilmesi Gereken Noktalar

  • IRAM_ATTR Önemi: Kesme anında flash belleğe erişim kısıtlı olabileceği için ISR fonksiyonu RAM’de tutulmalıdır.
  • ISR İçinde Ağır İşlemlerden Kaçınma: ISR fonksiyonu içinde printf veya gecikme (vTaskDelay) kullanılmamalıdır; veriler daima FreeRTOS Queue veya EventGroup gibi yapılarla görevlere aktarılmalıdır.
  • Debounce (Buton Arkı): Mekanik butonlarda parazit sıçramalarını önlemek için donanımsal filtreleme (RC filtre) veya yazılımsal debounce süre sayacı eklenmesi önerilir.

Tags , , , ,

How can we help?