---
---
18F14K50のEUSARTを使い非同期のシリアル信号を受信しLCD表示する回路を応用し、GPS受信機を作成しました。
使用したGPS受信モジュールGM-316は、電源を供給するだけで、GPSからの電波を受信し、さらに、その受信内容をシリアル信号で送り出してくれます。特別に設定を変更しなければ、GPSモジュールから1秒間隔で位置・時刻・受信衛星数等の情報が、4800bps、8bit、NonパリティのTTLレベルのシリアル信号として出力されます。
マイコンでは、この情報を受信し、必要なデータだけを取り出し、LCDに表示します。GPSモジュールが位置の計算など複雑な処理をするため、PIC本体のプログラム処理は、受信した文字情報を並び替えるだけの単純なものとなりました。
プロジェクトファイル GPS_GM316_I2C_4M_5v.zip |
<プログラム>
main.c
//********************************************************* // PIC18F14K50 // GPSユニットからの4800bpsのGGAデータを解析し // I2C接続LCD表示器に緯度・軽度を表示する。 // 18ビット目が ','なら、無効なデータと判断する // 1)Define I/O PORT // PORTB(4)pin13 : SDA // PORTB(6)pin11 : SCL // 2)OSC // 4MHz //********************************************************* #include <p18f14k50.h> #include <delays.h> #include "L_i2cLCD.h" #include <usart.h> #define CR_EN RCSTAbits.CREN #define O_ERR RCSTAbits.OERR #define Max 47 //-------------- コンフィグレーション ------------------------ #pragma config MCLRE = OFF #pragma config PWRTEN = OFF #pragma config BOREN = OFF #pragma config BORV = 30 #pragma config WDTEN = OFF #pragma config WDTPS = 32768 #pragma config STVREN = ON #pragma config FOSC = IRC // 内部クロック #pragma config PLLEN = ON #pragma config CPUDIV = NOCLKDIV #pragma config USBDIV = OFF #pragma config FCMEN = OFF #pragma config IESO = OFF #pragma config HFOFST = OFF #pragma config LVP = OFF #pragma config XINST = OFF #pragma config BBSIZ = OFF #pragma config CP0 = OFF #pragma config CP1 = OFF #pragma config CPB = OFF #pragma config CPD = OFF #pragma config WRT0 = OFF #pragma config WRT1 = OFF #pragma config WRTB = OFF #pragma config WRTC = OFF #pragma config WRTD = OFF #pragma config EBTR0 = OFF #pragma config EBTR1 = OFF #pragma config EBTRB = OFF // void rcvGPSword(void); void LCD_msg(char *, char); char str_cmp(char *, rom const char *, char); // #pragma code //------------ Strings Data char dataGPS[Max]; //データ例"GPGGA,101229.487,3723.2475,N,12158.3416,W,1,07,1.0,9.0,M, , , ,0000*3E"; //------------ Program void main(void){ char i; OSCCON = 0b01010010; // 内部クロック4Mhz PORTA = 0x00; PORTB = 0x00; PORTC = 0x00; TRISA = 0b11111111; //PortA すべて入力 TRISB = 0b11111111; //PortB すべて入力 TRISC = 0b11111111; //PortC すべて入力 ANSEL = 0b00000000; //すべて Degital PORT ANSELH = 0b00000000; ///*------------ Initialize LCD_int(); baudUSART ( BAUD_IDLE_RX_PIN_STATE_HIGH & BAUD_IDLE_TX_PIN_STATE_HIGH & BAUD_16_BIT_RATE & BAUD_WAKEUP_OFF & BAUD_AUTO_OFF); OpenUSART( USART_TX_INT_OFF & USART_RX_INT_OFF & USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_CONT_RX & USART_BRGH_HIGH, 207); //4800 bps while (1){ rcvGPSword(); // GPS GGAデータの受信 if(str_cmp(dataGPS,"GPGGA", 5)==0){ // if(dataGPS[18]==','){ // GPS受信していない if(0){ // GPS受信していない LCD_clr(); LCD_ROMstr(" GPS"); LCD_posyx(1,5); LCD_ROMstr("No Data"); }else{ // GPS受信している LCD_posyx(0,0); LCD_msg(dataGPS+6,2); // UTC時 LCD_dat(':'); LCD_msg(dataGPS+8,2); // UTC分 LCD_dat(':'); LCD_msg(dataGPS+10,2); // UTC秒 LCD_posyx(0,14); LCD_msg(dataGPS+44,2); // 衛星数 LCD_posyx(1,0); LCD_msg(dataGPS+27,1); // N or S LCD_msg(dataGPS+17,6); // 度 LCD_dat(' '); LCD_msg(dataGPS+40,1); // W or E LCD_msg(dataGPS+29,7); // 度 } } } } //************** GPSデータ受信 *********************** // 受信データは"$"の後から、 // データ配列の数まで、または // 改行が送られて来るまで繰り返される。 //************************************************* void rcvGPSword(void){ unsigned char i, data; i = 0; // 格納ポインタリセット if(O_ERR)CR_EN=0,CR_EN=1; // Overrunエラーをクリア do{ // "$"を受信するまで待つ while (!DataRdyUSART()); }while(ReadUSART() != '$'); do{ while (!DataRdyUSART()); // データを受信したら data=ReadUSART(); // dataGPS[i++] = data; // データ保存 if(i >= Max) break; // 配列のMaxまで }while(data != 0x0A); // 改行なら終了 } //-------- 文字列出力 -------------------------------- // 指定文字列から、指定文字数を出力する // --------------------------------------------------- void LCD_msg(char *str, char num){ while(num-- ) //指定文字数だけ継続 LCD_dat(*str++); //文字出力しポインタ+1 } // ------- 文字列比較 -------------------------------- // 指定文字列と””内文字列を、指定文字数比較する // 一致なら「0」、不一致なら正数 // --------------------------------------------------- char str_cmp(char *str, rom const char *msg, char num){ do{ if((*str++) != (*msg++))break; }while(--num); return num; }