«

»

Nis 19

Bu Yazı bas

GPS ile Konum Belirleme Sistemi ve C# arayüz ile görüntüleme

ORHAN YILMAZ, 14 Kasım 2010, Pazar

Proje Amacı:
GPS modül ile seri port üzerinden alınan verilerin ayrıştırılarak LCD yardımıyla kullanıcıya sunulması.

Proje Sahibi           :
Orhan YILMAZ

Proje Danışmanı   :
Yrd.Doç.Dr. Ahmet Özmen

Üniversite              :
Dumlupınar Üniversitesi

Bölüm                     :
Elektrik-Elektronik Mühendisliği

Proje Detayları
GPS Nedir: GPS (Global Positioning System; Küresel Konumlama Sistemi), düzenli olarak kodlanmış bilgi yollayan bir uydu ağıdır ve uydularla arasındaki mesafeyi ölçerek Dünya üzerindeki kesin yeri tespit etmeyi mümkün kılar.(tr.wikipedia.org) Kullanımı ücretsizdir.

GPS modülü olarak piyasada bulabileceğim, Sirfstar3 çipli ve seri port üzerinden direk çalıştırılabilen modülü kullanmayı düşündüm.
Bu işlem MSP430 kontrolörün Rx – Tx haberleşme portu üzerinden direk haberleştirme işlemiyle başlıyor. Devamında alınan verilerin çözülmesi ve son olarak Lcd display’e yazılması işlemiyle son buluyor.

Proje Sonucu

Proje tamamlandığında, istenilen şekilde gerekli yazılım güncellemeleri yapılarak otonom ya da manual kullanımlı, robotik sistemlerde, konum bilgisinin ve yön bilgisinin alınmasına ve bu bilgi yardımıyla izlemesi gereken yönde hareketini kolaylaştırmada temel oluşturmuş olacağız.

(Tarih:17.12.2010)
Güncelleme 1:

Temin edilen GPS modülü: XN934D
GPS modülünde karşılaşılan sıkıntılar:

1. GPS modulu pinleri smd olduğundan üzerine lehim yapıp kullanmak sıkıntılı oldu. Kablo sık sık kopuyordu.

Çözüm :GPS modülüne kabloları soket şeklinde  takılabilecek şekilde PCB çizildi.

GPS_PCB 1:

(Tarih:31.12.2010)

Güncelleme 2:

GPS_PCB 2 :

(5V Besleme eklendi)
Modul faraday kafesi şeklide gürültü korumalı olduğundan,
alt graund kısa devre ihtimaline karşı kaldırıldı.

Modül PCB Montajı Tamamlanmış Hali:

*Anten olarak deneme amaçlı standart wireless anten kullanıldı.

*PCB için okulun PCB Laboratuarı kullanıldı.

*3.3V regüle olarak AMS1117-3.3 kullanıldı.

2. MSP430G2231 Hardware(Donanım) olarak UART bulunmamakta ve bu projenin temelini oluşturmakta.

Çözüm: Software(Yazılımsal) UART geliştiriliyor. Proje sonucunda tamamlanabilirse genel bir c kütüphanesi haline getirilmesi amaçlanıyor.

(Tarih:20.01.2011)
Güncelleme 3:

GPS Modülü, Launchpad seri portu aracılığıyla direkt olarak bilgisayara bağlanarak çıktılarSirf Demo uygulaması aracılığıyla gözlemlendi ve Google Earth programı üzerinde işaretlenerek çıktı gözlemlendi.
Sonuç:

– Anten açık alana çıkarıldıkça konum hassasiyeti netleşti.
– Son olarak cam kenarında dahi yaklaşık 3-5 m bir hassasiyet alındı.(Testte deneme amaçlı bir anten kullanıldı.)

SirfDemo Çıktısı

GPS modülü SirfDemo çıkışı

GPS verisi 5 katlı binanın 1. katında alınmıştır.
Uygun bir GPS anteni kullanarak açık alanda daha hassas veriler alınabilir.

Google Earth Çıktısı

GPS anteni açık alana çıkarıldıkça konumun daha doğru alındığı Google Eart uygulaması ile de gözlemlenmiş oldu.


Test yapılırken kullanılan anten ve modul bağlantısı.

Sirfdemo Testi ve kullanılan antenSirfdemo Testi ve kullanılan anten

(Tarih:23.01.2011)
Güncelleme 4:

Software UART  Kütüphanemiz

my.h   


/*********************************************************************************
 ** Proje Başlığı: GPS ile Konum Belirleme					**
 ** Proje bağlantısı: http://www.mcu-turkey.com/?p=1938				**
 **-----------------------------------------------------------------------------**
 ** Proje Yürütücüsü: Orhan YILMAZ						**
 ** Danışman Hoca: Yrd.Doç.Dr.Ahmet ÖZMEN					**
 ** Üniversite: Dumlupınar Üniversitesi						**
 ** Bölüm: Elektrik - Elektronik Mühendisliği 					**
 ** ----------------------------------------------------------------------------**
 ** Not: Danışman hocamın yardımıyla tamamladığım uart uygulamasına 		**
 ** değişiklikler yapılarak kütüphane haline getirildi.				**
 ** Şuan değişiklik yapmadan,fonksiyonlar çağırılarak standart kütüphane gibi 	**
 ** kullanılabilir.								**
 ********************************************************************************/
 
//******************************************************************************
//  MSP430G2xx1 - Timer_A, Ultra-Low Pwr UART 9600, 32kHz ACLK
//******************************************************************************
#include "msp430g2231.h"
 
//------------------------------------------------------------------------------
// Hardware-related definitions
//------------------------------------------------------------------------------
#ifndef UART_TXD
#define UART_TXD   0x02 		// TXD on P1.1 (Timer0_A.OUT0)
#endif
 
#ifndef UART_RXD
#define UART_RXD   0x04                 // RXD on P1.2 (Timer0_A.CCI1A)
#endif
//------------------------------------------------------------------------------
// Conditions for 9600 Baud SW UART, SMCLK = 1MHz
//------------------------------------------------------------------------------
#define CLK 1000000
 
#ifndef BAUND
#define BAUND 9600
#endif
 
#define UART_TBIT_DIV_2     (CLK / (BAUND * 2))
#define UART_TBIT           (CLK / BAUND) 
 
//------------------------------------------------------------------------------
// Global variables used for full-duplex UART communication (Global Değişkenler)
//------------------------------------------------------------------------------ 
 
unsigned int txData;                        // UART internal variable for TX
unsigned char rxBuffer;                     // Received UART character 
 
//------------------------------------------------------------------------------
// Function prototypes (Fonksiyonlar)
//------------------------------------------------------------------------------
void UARTInit(void);
void SendByte(unsigned char byte);
void SendStr(char *string);
unsigned char RecvByte(void);
void RecvStr(char *msg, unsigned char n);
void RecvStrTEMP(void);



uart.h   
/*************************************************************************************
 ** Proje Başlığı: GPS ile Konum Belirleme					    **
 ** Proje bağlantısı: http://www.mcu-turkey.com/?p=1938				    **
 **---------------------------------------------------------------------------------**
 ** Proje Yürütücüsü: Orhan YILMAZ						    **
 ** Danışman Hoca: Yrd.Doç.Dr.Ahmet ÖZMEN					    **
 ** Üniversite: Dumlupınar Üniversitesi						    **
 ** Bölüm: Elektrik - Elektronik Mühendisliği 					    **
 ** --------------------------------------------------------------------------------**
 ** Not: Danışman hocamın yardımıyla tamamladığım uart uygulamasına 		    **
 ** değişiklikler yapılarak kütüphane haline getirildi.				    **
 ** Şuan değişiklik yapmadan,fonksiyonlar çağırılarak standart kütüphane gibi 	    **
 ** kullanılabilir.								    **
 *************************************************************************************/
 
//***********************************************************************************
//  MSP430G2xx1 Demo - Timer_A, Ultra-Low Pwr UART 9600, 32kHz ACLK
//***********************************************************************************
#include "my.h"
//-----------------------------------------------------------------------------------
// main()
//-----------------------------------------------------------------------------------
void uart(void)
{
    //char msg[CS];  // En fazla (CS-1) karakter alır.
 
    WDTCTL = WDTPW + WDTHOLD; 	// Stop watchdog timer (Watchdog Timer Kapatıldı)
 
    DCOCTL = 0x00;         	// Set DCOCLK to 1MHz (Frekans 1MHZ olarak ayarlandı)
    BCSCTL1 = CALBC1_1MHZ;
    DCOCTL = CALDCO_1MHZ; 
 
    P1OUT = 0x00;                   // Initialize all GPIO
    P1SEL |= UART_TXD + UART_RXD;   // Timer function for TXD/RXD pins
    P1DIR |= 0xFF & ~UART_RXD;      // Set all pins but RXD to output 
 
    __enable_interrupt(); 			//Kesmeleri aktif ettik
 
    UARTInit();                     // Start Timer_A UART  (Timer_A UART Başladı)
 
    SendStr("Merhabarn"); 		// Karşılama Mesajları Gönderiliyor...
    SendStr("UART Kullanima Hazir.rn");
    SendStr("GPS ile Konum Belirleme Projesi...rn");
    SendStr("ORHAN YILMAZrnrnrn");
    /*//Test Fonksiyonu:
    for (;;)
    {
        // Tek Byte alımı testi
        //--------------------------
        //SendStr("Bir karakter giriniz:");
        //ch = RecvByte();
        // Echo received character
        //SendByte(ch); 
 
        // String alımı testi
        //-------------------------- 
 
        RecvStr(msg, CS);   // (CS-1) karakter alacak.
        SendStr(msg); 		//msg dizisini gönder.
    } */
}
//-----------------------------------------------------------------------------------
// Function configures Timer_A for full-duplex UART operation (UART Ayarları)
//-----------------------------------------------------------------------------------
void UARTInit(void)
{
    TACCTL0 = OUT;                          // Set TXD Idle as Mark = '1'
    TACCTL1 = SCS + CM1 + CAP + CCIE;       // Sync, Neg Edge, Capture, Int
    TACTL = TASSEL_2 + MC_2;                // SMCLK, start in continuous mode
}
//-----------------------------------------------------------------------------------
// Outputs one byte using the Timer_A UART (Tek Byte Gönderme Fonksiyonumuz)
//-----------------------------------------------------------------------------------
void SendByte(unsigned char byte)
{
    while (TACCTL0 & CCIE);                 // Ensure last char got TX'd
    TACCR0 = TAR;                           // Current state of TA counter
    TACCR0 += UART_TBIT;                    // One bit time till first bit
    TACCTL0 = OUTMOD0 + CCIE;               // Set TXD on EQU0, Int
    txData = byte;                          // Load global variable
    txData |= 0x100;                        // Add mark stop bit to TXData
    txData <<= 1;                           // Add space start bit
}
//-----------------------------------------------------------------------------------
// Receives one byte using the Timer_A UART (Tek byte Alma Fonksiyonumuz)
//-----------------------------------------------------------------------------------
unsigned char RecvByte()
{
    // Gelen karakteri bekle
    __bis_SR_register(LPM0_bits);//Veri gelene kadar CPU'yu kapat(Düşük güç için)
    return rxBuffer;
}
//-----------------------------------------------------------------------------------
// Receives String using the Timer_A UART  (String Alma Fonksiyonumuz)
//-----------------------------------------------------------------------------------
void RecvStr(char *msg, unsigned char n)
{
    register unsigned int i;
    for(i = 0; i < n - 2; i++){
    	__bis_SR_register(LPM0_bits);//Veri gelene kadar CPU'yu kapat(Düşük güç için)
   		*(msg + i) = rxBuffer;       //Karakterleri değişkene al
   		if (rxBuffer == 'n') //Bitirme şartı gerçekleştiğinde döngüden çık
   			break;
    }
   	*(msg + (i + 1)) = '\00';		//Satır sonu ekle
}
 
//-----------------------------------------------------------------------------------
// Temp string (Gereksiz Veri Fonksiyonumuz)
//-----------------------------------------------------------------------------------
void RecvStrTEMP(void)
{
    for (;;)
    {
    	__bis_SR_register(LPM0_bits);
   		if (rxBuffer == 'n')
   			break;
    }
}
 
//-----------------------------------------------------------------------------------
// Prints a string over using the Timer_A UART (String Gönderme Fonksiyonumuz)
//-----------------------------------------------------------------------------------
void SendStr(char *msg)
{
	while (*msg)
       	SendByte(*msg++);
}
//-----------------------------------------------------------------------------------
// Timer_A UART - Transmit Interrupt Handler (Gönderme Kesme Vektörü)
//-----------------------------------------------------------------------------------
#pragma vector = TIMERA0_VECTOR
__interrupt void Timer_A0_ISR(void)
{
    static unsigned char txBitCnt = 10; 
 
    TACCR0 += UART_TBIT;                    // Add Offset to CCRx
    if (txBitCnt == 0) {                    // All bits TXed?
        TACCTL0 &= ~CCIE;                   // All bits TXed, disable interrupt
        txBitCnt = 10;                      // Re-load bit counter
    }
    else {
        if (txData & 0x01) {
          TACCTL0 &= ~OUTMOD2;              // TX Mark '1'
        }
        else {
          TACCTL0 |= OUTMOD2;               // TX Space '0'
        }
        txData >>= 1;
        txBitCnt--;
    }
}
//-----------------------------------------------------------------------------------
// Timer_A UART - Receive Interrupt Handler (Alma Kesme Vektörü)
//-----------------------------------------------------------------------------------
#pragma vector = TIMERA1_VECTOR
__interrupt void Timer_A1_ISR(void)
{
    static unsigned char rxBitCnt = 8;
    static unsigned char rxData = 0; 
 
    switch (__even_in_range(TAIV, TAIV_TAIFG)) { // Use calculated branching
        case TAIV_TACCR1:                        // TACCR1 CCIFG - UART RX
            TACCR1 += UART_TBIT;                 // Add Offset to CCRx
            if (TACCTL1 & CAP) {                 // Capture mode = start bit edge
                TACCTL1 &= ~CAP;                 // Switch capture to compare mode
                TACCR1 += UART_TBIT_DIV_2;       // Point CCRx to middle of D0
            }
            else {
                rxData >>= 1;
                if (TACCTL1 & SCCI) {            // Get bit waiting in receive latch
                    rxData |= 0x80;
                }
                rxBitCnt--;
                if (rxBitCnt == 0) {             // All bits RXed?
                    rxBuffer = rxData;           // Store in global variable
                    rxBitCnt = 8;                // Re-load bit counter
                    TACCTL1 |= CAP;              // Switch compare to capture mode
                    __bic_SR_register_on_exit(LPM0_bits);  // Clear LPM0 bits from 0(SR)
                }
            }
            break;
    }
}
//-----------------------------------------------------------------------------------
//Dumlupınar Üniversitesi	    ORHAN YILMAZ	    Dumlupınar Üniversitesi//
//-----------------------------------------------------------------------------------
GPS.c   
/////////////////////////////////////////////////////////////////////////
// Programcı: ORHAN YILMAZ                                             //
// Proje: GPS ile Konum Belirleme                                      //
// Üniversite: Dumlupınar Üniversitesi                                 //
// Danışman Hoca: Yrd.Doç.Dr.Ahmet ÖZMEN                               //
// Yazılım: GPS Modülünden gelen verilerden kullanılacak satırın       //
// yakalanarak gönderilmesi.					       //
/////////////////////////////////////////////////////////////////////////
#include "uart.h"
#define CS 83
 
void main(void)
{
	char ch[CS];
 
	uart();	//Temel uart konfigürasyonu çağrısı...
	RecvStrTEMP(); //İlk olarak 2 satır Modul versiyon bilgisi gelir ve
	RecvStrTEMP(); //proje için çöp veridir.
 
	for(;;)
	{
 
		RecvStr(ch,CS);	//$GPGGA anahtarlı veri alınıyor.
		RecvStrTEMP();	//Gereksiz bilgi...
		RecvStrTEMP();	//Gereksiz bilgi...
		RecvStrTEMP();	//Gereksiz bilgi...
		SendStr(ch);	//Okunan veri gönderiliyor.
 
	}
}

Bu komutun kullanıldığı test sırasında alınan ekran görüntüsü:

GPS Modul Echo

(Not:Uygulama www.fxdev.org adresinden indirilebilir. Yazan arkadaşa teşekkürler.)

Seçilerek alınan verinin ayrıştırılıp gönderildiği yazılım:

GPS2.c   
/////////////////////////////////////////////////////////////////////////
// Programcı: ORHAN YILMAZ                                             //
// Proje: GPS ile Konum Belirleme                                      //
// Üniversite: Dumlupınar Üniversitesi                                 //
// Danışman Hoca: Yrd.Doç.Dr.Ahmet ÖZMEN                               //
// Yazılım: GPS Modülünden gelen verilerden kullanılacak satırın       //
// ayrıştırılması ve ayrıştırılmış verinin gönderilmesi.               //
/////////////////////////////////////////////////////////////////////////
 
#include "uart.h"
#define CS 83
unsigned char i,j=0,k;
 
void Data(char *ch);
void main(void)
{
	char ch[CS];
 
	uart();	//Temel uart konfigürasyonu çağrısı...
	RecvStrTEMP(); //İlk olarak 2 satır Modul versiyon bilgisi gelir ve
	RecvStrTEMP(); //proje için çöp veridir.
 
	for(;;)
	{
 
		RecvStr(ch,CS);	//$GPGGA anahtarlı veri alınıyor.
		RecvStrTEMP();	//Gereksiz bilgi...
		RecvStrTEMP();	//Gereksiz bilgi...
		RecvStrTEMP();	//Gereksiz bilgi...
		SendStr(ch);	//Okunan veri gönderiliyor.
		Data(ch);
 
	}
}
 
 void Data(char *ch)
{
	j=0;
		if(*(ch+4) == 'G')
			if(*(ch+5) == 'A')
				for(i=0;i<CS;i++)
				{
					if(*(ch+i) == 'n')
						break;
 
				else if(*(ch+i) == ',')
					{
						j++;
						k = 0;
					}
					switch(j)
					{
						case 1:
							if(k == 0)
							{
								SendStr("rn----------rn");
								SendStr("UTC Saati:");
								k++;
							}
							if(*(ch+i) != ',')
								SendByte(*(ch+i));
							break;
						case 2:
							if(k == 0)
							{
								SendStr("rn");
								SendStr("Enlem:");
								k++;
							}
							if(*(ch+i) != ',')
								SendByte(*(ch+i));
							break;
						case 3:
							if(k == 0)
							{
								SendStr("rn");
								SendStr("Kutup(N-S):");
								k++;
							}
							if(*(ch+i) != ',')
								SendByte(*(ch+i));
							break;
						case 4:
							if(k == 0)
							{
								SendStr("rn");
								SendStr("Boylam:");
								k++;
							}
							if(*(ch+i) != ',')
								SendByte(*(ch+i));
							break;
						case 5:
							if(k == 0)
							{
								SendStr("rn");
								SendStr("Dogu-Bati(E-W):");
								k++;
							}
							if(*(ch+i) != ',')
								SendByte(*(ch+i));
							break;
						case 6:
							if(k == 0)
							{
								SendStr("rn");
								SendStr("GPS Kalite:");
								k++;
							}
							if(*(ch+i) != ',')
								SendByte(*(ch+i));
							break;
						case 7:
							if(k == 0)
							{
								SendStr("rn");
								SendStr("Baglanti Sayisi(Uydu):");
								k++;
							}
							if(*(ch+i) != ',')
								SendByte(*(ch+i));
							break;
						case 8:
							if(k == 0)
							{
								SendStr("rn");
								SendStr("Yatay hassasiyet:");
								k++;
							}
							if(ch[i] != ',')
								SendByte(*(ch+i));
							break;
						case 9:
							if(k == 0)
							{
								SendStr("rn");
								SendStr("Rakim:");
								k++;
							}
							if(*(ch+i) != ',')
								SendByte(*(ch+i));
							if(*(ch+i+1) == ',')
								SendStr("rn----------rnrn");
							break;
						default:
							break;
					}
				}
 
}

Güncel kod çalıştırıldığı ilk anda gelen veri:

Daha önce alınmış olan modül kayıtlarından gönderilen verinin ayrıştırılmış hali:

Ayrıştırılmış Data

Modül bağlantısı ile çalıştırılma görüntüleri:

Çalışma Vidyosu:

http://www.dailymotion.com/video/xgp6ij

Proje Amacı Güncellemesi: Proje ilave olarak  yetiştirilebilirse algılanan verinin belirli bir alan içerisinde bilgisayara gönderilmesi ve gönderilen veri ile devrenin çalıştırıldığı hareketli konumunun, Google Map üzerinde işaretlenmesi amaçlanmaktadır.

GPS Nasıl Çalışır ?

YouTube Preview Image

(Tarih: 23.02.2011)
Güncelleme 5:

-Proje başlangıcında belirtildiği gibi (2×16)LCD ilave edildi. LCD ilavesi yapılırken “Muhammet Fatih İnanç” Arkadaşımızın paylaşmış olduğu “IAR” derleyici ortamı içinde yazılmış olan kodlardan yararlanılarak, “Code Composer Studio” derleyicisi için tekrar hazırlandı. Bunun tercih edilme sebebi MSP430G2231 üzerinde 3 pin yeterli olması idi.

-UART kütüphaneleri tekrar gözden geçirildi. GPS verisi ayrıştırma kodları tekrar düzenlenerek seri port üzerinden alınan ve  geri çevrilen kısım yalın hale indirgendi.(LCD Yazılımından sonra flash hafıza yetmiyordu)

-LCD için gönderilmesi gereken veriler ayrıştırıldı. Hazırlanmış olan LCD fonksiyonları kullanılarak, kullanıcı bilgilendirilmesi gerçekleşmiş oldu.

-Verinin kaç saniyede yenilendiği Osilaskop ile GPS modülünden gelen ve entegreden seçilerek gönderilen veri işareti izlenerek tespit edildi.( Yaklaşık 10sn periyotla yeni koordinatlar alındığı gözlendi.)

Sonuç:
-Proje ilk belirtildiği hedefe ulaşmış oldu.

23.02.2011 Tarihli Yazılımlar:                  (Son Hali)

my.h   


/*********************************************************************************
 ** Proje Başlığı: GPS ile Konum Belirleme					**
 ** Proje bağlantısı: http://www.mcu-turkey.com/?p=1938				**
 **-----------------------------------------------------------------------------**
 ** Proje Yürütücüsü: Orhan YILMAZ						**
 ** Danışman Hoca: Yrd.Doç.Dr.Ahmet ÖZMEN					**
 ** Üniversite: Dumlupınar Üniversitesi						**
 ** Bölüm: Elektrik - Elektronik Mühendisliği 					**
 ** ----------------------------------------------------------------------------**
 **										**
 ** Not: Danışman hocamın yardımıyla tamamladığım uart uygulamasına 		**
 ** değişiklikler yapılarak kütüphane haline getirildi.				**
 ** Şuan değişiklik yapmadan,fonksiyonlar çağırılarak standart kütüphane gibi 	**
 ** kullanılabilir.								**
 ********************************************************************************/
 
//******************************************************************************
//  MSP430G2xx1 - Timer_A, Ultra-Low Pwr UART 9600, 32kHz ACLK
//******************************************************************************
#include "msp430.h"
 
//------------------------------------------------------------------------------
// Hardware-related definitions
//------------------------------------------------------------------------------
#ifndef UART_TXD
#define UART_TXD   0x02 	// TXD on P1.1 (Timer0_A.OUT0)
#endif
 
#ifndef UART_RXD
#define UART_RXD   0x04         // RXD on P1.2 (Timer0_A.CCI1A)
#endif
//------------------------------------------------------------------------------
// Conditions for 9600 Baud SW UART, SMCLK = 1MHz
//------------------------------------------------------------------------------
#define CLK 1000000
 
#ifndef BAUND
#define BAUND 9600
#endif
 
#define UART_TBIT_DIV_2     (CLK / (BAUND * 2))
#define UART_TBIT           (CLK / BAUND) 
 
//------------------------------------------------------------------------------
// Global variables used for full-duplex UART communication (Global Değişkenler)
//------------------------------------------------------------------------------ 
 
unsigned int txData;                        // UART internal variable for TX
unsigned char rxBuffer;                     // Received UART character 
 
//------------------------------------------------------------------------------
// Function prototypes (Fonksiyonlar)
//------------------------------------------------------------------------------
void UARTInit(void);
void SendByte(unsigned char byte);
void SendStr(char *string);
unsigned char RecvByte(void);
void RecvStr(char *msg, unsigned char n);
void RecvStrTEMP(void);



uart.h   
/*****************************************************************************************
 ** Proje Başlığı: GPS ile Konum Belirleme						**
 ** Proje bağlantısı: http://www.mcu-turkey.com/?p=1938					**
 **-------------------------------------------------------------------------------------**
 ** Proje Yürütücüsü: Orhan YILMAZ							**
 ** Danışman Hoca: Yrd.Doç.Dr.Ahmet ÖZMEN						**
 ** Üniversite: Dumlupınar Üniversitesi							**
 ** Bölüm: Elektrik - Elektronik Mühendisliği 						**
 ** ------------------------------------------------------------------------------------**
 **											**
 ** Not: Danışman hocamın yardımıyla tamamladığım uart uygulamasına 			**
 ** değişiklikler yapılarak kütüphane haline getirildi.					**
 ** Şuan değişiklik yapmadan,fonksiyonlar çağırılarak standart kütüphane gibi 		**
 ** kullanılabilir.									**
 ****************************************************************************************/
 
//***********************************************************************************
//  MSP430G2xx1 Demo - Timer_A, Ultra-Low Pwr UART 9600, 32kHz ACLK
//***********************************************************************************
#include "my.h"
//-----------------------------------------------------------------------------------
// main()
//-----------------------------------------------------------------------------------
void uart(void)
{
    //char msg[CS];  // En fazla (CS-1) karakter alır.
 
    WDTCTL = WDTPW + WDTHOLD; 	// Stop watchdog timer (Watchdog Timer Kapatıldı)
 
    DCOCTL = 0x00;         	// Set DCOCLK to 1MHz (Frekans 1MHZ olarak ayarlandı)
    BCSCTL1 = CALBC1_1MHZ;
    DCOCTL = CALDCO_1MHZ; 
 
    P1OUT = 0x00;                   // Initialize all GPIO
    P1SEL |= UART_TXD + UART_RXD;   // Timer function for TXD/RXD pins
    P1DIR |= 0xFF & ~UART_RXD;      // Set all pins but RXD to output 
 
    __enable_interrupt(); 			//Kesmeleri aktif ettik
 
    UARTInit();                     // Start Timer_A UART  (Timer_A UART Başladı)
 
 //   SendStr("Merhabarn"); 			// Karşılama Mesajları Gönderiliyor...
 //   SendStr("UART Kullanima Hazir.rn");
 //   SendStr("GPS ile Konum Belirleme Projesi...rn");
    SendStr("ORHAN YILMAZrnMCU-TURKEYrn");
    /*//Test Fonksiyonu:
    for (;;)
    {
        // Tek Byte alımı testi
        //--------------------------
        //SendStr("Bir karakter giriniz:");
        //ch = RecvByte();
        // Echo received character
        //SendByte(ch); 
 
        // String alımı testi
        //-------------------------- 
 
        RecvStr(msg, CS);   // (CS-1) karakter alacak.
        SendStr(msg); 		//msg dizisini gönder.
    } */
}
//-----------------------------------------------------------------------------------
// Function configures Timer_A for full-duplex UART operation (UART Ayarları)
//-----------------------------------------------------------------------------------
void UARTInit(void)
{
    TACCTL0 = OUT;                          // Set TXD Idle as Mark = '1'
    TACCTL1 = SCS + CM1 + CAP + CCIE;       // Sync, Neg Edge, Capture, Int
    TACTL = TASSEL_2 + MC_2;                // SMCLK, start in continuous mode
}
//-----------------------------------------------------------------------------------
// Outputs one byte using the Timer_A UART (Tek Byte Gönderme Fonksiyonumuz)
//-----------------------------------------------------------------------------------
void SendByte(unsigned char byte)
{
    while (TACCTL0 & CCIE);                 // Ensure last char got TX'd
    TACCR0 = TAR;                           // Current state of TA counter
    TACCR0 += UART_TBIT;                    // One bit time till first bit
    TACCTL0 = OUTMOD0 + CCIE;               // Set TXD on EQU0, Int
    txData = byte;                          // Load global variable
    txData |= 0x100;                        // Add mark stop bit to TXData
    txData <<= 1;                           // Add space start bit
}
//-----------------------------------------------------------------------------------
// Receives one byte using the Timer_A UART (Tek byte Alma Fonksiyonumuz)
//-----------------------------------------------------------------------------------
unsigned char RecvByte()
{
    // Gelen karakteri bekle
    __bis_SR_register(LPM0_bits);//Veri gelene kadar CPU'yu kapat(Düşük güç için)
    return rxBuffer;
}
//-----------------------------------------------------------------------------------
// Receives String using the Timer_A UART  (String Alma Fonksiyonumuz)
//-----------------------------------------------------------------------------------
void RecvStr(char *msg, unsigned char n)
{
    register unsigned int i;
    for(i = 0; i < n - 2; i++){
    	__bis_SR_register(LPM0_bits);//Veri gelene kadar CPU'yu kapat(Düşük güç için)
   		*(msg + i) = rxBuffer;       //Karakterleri değişkene al
   		if (rxBuffer == 'n')	//Bitirme şartı gerçekleştiğinde döngüden çık
   			break;
    }
   	*(msg + (i + 1)) = '\00';		//Satır sonu ekle
}
 
//-----------------------------------------------------------------------------------
// Temp string (Gereksiz Veri Fonksiyonumuz)
//-----------------------------------------------------------------------------------
void RecvStrTEMP(void)
{
    for (;
    {
    	__bis_SR_register(LPM0_bits);
   		if (rxBuffer == 'n')
   			break;
    }
}
 
//-----------------------------------------------------------------------------------
// Prints a string over using the Timer_A UART (String Gönderme Fonksiyonumuz)
//-----------------------------------------------------------------------------------
void SendStr(char *msg)
{
	while (*msg)
       	SendByte(*msg++);
}
//-----------------------------------------------------------------------------------
// Timer_A UART - Transmit Interrupt Handler (Gönderme Kesme Vektörü)
//-----------------------------------------------------------------------------------
#pragma vector = TIMERA0_VECTOR
__interrupt void Timer_A0_ISR(void)
{
    static unsigned char txBitCnt = 10; 
 
    TACCR0 += UART_TBIT;                    // Add Offset to CCRx
    if (txBitCnt == 0) {                    // All bits TXed?
        TACCTL0 &= ~CCIE;                   // All bits TXed, disable interrupt
        txBitCnt = 10;                      // Re-load bit counter
    }
    else {
        if (txData & 0x01) {
          TACCTL0 &= ~OUTMOD2;              // TX Mark '1'
        }
        else {
          TACCTL0 |= OUTMOD2;               // TX Space '0'
        }
        txData >>= 1;
        txBitCnt--;
    }
}
//-----------------------------------------------------------------------------------
// Timer_A UART - Receive Interrupt Handler (Alma Kesme Vektörü)
//-----------------------------------------------------------------------------------
#pragma vector = TIMERA1_VECTOR
__interrupt void Timer_A1_ISR(void)
{
    static unsigned char rxBitCnt = 8;
    static unsigned char rxData = 0; 
 
    switch (__even_in_range(TAIV, TAIV_TAIFG)) { // Use calculated branching
        case TAIV_TACCR1:                        // TACCR1 CCIFG - UART RX
            TACCR1 += UART_TBIT;                 // Add Offset to CCRx
            if (TACCTL1 & CAP) {                 // Capture mode = start bit edge
                TACCTL1 &= ~CAP;                 // Switch capture to compare mode
                TACCR1 += UART_TBIT_DIV_2;       // Point CCRx to middle of D0
            }
            else {
                rxData >>= 1;
                if (TACCTL1 & SCCI) {            // Get bit waiting in receive latch
                    rxData |= 0x80;
                }
                rxBitCnt--;
                if (rxBitCnt == 0) {             // All bits RXed?
                    rxBuffer = rxData;           // Store in global variable
                    rxBitCnt = 8;                // Re-load bit counter
                    TACCTL1 |= CAP;              // Switch compare to capture mode
                    __bic_SR_register_on_exit(LPM0_bits);  // Clear LPM0 bits from 0(SR)
                }
            }
            break;
    }
}
//--------------------------------------------------------------------------------------
// Dumlupınar Üniversitesi		ORHAN YILMAZ    	Dumlupınar Üniversitesi
//--------------------------------------------------------------------------------------

LCD_595.h   
/*********************************************************************************
 ** Proje Başlığı: GPS ile Konum Belirleme					**
 ** Proje bağlantısı: http://www.mcu-turkey.com/?p=1938				**
 **-----------------------------------------------------------------------------**
 ** Proje Yürütücüsü: Orhan YILMAZ						**
 ** Danışman Hoca: Yrd.Doç.Dr.Ahmet ÖZMEN					**
 ** Üniversite: Dumlupınar Üniversitesi						**
 ** Bölüm: Elektrik - Elektronik Mühendisliği 					**
 ** ----------------------------------------------------------------------------**
 ** 										**
 ** Not: "Muhammet Fatih İnanç" Arkadaşımızın paylaşmış olduğu "IAR" derleyici 	**
 ** ortamı içinde yazılmış olan kodlardan yararlanılarak,"Code Composer Studio" **
 ** derleyicisi için tekrar hazırlandı.	Fatih arkadaşıma teşekkür ederim...	**
 ********************************************************************************/
#define Clk BIT4
#define Data BIT5
#define Storage BIT7
 
void delay(unsigned long int);
void hc595_yaz(unsigned char);
void lcd_write(unsigned char);
void lcd_putch(unsigned char);
void lcd_puts(const char*);
void lcd_temizle(void);
void lcd_goto(char,char);
void lcd_init(void);

LCD_595.c   
/*********************************************************************************
 ** Proje Başlığı: GPS ile Konum Belirleme					**
 ** Proje bağlantısı: http://www.mcu-turkey.com/?p=1938				**
 **-----------------------------------------------------------------------------**
 ** Proje Yürütücüsü: Orhan YILMAZ						**
 ** Danışman Hoca: Yrd.Doç.Dr.Ahmet ÖZMEN					**
 ** Üniversite: Dumlupınar Üniversitesi						**
 ** Bölüm: Elektrik - Elektronik Mühendisliği 					**
 ** ----------------------------------------------------------------------------**
 ** 										**
 ** Not: "Muhammet Fatih İnanç" Arkadaşımızın paylaşmış olduğu "IAR" derleyici 	**
 ** ortamı içinde yazılmış olan kodlardan yararlanılarak,"Code Composer Studio" **
 ** derleyicisi için tekrar hazırlandı.	Fatih arkadaşıma teşekkür ederim...	**
 ********************************************************************************/
 
#include "msp430.h"
#include "LCD_595.h"
 
#define E_1     0x08
#define RS_E_1  0x0C
 
void delay(unsigned long int d)
{
  	d*=100;
  	for(;d>0;d--);
}
 
void hc595_yaz(unsigned char gelen)
{
	char i;
  	for(i=8;i>0;i--)
  	{
		P1OUT &= ~Data;
    	if(gelen & 0x80)
    		P1OUT |= Data;
    	P1OUT |= Clk;
    	P1OUT &= ~Clk;
    	gelen*=2;
  	}
  	P1OUT |= Storage;
  	P1OUT &= ~Storage;
}
 
void lcd_write(unsigned char port)
{
  //ilk 4 bit gönderiliyor...
  	hc595_yaz(E_1);
  	hc595_yaz(( port & 0xF0) | E_1);
  	hc595_yaz(((port & 0xF0) | E_1) & 0xF0);
  //Son 4 bit gönderiliyor...
  	hc595_yaz(E_1);
  	hc595_yaz(( port<<4 ) | E_1);
  	hc595_yaz(((port<<4 ) | E_1) & 0xF0);
}
 
void lcd_putch(unsigned char port)
{
  //ilk 4 bit gönderiliyor...
  	hc595_yaz(RS_E_1);
  	hc595_yaz(( port & 0xF0 ) | RS_E_1);
  	hc595_yaz(((port & 0xF0 ) | RS_E_1) & 0xF4);
  //Son 4 bit gönderiliyor...
  	hc595_yaz(RS_E_1);
  	hc595_yaz(( port<<4) | RS_E_1);
  	hc595_yaz(((port<<4) | RS_E_1) & 0xF4);
}
 
void lcd_puts(const char * s)
{
  	_nop();
  	while(*s)
    	lcd_putch(*s++);
}
 
void lcd_temizle(void)
{
  	lcd_write(0x1);
  	delay(2);
}
 
void lcd_goto(char x, char y)
{
	if(x==1)
    	lcd_write(0x80+((y-1)%16));
  	else
    	lcd_write(0xC0+((y-1)%16));
}
 
void lcd_init(void)
{	//Çıkış Portları Ayarlanıyor..
	P1DIR |= Clk|Data|Storage;
 
	//Clk,Data,Storage portları başlangıçta
	//sıfırlanıyor..
	P1OUT &= ~(Clk|Data|Storage);
 
	//LCD hazırlanıyor..
  	hc595_yaz(0x00);
 	delay(15);
  	hc595_yaz(0x08);
  	lcd_write(0x02);  // İmleç 0x0 konumunda
  	delay(2);
 
	lcd_write(0x28);  // 4 Bit , Çift Satır LCD
  	lcd_write(0x0C);  // İmleç Gizleniyor
  	lcd_temizle();    // Ekran Temizleniyor
  	lcd_write(0x06);  // Sağa doğru yazma aktif
  	lcd_write(0x80);  // LCD Birinci Satır Konumunda
}

main.c   
/*///////////////////////////////////////////////////////////////////////
// Programcı: ORHAN YILMAZ                                             //
// Proje: GPS ile Konum Belirleme                                      //
//---------------------------------------------------------------------//
// Üniversite: Dumlupınar Üniversitesi                                 //
// Danışman Hoca: Yrd.Doç.Dr.Ahmet ÖZMEN                               //
//---------------------------------------------------------------------//
// Yazılım: GPS v0.1						       //
// Derleyici: Code Compose Studio v4.xx	 			       //
//								       //
// Amaç:Gerekli verilerin seçilerek LCD'de gösterilmesi ve Koordinat   //
// içeren GPS verisinin tekrar seri port üzerinden geri gönderilmesi   //
//								       //
//---------------------------TEŞEKKÜR----------------------------------//
// Danışman hocam Sn. Ahmet ÖZMEN 'e ve Modül PCB hazırlanmasında      //
// desteklerini esirgemeyen Sn. Fırat AYDEMİR 'e 		       //
// Teşekkürlerimi Sunarım...		   			       //
//-****************************************ORHAN YILMAZ***************-//
///////////////////////////////////////////////////////////////////////*/
 
#include "uart.h"
#include "LCD_595.h"
#define CS 83
 
void Data_w(char *ch);
void main(void)
{
	char ch[CS];
 
	uart();	//Temel uart konfigürasyonu çağrısı...
	lcd_init();
	lcd_temizle();
	lcd_goto(1,2);
	lcd_puts("ORHAN YILMAZ");
	lcd_goto(2,3);
	lcd_puts("MCU-TURKEY'11");
  	delay(1000);
  	lcd_temizle();
  	lcd_goto(1,1);
	lcd_puts("Uydudan Konum ");
	lcd_goto(2,1);
	lcd_puts("Aliniyor...");
	RecvStrTEMP();	//Gereksiz bilgi...
 
	for(;;)
	{
 
		RecvStr(ch,CS);	//$GPGGA anahtarlı veri alınıyor.
		Data_w(ch);		//Okunan veri ayrıştırılarak gönderilir..
 
  		//lcd_puts("DUMLUPINAR UNIV.");
  		//lcd_goto(2,2);
	}
}
 
 void Data_w(char *ch)
{
 unsigned char i,j=0,k;
 
	j=0;
	if(*ch == '$')
	if(*(ch+1) == 'G')
	if(*(ch+2) == 'P')
	if(*(ch+3) == 'G')
		if(*(ch+4) == 'G')
			if(*(ch+5) == 'A')
				for(i=0;i<CS;i++)
				{
					if(*(ch+i) == 'n')
						break;
 
				else if(*(ch+i) == ',')
					{
						j++;
						k = 0;
					}
					switch(j)
					{
						case 1:
							if(k == 0)
							{
								SendStr(ch);	//Onaylanan veri seri porttan gönderiliyor.
								//SendStr("rn----------rn");
								//SendStr("UTC Saati:");
								//////LCD////////
								lcd_temizle();
   								lcd_goto(1,1);
  								lcd_puts("UTC Saati:");
  								lcd_goto(2,1);
  								///////END LCD/////
								k++;
							}
							if(*(ch+i) != ',')
							{
							//	SendByte(*(ch+i));
 
								lcd_putch(*(ch+i));
							}
							break;
						case 2:
							if(k == 0)
							{
							//	SendStr("rn");
							//	SendStr("Enlem:");
								//////LCD////////
								delay(1000);
								lcd_temizle();
 
  								lcd_goto(1,1);
  								lcd_puts("Enlem:");
  								lcd_goto(2,1);
								k++;
							}
							if(*(ch+i) != ',')
							{
							//	SendByte(*(ch+i));
 
								lcd_putch(*(ch+i));
							}
							break;
						case 3:
						/*	if(k == 0)
							{
								//SendStr("rn");
								//SendStr("Kutup(N-S):");
								k++;
							}
						*/	if(*(ch+i) != ',')
							{
							//	SendByte(*(ch+i));
 
								lcd_putch(*(ch+i));
							}
							break;
						case 4:
							if(k == 0)
							{
							//	SendStr("rn");
							//	SendStr("Boylam:");
								//////LCD////////
								delay(1000);
								lcd_temizle();
   								lcd_goto(1,1);
  								lcd_puts("Boylam:");
  								lcd_goto(2,1);
 
								k++;
							}
							if(*(ch+i) != ',')
							{
							//	SendByte(*(ch+i));
 
								lcd_putch(*(ch+i));
							}
							break;
						case 5:
						/*	if(k == 0)
							{
								//SendStr("rn");
								//SendStr("Dogu-Bati(E-W):");
								k++;
							}
						*/	if(*(ch+i) != ',')
							{
							//	SendByte(*(ch+i));
 
								lcd_putch(*(ch+i));
							}
							break;
					/*	case 6:
							if(k == 0)
							{
								SendStr("rn");
								SendStr("GPS Kalite:");
								k++;
							}
							if(*(ch+i) != ',')
								SendByte(*(ch+i));
							break;
						case 7:
							if(k == 0)
							{
								SendStr("rn");
								SendStr("Baglanti Sayisi(Uydu):");
								k++;
							}
							if(*(ch+i) != ',')
								SendByte(*(ch+i));
							break;
						case 8:
							if(k == 0)
							{
								SendStr("rn");
								SendStr("Yatay hassasiyet:");
								k++;
							}
							if(ch[i] != ',')
								SendByte(*(ch+i));
							break;
						case 9:
							if(k == 0)
							{
								SendStr("rn");
								SendStr("Rakim:");
								k++;
							}
							if(*(ch+i) != ',')
								SendByte(*(ch+i));
							if(*(ch+i+1) == ',')
								SendStr("rn----------rnrn");
							break;
					*/	default:
                                                    if(j == 6)
                                                        delay(500);
                                                    if(j == 7)
                                                    {
						        lcd_temizle();
						        lcd_goto(1,1);
						        lcd_puts("Lutfen");
						        lcd_goto(2,3);
						        lcd_puts("Bekleyiniz...");
                                                    }
						break;
					}
				}
 
}

LCD ile Çalışma Görüntüleri:

.

Osilaskop Veri Sinyali Görüntüleri:


Entegre Veri Çıkışının Osilaskop Görüntüsü:

 

Uydu Bağlantısı Yapıldığında:


*Koordinatların alınıp gözlenmesi okulun elektronik laboratuarında yapılmıştır.

LCD Koordinat verisi açıklaması:

LCD ekranda izlenen koordinat verilerinde,
UTC Saati veri formatı: hhmmss.sss (h= Saat, m=Dakika, s=Saniye)
Enlem verisi formatı: ddmm.mmmm (d=Derece, m=Dakika)
Boylam verisi formatı: dddmm.mmmm (d=Derece, m=Dakika)

*Bulunduğunuz konumu Google haritalarında işaretletmek isterseniz, yukarıdaki bilgileri kullanarak dereceye çevirmeli ve sonrasında gerekli yerlere girmelisiniz.Hesaplamalar için entegre kapasitesi dolduğundan bu şekilde bırakıldı.

(Tarih:28.02.2011)
Güncelleme 6:

Bu projeye son olarak C# ile konumu harita üzerinde işaretlemeye yarayan  uygulama geliştirildi.
(Proje Harita olarak google haritalarını kullanmakta.Dolayısıyla internet gerekli.)

-İlk C# uygulamam olduğu için belki bug içerebilir.Elimden geldiğince hataları giderdim.

DPU-GPS Programı Başlangıç

Bu resimde devremizden  gelen veri çözülerek işaretlendi.

*Bu Programı buradan indirebilirsiniz.

Not: Entegreden seçilerek gönderilen veri GSM modülü ile merkezde diğer bir GSM e sms gönderilmesi ve merkezde koordinatlar  bilgisayara aktarılması, sonuç olarak bu programla harita üzerinde işaretlenerek bir takip sistemi yapılması amaçlanmıştı. Buna bağlı olarak ek destek talebinde GSM modülü istendi.Fakat imei kaydı yaptırılamadığından şimdilik bu kısım  eklenmedi.

Kabaca çalışmasını anlatacak olursak seri port üzerinden çıkış alınan koordinat bilgileri, GSM modülüne AT komutları ile sms gönderilecek diğer tarafta da benzer şekilde GSM modülü yada akıllı bir telefon ile Bluetooth bağlantısı üzerinden sms okunup programda işlenilerek haritada işaretleme mantığına dayanmaktadır.

Proje en başta belirtildiği şekli ile ve ek olarak bilgisayar arayüzü hazırlanarak tamamlanmış oldu. Bu tarz proje/yarışmaların ülkemizde giderek çoğalması dileğimle tüm arkadaşlara başarılar dilerim…

ORHAN YILMAZ
Dumlupınar Üniversitesi

Bu yazının kalıcı bağlantısı http://www.mafgom.com/gps-ile-konum-belirleme-sistemi/

1 ping

Yorumu formunu geç

  1. @hayrullah_oz

    güzel bir paylaşım okunası ..

    1. Orhan YILMAZ

      Yorumunuz için teşekkür ederim.

  2. Cengizhan

    Çok güzel bir paylaşım olmuş

  3. Hasan Şiyar

    Hocam linki yenileyebilir misiniz?

    1. Orhan YILMAZ

      Link güncellenmiştir. Bilginize.

  4. Güray Tonguç

    Merhaba,
    Okunan Enlem-Boylam değerlerinin Google'da görüntülenmesi için ne yapmak gerekiyor acaba?
    Teşekkürler.

    1. Orhan YILMAZ

      Merhaba
      Google API lerini araştırırsanız size konu hakkında fikir verecektir.
      Kolay gelsin.

  5. Sebahattin

    Güzel bir çalışma tebrik ederim bende butür bir çalışma ile uğraşıyorum holux gr-89 gps modulu kullanıyorum fakat gelen datalar google maps ta yanlış yerde gösteriyor Google Earth a bağladığımda sorun suz çalışıyor hocam bu konuda yardımcı olabilirmisiniz teşekkürler

    1. Orhan YILMAZ

      Selamlar Sebahattin,
      Yazılımınızdaki koordinat dönüşümlerde formata dikkat edin. Muhtemelen onda bir hata var. Tamamını dereceye çevirmelisiniz.
      —-
      UTC Saati veri formatı: hhmmss.sss (h= Saat, m=Dakika, s=Saniye)
      Enlem verisi formatı: ddmm.mmmm (d=Derece, m=Dakika)
      Boylam verisi formatı: dddmm.mmmm (d=Derece, m=Dakika)
      —-
      İyi çalışmalar.

  6. kontrobilgisayar

    merhabalar. gps cihazını bir bisiklete bağladığımızı düşünelim. bilgisayar ekranıından onu anlık takip etmek istiyoruz. nasıl bir yol izlemeliyiz. gps i bilgisayarla nasıl haberleştiririz? c# kullanacağız prog. dili olarak

  7. samet

    Orhan yılmaz size nasıl ulaşabilirim çok acil yardımınıza ihtiyacım var.

    1. Orhan YILMAZ

      Selamlar,
      İletişim kısmını kullanabilirsiniz.

  8. ali onur aktepe

    İyi günler size mailde atmıştım ama buradan da yazayim kodları IAR a direk yapıştırdığımda kütüphane bulunamadı hatası veriyor yardımcı olabilirmisiniz ?

    1. Orhan YILMAZ

      Merhaba,

      Geliştirilirken içeriktede belirtildiği gibi IAR değil Code Composer Studio kullanıldı.

      İyi çalışmalar.

  9. berk

    hocam size zahmet bu C# kodlarını gönderirmisiniz

  10. osman

    güzel bir Çalışma olmuş

Bir Cevap Yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir


Hit Counter provided by orange county divorce attorney