7. ünite / 11 · yaklaşık 4 saat
UART: seri iletişim ve komut satırı
Çerçeve (start, veri, parite, stop), baud ve BRR, saat hatası; kesmeyle satır okuma ve basit bir komut arayüzü.
Bu ünitenin sonunda
- UART çerçevesini bit bit çizmek ve 8N1'in ne demek olduğunu açıklamak
- Saat frekansından BRR değerini ve gerçek baud hatasını hesaplamak
- Çerçeve ve parite hatalarının nedenlerini ayırt etmek
- Kesmeyle bayt bayt okuyup satır tabanlı komut arayüzü kurmak
Ders notları
UART, saat hattı olmadan iki tel (TX, RX) ve ortak toprakla haberleşir. İki taraf da aynı hızı (baud) önceden bilir. Hat boşta 1'dir; her bayt bir start biti (0) ile başlar, LSB önce 8 veri biti gelir, isteğe bağlı bir parite biti ve bir ya da iki stop biti (1) ile biter. "8N1": 8 veri, parite yok, 1 stop; bir bayt 10 bit sürer.
BRR ve saat hatası
Alıcı start bitinin düşen kenarından sonra her bitin ortasında örnekler. STM32'de USARTDIV = fck / (16 × baud); tam kısım mantis, 16'da biri kesir olarak BRR'ye yazılır. 84 MHz ve 115200 için USARTDIV = 45,57 → 45 + 9/16, gerçek baud 115 226 (hata %0,02). İki ucun toplam hatası yaklaşık %2'yi aşarsa son bitler komşu bitin içinde örneklenir ve çerçeve bozulur.
Hatalar
- Çerçeve hatası (FE): stop biti 0 okundu. Neden: baud uyuşmazlığı ya da gürültü.
- Parite hatası (PE): 1'lerin sayısı pariteyle tutmadı.
- Taşma (ORE): yeni bayt geldi ama öncekini okumadın. Neden: yoklama ya da yavaş ISR.
Komut arayüzü
Nucleo'da USART2, ST-LINK'in sanal COM portuna bağlıdır: bilgisayarda bir seri terminal açıp kartla yazışabilirsin. Satır sonuna kadar baytları tampona topla, sonra satırı çözümle: PWM 40, DIR F, STATUS. Bitirme projesinin kullanıcı arayüzü budur.
Simülasyon
UART çerçeve görselleştirici ve BRR
Bir metin yaz: her karakter start biti, LSB önce 8 veri biti, isteğe bağlı parite ve stop bitine dönüşür. Baud, parite ve stop bitini değiştir, bir biti boz ve alıcının çerçeve (FE) ya da parite (PE) hatasını gör. BRR ve baud hatası hesaplanır.
Kendin dene
UART görselleştiricisine "OK" yaz ve ilk karakterin bitlerini LSB önce oku. Pariteyi çift yap: parite biti neden 0 ya da 1? Bir stop bitini bozup alıcının FE vermesini izle. BRR hesabında 16 MHz HSI ile 115200 ve 921600 baud'un hatasını karşılaştır. "Komut" sekmesinde PWM 40, START, DIR R ve STATUS komutlarını dene.
Wokwi'de
- Wokwi'de STM32 projesinde USART'ı Wokwi'nin seri monitörüne bağla ve "PWM 40" gibi komutlara satır satır yanıt veren döngüyü yaz.
- Baud'u iki uçta farklı ayarlayıp bozuk karakterleri gözlemle.
Kod
UART_HandleTypeDef huart2;
static uint8_t rx;
static char line[33];
static volatile uint8_t len = 0, ready = 0;
void uart_init(void) {
huart2.Instance = USART2;
huart2.Init.BaudRate = 115200; /* APB1 42 MHz → BRR = 22,8125 */
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.StopBits = UART_STOPBITS_1; /* 8N1 */
huart2.Init.Mode = UART_MODE_TX_RX;
HAL_UART_Init(&huart2);
HAL_UART_Receive_IT(&huart2, &rx, 1); /* her bayt için kesme */
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *h) {
if (rx == '\n' || rx == '\r') { if (len) { line[len] = 0; ready = 1; } }
else if (len < sizeof line - 1 && !ready) line[len++] = (char)rx;
HAL_UART_Receive_IT(h, &rx, 1); /* bir sonraki baytı yeniden iste */
}Sık yapılan hatalar
- TX'i TX'e bağlamak: TX karşı tarafın RX'ine gider.
- Ortak GND bağlamamak: sinyal seviyesi tanımsız kalır.
- 5 V USB-seri dönüştürücüyü 3,3 V pine bağlamak; çoğu STM32 pini 5 V toleranslıdır ama hepsi değil (veri sayfasında FT işaretine bak).
- HAL_UART_Receive'i engelleyici ve sonsuz zaman aşımıyla çağırmak: kart takılır.
Yazılım mühendisliği bağlantısı
Komut çözümleyiciyi donanımdan ayır: girdi bir metin, çıktı yeni durum ve yanıt.
- Bu saf fonksiyon bilgisayarda Unity testleriyle sınanır: aralık dışı değer, bilinmeyen komut, fazla uzun satır.
- Protokolü bir README tablosunda belgele (komut, argüman, yanıt, hata): sözleşme budur.
Kendini sına
8N1 çerçevesinde bir bayt kaç bit sürer?
'A' (0x41 = 0100 0001) gönderilirken start bitinden sonraki ilk veri biti?
Alıcı sürekli FE (çerçeve hatası) veriyorsa ilk şüphe?
84 MHz, 115200 baud için USARTDIV yaklaşık kaçtır?
Bu üniteden sonra bitirme projesinde
- UART komut arayüzü: Kesmeyle satır okuma ve command() çözümleyici; PlatformIO native ortamında Unity testleri.
