uart-kapak

UART İletişim Protokolü ve MikroC Kütüphanesi

This post is also available in: English



UART Nedir

  • Veri haberleşme protokollerinden biri olan UART yani “evrensel asenkron veri iletişim” protokolünü inceleyeceğiz. Detaylı incelemeden sonra bu bilgiler ışığından ister kendi kütüphanenizi oluşturabilir yada benim MikroC için yazdığım UART kütüphanesini kullanabilirsiniz.

UART İletişim Protokolü

  • UART iletişim protokolü bir seri iletişim protokolüdür.
  • Diğer I2C veya SPI ile iki MCU yada Entegre birbiri ile haberleşirken UART ta farklı olarak MCU – PC ile yada PC – PC haberleşmesi sağlanır.
  • İnternet , ethernet  gibi tüm sistemler UART protokolü ile iletişim sağlar.
  • Aşağıda bu protokolün iyi ve kötü yanlarını tabloda inceleyelim
Olumlu Özellikler Olumsuz Özellikler
Sistem maliyetsizdir sadece 2 kablo ve GND ile bağlatı kurulur( kablosuz iletişimde GND olmaz) Yüksek hız istenmeyen uygulamalarda kullanılabilir
Sadece 1 alıcı ve 1 verici ile sistem çalışır Diğer seri iletişim protokolleri gibi aynı hat üzerine birden fazla ünite bağlanamaz. Herhangi bir şekilde master-slave ilişkisi yoktur iletişim ancak 2 ünite arasında gerçekleşir
Karmaşık değildir eşlik biti ile verileri hızlı olarak doğrular Haberleşme sağlayan alıcı ve verici aynı hızda haberleşmek zorundadır
RF verici -alıcı , ethernet , internet gibi sistemlerde ve PC – PIC yada PC – PC bağlantılarında kullanılır Büyük veri gönderimlerinde  zaman alır
 Gerekli tedbirler ile I2C veya SPI gibi seri iletişim protokollerinin aksine uzun mesafelerde kullanılabilir.  Seri iletişim protokolü olduğundan bütüm veri parçalanıp seri olarak gönderilmelidir.
 İletişim esnasında herhangi bir saat darbesine ihtiyaç yoktur.  Tek seferde veri gönderim boyutu en fazla 9 bit ile sınırlıdır

 

UART Protokolü Nasıl Çalışır

  • UART protokolünün nasıl çalıştığını inceleyeceğiz.
  • UART protokolünü 3 aşamaya ayırabiliriz
    • Veri gönderme
    • Veri alma
    • Hız hesap ve ayar

 

A-  UART Protokolü Veri Gönderme ve Alma (Tx – Rx)

  • Veri gönderilmeden önce belli bir kalıba göre şekillendirilmelidir.
  • Veri gönderme ve veriyi alma benzer şekillerde yapıldığından aynı başlık altına alındı
uart-protokolu-veri-kalibi
UART protokolünde uyulması gereken veri kalıbı
  • Veri kalıbı 4 parçadan oluşur. Bunlar ;
    • Başlangıç biti – 1 bit başlangıç biti, iletişimi başlatır hattı 1 den 0 a çeker
    • Veri – 8 bit ( değişken olabilir benim kütüphanemde 8 bittir) ana veri seri olarak gönderilir
    • Eşlik biti -1 bit eşlik biti duruma göre 0 yada 1 olur, verinin ulaştığı yerde hızlı olarak doğruluk kontrolü yapılmasını sağlar
    • Durdurma biti – 1 bit bitiş biti hattı 1 e çeker böylece iletişimin bittiği anlaşılır

 

A1 – Başlangıç Biti

uart-protokolu-baslangic-biti
UART protokolünde başlangıç biti gönderilmesi
  • Daima 0 ( sıfırdır) dır
  • Hat her zaman yüksekte tutulmalıdır aksi halde dalgalanmalar hatalı iletişim başlangıçlarına sebep olabilir.
  • Başlangıç biti aynı zamanda senkoronizasyon bitidir bu sebeple daima hattı 1 den 0 a çeker ve iletişimin aynı anda başlamasını sağlar
  • Veri okuma yapılırken hattın sıfıra çekilmesi beklenir sıfır olduğunda okuma başlar

 

A2 – Ana Veri

uart-protokolu-ana-veri
UART protokolünde veri gönderilmeye LSB den başlanır
  • Genel olarak 8 bit kullanılır.
  • Göndermek istediğimiz veri paralel halden seri hale çevirilerek gönderilir.
  • Veriler gönderilirken daima LSB den gönderilmeye başlanır.
  • Veri gönderim paketi bazı kütüphanelerde 7 veya 9 bit olabilir bunun için yardım dosyalarını inceleyin. Benim kütüphanemde kolaylık açısından 8 bit tercih edilmiştir.
  • Veri okunurken aynı şekilde ilk gelen veri en sona yazılarak anlamlı hale getirilir yani terse çevirilmiş veri eski haline gelir.

 

A3 – Eşlik Biti

uart-protokolu-eslik-biti
UART protokolünde eşlik biti hesaplama
  • Verilerin doğru aktarılıp aktarılmadığını denetler.
  • Genel olarak 1 yada 2 bit olarak seçilir ben kütüphanemde 1 bit olarak belirledim.
  • Eşlik biti hesaplaması aşağıdaki gibidir ;
    • Örnek veriyi ele alırsak verimizin binary hali “01000101” dir
    • Buna göre verimizde bulunan “1” leri topluyoruz ve toplamda 3 adet “1” bulunmakta
    • Sonuç tek sayı olduğu için eşlik biti “1” olur eğer sonuç çift sayı olsaydı eşlik biti “0” olacaktı.
    • Aslında bu binary sayıların kendi arasında XOR yapılması ile de elde edilebilir . Yöntem seçimi size kalmış
  • Veri okumada 9. bit eşlik biti saklanarak eşlik biti gelen veri için hesaplanır eğer hesaplanan ve gelen eşlik biti aynı ise veriler doğru aktarılmış demektir.

 

A4 – Bitiş Biti

uart-protokolu-bitis-biti
UART Protokolü bitiş biti gönderilmesi
  • Hattı 1 e çekerek iletişimin sonlandırıldığını bildirir.
  • 9. bitten sonra hat yükseğe çekilir ( yani boşta durumuna geri döner) böylece iletişimin bittiği anlaşılır

 

B-  UART Protokolünde Haberleşme için İstenilen Hız ve Gerekli Zamanı Hesaplamak

  • UART ta veri iletişim hızı bps ( bits per second) “saniye başına bit” olarak ölçülür
  • Örnek : 1700 bps hızla haberleşmek istiyorsak
    • 1/1700 = 5,88 gibi  bir değer elde ederiz
    • 5,88*100 = 588 us yani mikro saniye
    • Buna göre eğer biz 1700 bps hızda haberleşmek istiyorsak her bit arasında 588 us ( mikro saniye) bekleme yapılmalıdır.
  • Aşağıda belki lazım olabilecek bir hız dönüşüm hesaplama örneği bulunmaktadır
    • Haberleşme hızımızı 25000 bps olarak düşünelim bunun kaç kbps ettiğini bulalım
      • Öncelikle 25000 bps düz hesaplama ile 25 kbps eder diye düşünülebilir ancak bu yanlıştır. Çünkü önemli olan veri aktarımıdır biz 25000bps ile haberleşirken her blokta 8 bit veri ile beraber başlangıç -bitiş bitleri ve eşlik biti de göndermekteyiz.Bu tek başına veri aktarımı anlamına gelmez. O halde;
      • 1 başlangıç biti + 1 bitiş biti + 1 eşlik biti + 8 veri biti =11 bit eder
      • Biz 8 bit veri taşımayı hesaplayacağımızdan 8/11 = 0,72 eder
      • 25 kbps * 0,72 = 18 kbps yani bizim gerçekte veri taşıma hızımız 25 değil 18 kbps dir.Arta kalan zaman ise başlangıç-bitiş-eşlik biti aktarımı için harcanan zamandır.
    • 18 kbps kaç KB/s eder
      • 1 byte = 8 bit
      • 1 KB = 1.024 byte
      • 1 KB = 1024*8 = 8192 bit eder
      • 18.000 bps * (1KB/8192 bit) = 2,19 KB/s demektir
      • Yani hızımızı 18 kbps ye ayarladığımzda yapacağımız veri aktarımı aynı zamanda 2,19 KB/saniye ye eşit demektir.

 

UART Protokolü Sonuç

  • UART iletişim protokolü hakkında gereken teorik bilgiyi edindiniz.
  • Veri iletişimi nasıl olur nasıl başlar veri nasıl bir kalıba alınmalı bunları bildiğiniz için kendi fonksiyonlarınızı yazabilirsiniz yada konuya devam ederek benim mikroC de hazırladığım kütüphanemi inceleyerek kullanabilirsiniz.

 

UART Protokolü MikroC Kütüphanesi

  • MikroC içerisinde yazdığım kütüphane ile PIC donanımından bağımsız olarak UART protokolünü kullanabilirsiniz.
  • Çalışma 18 f serisi PIC ile denenmiştir.
  • Fonksiyonlar temel işlevleri yerine getirmektedir. Geriye kalan karmaşık yapıları kendiniz bu fonksiyonlar ile kurabilirsiniz
  • Fonksiyonlarda asla kesme ve zamanlama kullanılmaz bu sebeple bir kütüphane için ( mikroc nin standart kütüphanesinde olduğu gibi) zamanlama ve kesmelerden vazgeçmek zorunda kalmazsınız

Fonksiyonlar

  • Fonksiyonları parametreleri ile temel olarak gördükten sonra detaylı iki örnek ile anlatacağım
  • Fonksiyonların tamamı kullanıcı fonksiyonudur. Sadece eşlik biti hesaplayıcısının kullanılmasına gerek yoktur. Fonksiyon içerisinde kullanılmaktadır ancak kendi projelerinizde sadece eşlik biti hesabı içinde kullanabilirsiniz.
  • Kullanıcı fonksiyonları kullanıcı için yazılmış fonksiyonlardır sistem fonksiyonları ise sistem içerisinde kullanılır dolayısı ile sistem fonksiyonlarının çağırılması çalışmada sorunlara yol açabilir.

 

UART_VERI_TAMPONU Genel Dizisi

  • Bu genel olduğundan programın herhangi bir yerinden çağırılabilir ve aynı isme ait dizi oluşturulamaz
  • Dizi fonksiyonlar arası iletişim için kullanıldı. Dizinin elemanlarının işlevi aşağıdaki gibidir
    • uart_veri_tamponu[11]={0,0,0,0,0,0,0,0,0,0,1}
    • 1. bit =”0″  UART başlangıcı için mutlaka “0” verisi gönderilir.
    • 2-9 bit = Gönderilecek veriyi taşıyan 8 bittir.
    • 10. bit = Eşlik bitidir verinin doğru gidip gitmediğini belirler
    • 11. bit =“1” UART bitişte mutlaka  “1” verisi gönderir.
  • NOT: Verileri okumak için sizin fazladan bir işlem yapmanıza gerek yotur. Okuma fonksiyonu gelen ham veriyi parçalar ve gerekli bilgi kısmını geri döndürür. Bu açıklama sadece bilgi amaçlıdır. İstenirse herhangi bir anda dizideki veriler okunabilir.

 

– UART_ESLIK_BIT_HESAPLAMA Fonksiyonu

Fonksiyon : unsigned char UART_ESLIK_BIT_HESAPLAMA(unsigned char VERI)

Amacı :

  • 8 bitlik veri için gerekli olan eşlik bitini hesaplar.
  • Bu fonksiyon hem veri gönderirken hemde veriyi aldığımızda kontrol amacı ile kullanılır

Parametreler :

  • VERI : Eşlik biti hesaplanması istenen 8 bitlik veri yazılır

Kullanım Şekli:

UART_ESLIK_BIT_HESAPLAMA(VERI);//değişken yada direk veri yazılabilir

Geri Bildirim : Gerekli eşlik bitini geri döndürür

 

UART_GONDERILECEK_VERI_AYIKLAMA Fonksiyonu

Fonksiyon: void UART_GONDERILECEK_VERI_AYIKLAMA(unsigned char VERI)

Amacı : Ana veriyi gönderilmeden önce parçalara ayırarak “uart_veri_tamponu” na yükler

Parametreler: 

  • VERI : Ayıklanacak veri buraya yüklenir 8 bittir.

Kullanım Şekli :

UART_GONDERILECEK_VERI_AYIKLAMA(VERI);

Geri Bildirim :

  • Geri bildirimde bulunmaz.
  • Sistem fonksiyonudur

 

– UART_VERI_GONDER Fonksiyonu

Fonksiyon :  void UART_VERI_GONDER(unsigned char VERI)

Amacı : 8 bitlik veriyi alıcıya gönderir ( eşlik bitini kendi içerisinde hesaplar ayrıca hesaplamaya gerek yoktur)

Parametreler :

  • VERI : Gönderilecek 8 bit veriyi taşır

Kullanım Şekli :

bilgi=0b00001111;

UART_VERI_GONDER(bilgi) ; // bilgi değişkenine atalı 8 bit veriyi gönderir

Geri Bildirim : Geri bildirimde bulunmaz

 

UART_AYIKLANMIS_VERIYI_BIRLESTIR Fonksiyonu

Fonksiyon: unsigned char UART_AYIKLANMIS_VERIYI_BIRLESTIR(unsigned char *veri_hatasi)

Amaıc: Parçalanmış olarak gelen veriyi bir bütün haline getirip anlamlı bilgiyi taşıyan 8 biti içerisinden alır.

Parametreler:

  • *veri_hatasi : Eşlik biti kontrolü bu pointerin değeri okunarak elde edilir eğer pointer
    • 1 ise hata var demektir
    • 0 ise hata yok demektir
    • Bu fonksiyon değeri olarak geri dönmez direkt olarak pointerin değeri okunmalıdır

Kullanım Şekli:

unsigned char hata_kodu;

UART_AYIKLANMIS_VERIYI_BIRLESTIR(&hata_kodu);//hata kodu değişkenine pointerin aldığı değer atanır

Geri Bildirim:

  • Fonksiyon geriye anlamlı veriyi döndürür
  • Veri aktarım hatası olup olmadığının anlaşılması için mutlaka *veri_hatasi pointeri okunması gereklidir
    • 1 ise hata var demektir
    • 0 ise hata yok demektir
  • Sistem fonksiyonudur

 

– UART_VERI_AL Fonksiyonu

Fonksiyon : unsigned char UART_VERI_AL(unsigned char *hata_kodu)

Amacı : Vericiden gelen 8 bitlik veriyi alır ve kontrol eder

Parametreler :

  • *hata_kodu : Pointer dır eğer veri hatalı aktarılmışsa bu pointer 1 olur

Kullanım Şekli:

veri=UART_VERI_AL(hata,10000) ;//gelen bigli veri değişkenine atanır

Geri Bildirim :

  • Fonksiyon kendisi ile okunan veriyi gönderir
  • *hata_kodu pointeri ile hata olup olmadığı denetlenir. Veride hata varsa 1 olur bu halde okunan veri dikkate alınmamlıdır.

 

– İletişim Hızının Belirlenmesi

  • İletişim hızı donanımdan bağımsız olduğu için kütüphane içerisinde bulunan UART.h dosyasından ayarlanır
#define UART_ILETISIM_HIZI Delay_us(833);// (1/bps)*1000000 =xxxus
  • Yukarıdaki kodda Delay_us(833) ün içeriği veya tamamen kendiside değiştirilebilir buraya eklenen bekleme süresi iletişimdeki bekleme süresini belirleyecektir.
  • Süreyi hesaplama yukardaki derste ve kodların yanında paylaşılmıştır.
  • Buna göre (1/istenilen hız) *1000000 = bize bu hız için gerekli bekleme süresini verecektir.
  • Alıcı ve verici PIC ler mutlaka aynı hızda haberleşmelidirler.

 

Fonksiyonların Uygulanması

  • Uygulama kısmı alıcı ve verici kodları olarak 2 ye ayırılmıştır.

Verici Kod Örneği

 
//UART PIN TANIMLAMALARI
 sbit UART_RX at RC7_bit;
 sbit UART_TX at RC6_bit;
 sbit UART_RX_Direction at TRISC7_bit;
 sbit UART_TX_Direction at TRISC6_bit;*/

void  main()
{
    unsigned char veri;
    ADCON1=13;
    CMCON=7;

    veri=0b00001111;//8 bit ham verimiz

    UART_VERI_GONDER(veri) ; //veriler verici Pinden gönderilir  
}
  • Öncelikle UART ı kullanacağımız pinler tanımlanır.
  • Ardından gerekli veri  “UART_VERI_GONDER” fonksiyonu ile ister değişken isterse direk veri yazarak gönderilir.
  • Ayrıca eşlik biti hesaplamanıza gerek yoktur fonksiyon kendi içerisinde hesaplama yapmaktadır.

 

Alıcı Kod Örneği

//UART PIN TANIMLAMALARI
 sbit UART_RX at RB2_bit;
 sbit UART_TX at RB3_bit;
 sbit UART_RX_Direction at TRISB2_bit;
 sbit UART_TX_Direction at TRISB3_bit;


void  main()
{
    unsigned char veri =0 ,hata=0;
    ADCON1=13;
    CMCON=7;
   
   //Pinlere bir LED bağlandı ve başlarken söndürüldü
    trisb.rb1=0;
    portb.rb1=0;
  

 do{
     veri=UART_VERI_AL(&hata) ;//veri alma fonksiyonu-
   }while(koşul);
/*not:yukarıdaki döngü koşulu kullanıcıya bırakılmıştır istenirse kablolu iletişimde 0 başlangıç biti beklenebilir ancak kablosuz iletişimde
en az 8 bitlik ön doğrulama verisi kullanılması gerekir bu sebeple veri iletişimine başlama döngüsü buradan ayarlanmaktadır.*/

if(hata==0)//veri aktarımında hata yok ise-pointer okunur sıfır ise hata yok demektir.
  {  
    if(veri==0b00001111)
      {
        portb.rb1=1;// veri doğru gelmiş ise LED i yak
      }
  }
}
  • İlk olarak pin tanımlamarı yapılır
  • İstenilen verinin gelip gelmediğini anlamak için temsili olarak LED bağlanmış ve koşul ile doğru veri gelmesi halinde LED in yanması sağlanmıştır
  • Veriler  “UART_VERI_AL” fonksiyonu ile okunur.
  • Okuma için bekleme rutini do-while sistemi ile kurulur burada kullanılacak koşul kullanıcıya kalmıştır yani eğer kablolu bir sistem ise sadece başlangıç biti olan sıfır beklenebilir ancak kablosuz bir sistem ise en az 8 bitlik bir ön doğrulama kodu kullanılması gerekebilir bu sebeple bu koşul bu bölümde ayarlanmaktadır.

SONUÇ

  • UART protokolünün işleyişi hakkında bilgi sahibi oldunuz artık kendi fonksiyonlarınızı yazabilirsiniz yada benim mikroC kütüphanemi de kullanabilirsiniz
  • UART  özellikle RF vericilerde kullanılmaktadır bende öncelikle bu amaç ile bu protokolü yazmayı uygun gördüm .
  • PIC veya diğer MCU donanımlarında UART modülleri bulunabilir ancak her PIN de bu yoktur bu sebeple bu kütüphane UART donanımından ayrı olarak istenilen pin üzerinden kullanılabilir.
  • Sorularınızı foruma sorabilirsiniz.

Kütüphane Dosyaları

 


Yararlanılan Belgeler


 

ERCAN KOÇLAR Hakkında

Çalışmalarım çocukken başladı kolonyalı kağıtları yakmak, ilaçları birbirine katmak gibi değişik deneylerim vardı. Kimya kitabında elektroliz ile suyun hidrojen ve oksijene ayrıldığı ve hidrojenin yandığını yazıyordu, o zamanlarda aklım almıyordu sudan nasıl yanan....Devamını okumak için tıklayınız ;)