PIC18F14K50の基本動作から応用プログラムまでを学びます。

ホーム
16F18313
16F18325
16F18346
16F1619
Curiosity
---
---
    
12F1822
16F1455
16F1459
18F14K50
18F26J50
dsPIC
その他
GPS受信機-GM316

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;
}