Ana içeriğe geç
Elektronik & Mikrodenetleyici Orta Seviye

Mikrodenetleyici Programlama: I2C / SPI / UART Haberleşme

Hazırlayan: VoltGuard Mühendislik Ekibi · Son gözden geçirme:

Bu ders; ARM Cortex-M tabanlı mikrodenetleyicilerde (STM32, NXP) GPIO, kesme ve DMA kullanımını, UART, SPI ve I2C haberleşmesini kod örnekleri ve bir sıcaklık sensörü okuma uygulamasıyla anlatır.

Ön koşul ve ilgili kaynaklar: Elektronik ve Mikrodenetleyici Temelleri · ADC çözünürlük hesabı · Modbus RTU haberleşmesi neden kesiliyor?

Öne Çıkanlar

Mikrodenetleyici Mimarisi

Bir mikrodenetleyici; CPU çekirdeği (ARM Cortex-M), Flash, RAM, çevre birimleri (GPIO, timer, ADC, UART, SPI, I2C, CAN, USB) ve saat sistemini tek çip halinde barındırır. Endüstriyel gömülü sistemlerde en yaygın seri STM32'dir (STMicroelectronics). Örnek konfigürasyon: STM32F411, ARM Cortex-M4F, 100 MHz, 512 KB Flash, 128 KB RAM, 3 UART, 5 SPI, 3 I2C, 1 ADC, USB, timer. Endüstriyel cihazlarda UART çıkışı çoğunlukla bir RS-485 sürücüsüyle sahaya taşınır ve PLC ve SCADA otomasyon sistemlerinde Modbus RTU haberleşmesinin fiziksel temelini oluşturur.

GPIO Kontrolü: Register Tabanlı

LED'in PA5 pinine bağlı olduğunu düşünelim (STM32). Yapılan işlemler:

  1. Clock aktif: RCC → AHB1ENR → GPIOAEN = 1
  2. Pin modu: GPIOA → MODER[11:10] = 01 (output)
  3. Çıkış tipi: OTYPER[5] = 0 (push-pull)
  4. Hız: OSPEEDR[11:10] = 00 (low speed)
  5. Pull-up/down: PUPDR[11:10] = 00 (none)
  6. Çıkış: ODR[5] = 1 (LED yak), = 0 (söndür)

HAL kütüphanesiyle: HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);

Kesme (Interrupt) ile Buton

Buton PA0 ile GND arasına bağlı, PA0'da dahili pull-up açık olsun. Butona basıldığında pin 1'den 0'a düşer; bu nedenle kesme düşen kenarda tetiklenir:

// CubeMX ile PA0 = GPIO_EXTI0, Falling Edge, Pull-up
void EXTI0_IRQHandler(void) {
    HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
}

static volatile uint32_t last_ms = 0;

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
    if (GPIO_Pin == GPIO_PIN_0) {
        uint32_t now = HAL_GetTick();
        if (now - last_ms >= 30) {          // 30 ms içindeki sıçramaları yok say
            last_ms = now;
            HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
        }
    }
}
    

Mekanik buton kontağı sıçradığı için tek basış birkaç kesme üretebilir. Kesme rutininde bekleme (HAL_Delay) yapılmaz; yukarıdaki gibi zaman damgasıyla veya bir zamanlayıcıyla filtreleme yapılır. Donanımda RC filtre ve Schmitt tetikleyici de kullanılabilir.

UART: Seri Haberleşme

UART (Universal Asynchronous Receiver-Transmitter), iki cihaz arasında asenkron seri haberleşme sağlar. Tipik parametreler: 9600 bit/s, 8 veri biti, paritesiz, 1 stop biti (8N1). MCU pinlerindeki UART sinyali TTL/CMOS seviyesindedir (3,3 V veya 5 V) ve yalnızca kart içinde ya da çok kısa bağlantılarda kullanılır. Daha uzun mesafede bir sürücüyle başka bir fiziksel katmana çevrilir: RS-232'de sinyal seviyeleri ±3 V ile ±15 V arasındadır. RS-485'te ise diferansiyel sürücü çıkışı en az ±1,5 V'tur ve tek hat üzerinde çok sayıda cihaz bulunabilir.

HAL_UART_Transmit(&huart1, (uint8_t*)"Hello\r\n", 7, 100);

// DMA ile:
HAL_UART_Transmit_DMA(&huart1, buf, len);
    

SPI: Yüksek Hızlı Senkron

SPI (Serial Peripheral Interface), 4 hatlı (MOSI, MISO, SCLK, CS) senkron bir protokoldür. Aynı bus'ta birden fazla cihaz olabilir; her cihaz kendi CS (Chip Select) hattıyla seçilir. Hız, cihaza ve kart yerleşimine bağlı olarak onlarca MHz'e çıkabilir. Örnek uygulama: SPI Flash, OLED ekran, SD kart, ADC (MAX11040 gibi).

uint8_t tx[2] = {0x01, 0x02};
uint8_t rx[2];
HAL_GPIO_WritePin(CS_PORT, CS_PIN, GPIO_PIN_RESET);
HAL_SPI_TransmitReceive(&hspi1, tx, rx, 2, 100);
HAL_GPIO_WritePin(CS_PORT, CS_PIN, GPIO_PIN_SET);
    

I2C: Çoklu Cihaz Bus'ı

I2C (Inter-Integrated Circuit), yalnızca 2 hat (SDA, SCL) kullanan çok cihazlı bir bus'tır. Hız modları: Standard 100 kHz, Fast 400 kHz, Fast-mode Plus 1 MHz. Hatlar açık-drenajdır ve pull-up direnci gerektirir. Direnç değeri bus kapasitansına ve hıza göre seçilir; tipik aralık 2,2-10 kΩ'dur. 7 bit adresleme 128 adres verir; bunların bir kısmı ayrılmış olduğu için kullanılabilir adres sayısı yaklaşık 112'dir. Örnek uygulama: EEPROM (24LC256), sıcaklık sensörü (LM75, BMP280), IMU (MPU6050), RTC (DS3231).

// LM75 sıcaklık sensörü örneği
uint8_t reg = 0x00;  // Temp register
uint8_t data[2];
HAL_I2C_Master_Transmit(&hi2c1, 0x90, &reg, 1, 100);
HAL_I2C_Master_Receive(&hi2c1, 0x90, data, 2, 100);
int16_t raw = (int16_t)((data[0] << 8) | data[1]);  // işaretli 16 bit
raw >>= 5;                                           // 11 bit, 0,125 °C/bit (LM75B)
float celsius = raw * 0.125f;
    

UART / SPI / I2C Karşılaştırma

ProtokolTelHızMesafeCihazYaygın kullanım
UART2 (TX, RX) + GND9,6-921,6 kbit/sTTL: kart içi; RS-232: ~15 m; RS-485: 1200 m'ye kadar2 (nokta-nokta); RS-485 ile çok noktalıDebug, GPS, Modbus RTU
SPI4 + cihaz başına CS1-50 MHzKart içi (~30 cm)Her CS hattı bir cihazSPI Flash, SD, OLED, ADC
I2C2100 kHz-1 MHzKart içi; bus kapasitansı en fazla 400 pF~112 (7 bit adres)Sensör, EEPROM, RTC

DMA (Direct Memory Access)

DMA, çevre biriminden RAM'e (veya tersi) CPU müdahalesi olmadan blok halinde veri taşır. CPU sadece transfer başladığında ve bittiğinde meşgul olur; arada başka işleri yapabilir. Sürekli ADC örneklemesinde, UART ile değişken uzunlukta veri alırken ve SPI/I2C toplu transferlerinde özellikle yararlıdır.

Debug Araçları

Sıradaki Konu

Bu orta seviye dersi tamamladıktan sonra:

Bu içerik eğitim amaçlıdır. Gerçek ürün tasarımında; MCU seçimi, güvenlik, sertifika ve üretim testleri için yetkili mühendis çalışması gereklidir.

Gömülü sistem ve mikrodenetleyici projeleriniz için destek alınVoltGuard Ar-Ge ekibiyle iletişime geçin.
Hizmetlerimiz Teklif Al

← Tüm dersler: VoltGuard Akademi