ただのメモです。
これを以前はアセンブラで書いてました;;
・「$GPGGA,」を検出して、次の「,」になるまで Buf に時刻文字列を格納します。
・Tgtで指定されている「$GPGGA,」を「$GPRMC,」などに変えればそちらを探せます。
・状態遷移型(switch case のところ)で書くとロジックがよく見えます。
・なので enum を書くのが久し振りだったりします。
・BaudRateGen()マクロはまるまるパクリです。_XTAL_FREQ と _BAUD_RATE を #define するだけで最適なボーレートを算出してくれます。
・main() の最後に while() が3つありますが、最初の2つは、Buf に最初の結果が書かれるまで待つためにあります。
--------------ここから----------------------
#include <xc.h>
#include "MyDef.h"
#include "I2CLib.h"
#include "AQM0802lib.h"
#pragma config FOSC = INTOSC
#pragma config WDTE = OFF
#pragma config PLLEN = OFF
enum Stat {Ready, Detectng, Matchd} SrchStat = Ready;
#define BUFSIZ 16
char Buf[BUFSIZ];
char Tgt[] = "$GPGGA,";
#define TGTEND ','
void InterUsart(void)
{
unsigned char dt;
static char *pt;
static unsigned char i;
if (!RCIF) return;
dt = RCREG; // RCIF -> 0 automatically
switch (SrchStat) {
case Ready:
pt = Tgt;
if (dt == *pt) {
pt++;
SrchStat = Detectng;
}
break;
case Detectng:
if (dt == *pt) {
pt++;
if (*pt == 0) {
i = 0;
SrchStat = Matchd;
}
} else {
SrchStat = Ready;
}
break;
case Matchd:
if (dt == TGTEND) {
SrchStat = Ready;
} else {
Buf[i++] = dt;
if (i >= BUFSIZ) i = 0;
}
break;
default:
break;
}
}
void interrupt InterFunction( void )
{
InterI2C() ;
InterUsart();
}
void init_usart(void)
{
TXSTA = 0b00100000; // 8-bit, TXEN, async, BRGH=0
RCSTA = 0b10010000; // SPEN, 8-bit, CREN
BAUDCON = 0b00000000; // BRG16=0
BaudRateGen(); // init SPBRG, BRGH,
RCIE = 1;
RCIF = 0;
}
void main()
{
unsigned short i;
OSCCON = 0b01110010; // 8MHz
OPTION_REG = 0b00000000; // Weak Pullup enable
ANSELC = 0b00000000;
RC0PPS = 0x10;
RC1PPS = 0x11;
InitI2C_Master();
LCD_Init(0, 0x20, 0);
init_usart();
while(SrchStat != Matchd)
;
while(SrchStat != Ready)
;
while(1) {
LCD_SetCursor(0, 0);
for (i = 0; i < 8; i++) {
LCD_Putc(Buf[i]);
}
__delay_ms(200);
}
}