C18 Diliyle Robot Programlama – RS232 Seri Haberleşme (USART)

Bu yazıda amaç bilgisayar ile deneme kartımızı seri şekilde haberleştirmek olacak. Bilgisayarlarla haberleşmek için seri iletişim, paralel iletişim gibi yöntemler vardır. Paralel iletişimde her bir bilgi için bir data hattı vardır, tüm bilgiler aynı anda bu veri yollarından gönderilir. Bu nedenle paralel iletişim seri iletişime göre daha hızlıdır fakat mesafe uzayınca çok maliyetli olmaktadır.

Seri haberleşmede bilgiler tek bir hat üzerinden gönderilip alınır. Hızı paralel iletişime göre yavaş fakat daha ucuzdur. Senkron ve Asenkron olmak üzere 2 adet seri haberleşme yöntemi vardır.

Senkron seri iletişimde gönderilen ve alınan veriler aynı anda aktarılır, yani verici ve alıcı taraf eşzamanlı çalışır. Bu eşzamanlılığı sağlamak için iki devre arasında bir clock sinyali hattı bulunur. Bu nedenle asenkron iletişime göre daha hızlıdır. Asenkron seri iletişimde sadece veri hattı bulunur, alıcı ve verici taraf farklı zamanlarda data gönderebilir.     Eşzamanlı olmadığı için iletilen her verinin başında ve sonunda start-stop bitleri bulunur. Ayrıca her veriyle beraber hata kontrolü için gönderilen parity biti vardır.

Seri iletişim hızı, saniyede gönderilen bit sayısıdır. (bps – bit per second) Bu orana seri iletişim hızını belirtmek için kullanılan baud oranı (baud rate) denir. Seri iletişim baud oranları 110, 150, 300, 600, 1200, 2400, 4800, 9600, 19200 değerlerinde olabilir. Bilgisayarda asenkron seri iletişim için 9 ve 25 pinli  RS-232 C portları vardır. Biz bu    bölümde 9 pinli RS-232 portunu kullacağız. Bilgisayar ile kartı USB to RS-232(9 pin) Serial Adapter cihazıyla birbirine bağlayacağız. RS232 portunun erkek(male) ve dişi(female) pinleri aşağıdaki şekilde görülmektedir;

Kullanacağımız USB to RS-232(9 pin) Serial Adapter cihazı ise aşağıdaki gibidir;

Yardımcı kartın RS232 çıkışı ile bilgisayarın USB çıkışını birbirine bağladıktan sonra yazdığımız programı PicKit2 ile kart üzerndeki PIC18F4585 mikrodenetleyicisine yükleyeceğiz. Verilerin akışını ise bilgisayar üzerinden Cutecom adlı bir program aracılığıyla yapacağız. Programı kurması gayet basit. Herhangi bir paket yöneticisi kullanılarak indirilebilir. En kolay yolu Ubuntu Yazılım Merkezi‘ni veya ona muadil başka bir aracı yazılımı kullanmak. Arama kutusuna cutecom yazınca program çıkıyor zaten.

Programı, terminale cutecomyazarak veya Alt + F2 tuşlarına basıldığında çıkan Uygulama   Çalıştırpaneline cutecomyazarak çalıştırabilirsiniz. Programı kurduktan sonra birkaç ufak ayar yapmak gerekiyor.

  • İlk iş olarak USB to RS-232 cihazını bilgisayara bağladıktan sonra terminali açıp ls /dev/ttyU* komutunu giriyoruz ve bilgi olarak USB to RS-232 cihazının hangi USB girişine bağlı olduğu dönüyor. Daha sonra bu çıkışı cutecom arayüzünde device bölümüne /dev/ttyUSB0 formatında yazıyoruz.

  • Yine cutecom arayüzünde Hex output ve Hex input seçeneklerini seçiyoruz (Gönderdiğimiz ve aldığımız veriler Hexadecimal olacak). Data bitlerimiz 8 ve stop bitimiz 1 olacak, baud rate ise 9600 olarak seçilebilir.

Bu ayarlamaları yaptıktan sonra program kodunu yazmaya başlayabiliriz. Programda   yapacağımız şey RB0 pinine bağlı butonu kullanarak bilgisayara sayı göndermek ve bilgisayardan cutecom arayüzüyle karta gönderdiğimiz verileri okumak (Okuma işleminde kesme mekanizması kullanılacak çünkü bilgisayardan ne zaman veri gönderileceğini bilmiyoruz. Program da bütün zamanını bilgisayardan veri bekleyerek geçirmemeli).

RS-232 portu ile PIC18F4585 arasındaki bağlantının nasıl olması gerektiği hakkında bir bilgim yok, benim çalıştığım kart üzerinde yerleşik olarak 9 pinli bir RS-232 portu bulunuyor. Sadece programlama aşamasına değineceğim.

Programda bu bölüm için kullanacağımız fonksiyonlar;

  • OpenUSART(): USART modülünü kullanıma açar.
  • WriteUSART(): 1 byte’lık veri gönderir.
  • ReadUSART(): 1 byte’lık veri okur.
  • DataRdyUSART(): Data okunmaya müsait mi diye kontrol eder. 1 ile dönerse data alım için uygundur, 0 ile dönerse data alınacak durumda değildir.

Ayrıca programda aldığımız verileri gösterebilmek için RB3, RB4 ve RB5 pinlerine bağlı ledleri kullanacağımızdan dolayı alınan sayıları (0-7 arasında olmak zorunda) binary şekilde ledlerde gösteren show_on_leds() fonksiyonu bulunacak.

Program kodları aşağıdaki şekilde olacak;

<pre>/* 
 * File:   usart_main.c
 * Author: cagatay
 *
 * Created on 02 ?ubat 2012 Per?embe, 14:53
 */

#include <p18cxxx.h>
#include <stdio.h>
#include <delays.h>
#include <usart.h>

#pragma config OSC = HS, WDT = OFF, LVP = OFF

char data_rx=0;

void int_handler(void);

#pragma code high_vector=0x08
void high_interrupts (void) {
    _asm GOTO int_handler _endasm
}

#pragma code low_vector=0x18
void low_interrupts (void) {
    _asm GOTO int_handler _endasm
}

#pragma code
#pragma interrupt int_handler
void int_handler(void) {
    if(PIR1bits.RCIF == 1) {
        PIR1bits.RCIF = 0;
        while(!DataRdyUSART());

        data_rx = (char)ReadUSART();        
    }
}

void show_data_on_leds(char data) {

    if(data == 1) {
        PORTBbits.RB3 = 1;
        PORTBbits.RB4 = 0;
        PORTBbits.RB5 = 0;
    }

    if(data == 2) {
        PORTBbits.RB3 = 0;
        PORTBbits.RB4 = 1;
        PORTBbits.RB5 = 0;
    }

    if(data == 3) {
        PORTBbits.RB3 = 1;
        PORTBbits.RB4 = 1;
        PORTBbits.RB5 = 0;
    }

    if(data == 4) {
        PORTBbits.RB3 = 0;
        PORTBbits.RB4 = 0;
        PORTBbits.RB5 = 1;
    }

    if(data == 5) {
        PORTBbits.RB3 = 1;
        PORTBbits.RB4 = 0;
        PORTBbits.RB5 = 1;
    }

    if(data == 6) {
        PORTBbits.RB3 = 0;
        PORTBbits.RB4 = 1;
        PORTBbits.RB5 = 1;
    }

    if(data == 7) {
        PORTBbits.RB3 = 1;
        PORTBbits.RB4 = 1;
        PORTBbits.RB5 = 1;
    }

}

void main(void) {
    int data_tx = 0;

    ADCON1 = 0x0F;

    TRISB = 0x07;
    PORTB = 0;
    
    OpenUSART(USART_TX_INT_OFF &
              USART_RX_INT_ON &
              USART_ASYNCH_MODE &
              USART_EIGHT_BIT &
              USART_CONT_RX &
              USART_BRGH_HIGH,
              25 );

    INTCONbits.GIE = 1;
    INTCONbits.PEIE = 1;
    PIE1bits.RCIE = 1;
    
    while(1) {

        if(!PORTBbits.RB0) {
            while(!PORTBbits.RB0);
            
            WriteUSART(data_tx);
            while(!PIR1bits.TXIF);

            data_tx++;
        }

        if(data_rx>0 && data_rx<8)
            show_data_on_leds(data_rx);
        
        else if(data_rx != 0) {
            PORTB = 0x38;
            Delay10KTCYx(100);
            PORTB = 0;
        }

    }
}</pre>

Satır 15’de aldığımız veriyi saklayacağımız data_rx değişkenini tanımlıyoruz.

Satır 40′ da aldığımız sayıları (0-7 arasında) ledlerde göstermek için yazdığımız fonksiyon başlıyor. Burada gelen sayı sırayla 1’den 7’ye kadar eşit mi diye kontrol ediliyor. (Sıfırsa ledler yanmayacak)

Satır 87’de tanımladığımız data_tx değişkeni göndereceğimiz değişken. Bu değişkene göndermek istediğimiz değeri bu satırda atıyoruz. Bu değişkeni bilgisayara 111. Satırdaki WriteUSART() fonksiyonuyla gönderiyoruz.

Satır 89’da bütün ADC pinleri dijital olarak ayarlanıyor, satır 91 ve 92 de B portu RB0 pinine bağlı butonu okuyacak ve RB3, RB4, RB5 pinlerina bağlı ledleri yakacak şekilde ayarlanıyor.

Satır 94’de USART modülü kullanıma çaılıyor. Satır 33, 34 ve 111’deki fonksiyonları artık kullanabiliriz.

Satır 102’de global kesmeler, satır 103’de çevresel kesmeler, satır 104’de “usart üzerinden veri alındı” kesmesi (Veri geldiğinde bu kesmeye bağlı flag-PIR1bits.RCIF set olacak) aktif ediliyor.

Not: Satır 35’de veriyi okurken (char)ReadUSART() şeklinde değişken dönüşümü uygulayarak okuduk. Bunu yapmamızın amacı veriyi bizim normal kullandığmız formatta (1,2,3…) onluk tabandaki sayılar gibi alabilmek. Eğer (char) dönüşümü uygulamasaydık verileri hexadecimal aldığımızdan dolayı yapacağımız işlemleri de hexadecimal yapmamız gerekecekti (Ör: data == 6 yerine data == 0x06 kullanacaktık).

OpenUSART() ile kullanılan parametrelerin ne anlama geldiği aşağıda verilmiştir;

  • USART_TX_INT_OFF: İletim kesmeleri kapalı
  • USART_RX_INT_ON: Alım kesmeleri açık
  • USART_ASYNCH_MODE: Asenkron iletişim yapacak
  • USART_EIGHT_BIT: 8 bitlik veri aktarımı
  • USART_CONT_RX: Sürekli bir haberleşme olacak
  • USART_BRGH_HIGH: Yüksek baud oranında iletişim
  • 25: Baud oranının hesaplanmasında kullanılacak değer

Kodlar çalıştırıldığında program 0’dan başlayarak her butona basıldığında data_tx‘deki değeri USART üzerinden bilgisayara gönderip data_tx içeriğini 1 arttırmaktadır. cutecom arayüzünde aşağıdakine benzer bir durum oluşacaktır.

Gönderilecek değeri input satırına girip enter’a basarak gönderebiliriz. Eğer girdiğimiz  değer 0-7 arasındaysa o rakam ledlerde gösterilir, değilse ledlerin hepsi bir seferlik yanıp söner.

Bir Cevap Yazın

Aşağıya bilgilerinizi girin veya oturum açmak için bir simgeye tıklayın:

WordPress.com Logosu

WordPress.com hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap /  Değiştir )

Google+ fotoğrafı

Google+ hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap /  Değiştir )

Twitter resmi

Twitter hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap /  Değiştir )

Facebook fotoğrafı

Facebook hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap /  Değiştir )

Connecting to %s