STM32 HAL Kütüphanesi ile UART Birimini Kullanma

UM1786 adlı kütüphane kılavuzunu açıp içindekilere baktığımızda HAL kütüphanesinde UART ve USART sürücüsü olmak üzere iki ayrı sürücü olduğunu görüyoruz. Datasheet okurken tek bir birim olarak USART bahsedilse de bu birimi UART ya da USART olarak kullanmak bize bağlıdır. UART sürücüsünde evrensel asenkron iletişime dair fonksiyonlar bulunmaktadır. Senkron iletişimle alakalı fonksiyonlar ise USART sürücüsünde görülmektedir.

Biz USART konusunu atlayacağımız için USART sürücüsüne bakmayacağız. Yine de böyle bir sürücü olduğunu bilmeniz gerekir. Bunu tembellikten dolayı değil senkron iletişimin pratikte pek kullanılmamasından dolayı yapıyoruz. Şimdi UART sürücü sayfasını kılavuzdan açıp inceleyelim.

Öncelikle kafamızın karışmaması açısından sürücüler senkron ve asenkron yani UART ve USART olarak ikiye ayrıldığı gibi yapı tiplerinin tanımlamasında da UART_InitTypeDef ve UART_AdvFeatureInitTypeDef olmak üzere ikiye ayrılmıştır. Bunların adından birinin karmaşık özellikler için ayrıldığını anlayabiliriz. Bizim şu an yapmak istediğimiz en basit işlemleri yapmak olduğundan şimdilik çok fazla ayrıntıya girmeyeceğiz.

“How to use this driver” başlığını her zaman olduğu gibi önceden okuyalım. Burada sürücünün nasıl kullanılacağına dair talimatlar yer almaktadır. Şimdi bu talimatlara göz atalım.

İlk öncelikle UART_HandleTypeDef tipinde bir ele alma yapısı tanımlanmalıdır. (UART_HandleTypeDef uart gibi)

Sonrasında HAL_UART_MspInit() fonksiyonu ile ön tanımlama işlemi yapılmalıdır.  Burada şu ayarlar göz önünde bulundurulur,

USARTx arayüz saati etkinleştirilir.

UART Ayak Ayarlaması Yapılır. Bunun için UART biriminin RX ve TX ayaklarının denk geldiği GPIO portlarının saati etkinleştirilir ve ayaklar alternatif fonksiyonda pull-up olarak tanımlanır. Bu GPIO sürücüsü kullanılarak yapılmalıdır.

Eğer UART kullanırken kesmeleri kullanacaksak NVIC ayarlamaları yapılır. Bu kesme tabanlı fonksiyonlar HAL_UART_Transmit_IT() ve HAL_UART_Recieve_IT() fonksiyonlarıdır. Bunlar için USARTx kesme öncelik ayarı ve NVIC USART IRQ ele alıcısı etkinleştirilir.
Özel UART fonksiyonları __HAL_UART_ENABLE_IT() makrosu ile etkinleştirlir ve __HAL_UART_DISABLE_IT() makrosu ile devre dışı bırakılır.

Eğer DMA kullanacaksak ona özel ayarlamalar yapılmalıdır. DMA özelliğini HAL_UART_Transmit_DMA() ve HAL_UART_Recieve_DMA() fonksiyonları kullanmaktadır. Bunun için öncelikle DMA ele alma yapısını TX ve RX kanalları için tanımlamalı, DMAx arayüz saatini etkinleştirmeli, tanımlanan DMA ele alma yapısını ayarlamalı, DMA ele alma yapısını UART DMA TX/RX ele alma yapısıyla birleştirmelidir. DMA konusuna çok daha sonra geleceğimiz için DMA’yı anlatmadan uygulama yapmayacağız.

Kesme ve DMA kısmını normal program akışında yapacağımız UART işlemi için görmezden gelebiliriz. Fakat USART birimini kullanırken kesmelerden yardım almamız çok işimize yarayacaktır. Çünkü UART veri alış verişinin ne zaman gerçekleşeceğini kestirmek güçtür. Normal program akışında (polling) verinin gelip gelmediğini öğrenmek için sürekli karar yapılarıyla denetlememiz gerekebilir. Kesmeler tam bu anda bize yardımcı olmaktadır. O yüzden profesyonel bir program işlemci yükünü asgari seviyeye indirmeyi esas alır. Profesyonel bir programcı da kesmeleri bol bol kullanmaktadır.

Bir sonraki aşamada ise baud oranı, gönderilecek verinin uzunluğu, stop biti, eşlik ve donanım akışı denetimi ve modu belirlenir. Bu init yapısı içerisinde belirlenmelidir.

Eğer gerekirse UART’ın gelişmiş fonksiyonlarını AdvancedInit yapısı içerisinde tanımlayabilirsiniz.

Bütün bu tanım ve ayarlamalardan sonra UART’ı kullanmak ve bu verileri UART yazmaçlarına yazmak için HAL_UART_Init() fonksiyonu kullanılır. Eğer tekli modda kullanacaksak HAL_HalfDuplex_Init() fonksiyonu kullanılır.

Şimdi bu yazdıklarımızı tekrar bir gözden geçirirsek UART birimini tanımlamanın oldukça kolay olduğunu görüyoruz. HAL kütüphanesi belli bir standartta olduğundan kısa sürede öğrenebiliyoruz. Burada da yapmamız gereken önce tanımlamak için bir yapı tipi tanımlamak ve sonrasında parametreleri girdikten sonra tanımlama fonksiyonu ile değerleri yazmaçlara yazdırmaktır. Bunu uygulamalı olarak yaptığımızda öteki sürücüleri kullanmaktan pek farkının olmadığını göreceksiniz.

HAL kütüphanesinde önce birim için tanımlama ve ayarlar yapılır, parametreler girilir ve hazır hale getirilir. Sonrasında kullanmak için ise ayrı fonksiyonlar mevcuttur. Bu fonksiyonlar yine üç ayrı modda kullanılmaktadır. Bunlar normal program akışı, kesme ve DMA modlarıdır.

Normal program akışında sadece iki fonksiyon ile UART iletişimi kullanabiliriz. Veri göndermek için HAL_UART_Transmit(), veri almak için de HAL_UART_Recieve() fonksiyonlarını kullanırız. Eğer CubeMX programı ile ön ayarlamaları yaptıysak kullanmamız gereken iki fonksiyon olduğunu görebiliriz. Bir sonraki makalemizde CubeMX ile bu ayarlamaları yapalım ve üretilen kodu görelim.

Bizi Facebook grubumuzda takip etmeyi unutmayın. Bilgili ve öğrenmeye hevesli bir topluluk oluşturmak istiyoruz.

https://www.facebook.com/groups/1233336523490761/

UYARI!!

Gökhan Dökmetaş

"Arduino Eğitim Kitabı" ve "Arduino ve Raspberry PI ile Nesnelerin İnterneti" kitaplarının yazarı. Başkent Teknoloji ve Dedektör Merkezi'nde Ar-ge Sorumlusu. Araştırmacı-Yazar.

You may also like...

Bir cevap yazın

E-posta hesabınız yayımlanmayacak.