NUC200 NUC220接收&處理GPS之資料
透過MCU的UART接收GPS的資料,然後透過字串處理解讀NMEA GPRMC
執行結果:
#include "stdlib.h"
#include "stdio.h"
#include "string.h"
#include "NUC200Series.h"
#define PLL_CLOCK 48000000
char gps_data[512] = { 0 };
int flag = 0;
struct {
char _gprmc[10];
char utc_time[10];
char status[10];
char latitude_value[10];
char latitude[10];
char longtitude_value[10];
char longtitude[10];
char speed[10];
char azimuth_angle[10];
char utc_date[10];
char declination_value[10];
char declination[10];
char check_sum[10];
} gprmc = { 0 };
void SYS_Init(void)
{
/*---------------------------------------------------------------------------------------------------------*/
/* Init System Clock */
/*---------------------------------------------------------------------------------------------------------*/
/* Enable Internal RC 22.1184MHz clock */
CLK_EnableXtalRC(CLK_PWRCON_OSC22M_EN_Msk);
/* Waiting for Internal RC clock ready */
CLK_WaitClockReady(CLK_CLKSTATUS_OSC22M_STB_Msk);
/* Set core clock as PLL_CLOCK from PLL */
CLK_EnablePLL(CLK_PLLCON_PLL_SRC_HIRC, PLL_CLOCK);
CLK_WaitClockReady(CLK_CLKSTATUS_PLL_STB_Msk);
/* Switch HCLK clock source to Internal RC and HCLK source divide 1 */
CLK_SetHCLK(CLK_CLKSEL0_HCLK_S_HIRC, CLK_CLKDIV_HCLK(1));
/* Enable UART module clock */
CLK_EnableModuleClock(UART0_MODULE);
/* Select UART module clock source */
CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART_S_HIRC, CLK_CLKDIV_UART(1));
/* Update System Core Clock */
SystemCoreClockUpdate();
/*---------------------------------------------------------------------------------------------------------*/
/* Init I/O Multi-function */
/*---------------------------------------------------------------------------------------------------------*/
/* Set GPB multi-function pins for UART0 RXD(PB.0) and TXD(PB.1) */
SYS->GPB_MFP &= ~(SYS_GPB_MFP_PB0_Msk | SYS_GPB_MFP_PB1_Msk);
SYS->GPB_MFP |= SYS_GPB_MFP_PB0_UART0_RXD | SYS_GPB_MFP_PB1_UART0_TXD;
}
void fatch_gprmc(void)
{
char *xPtr;
char rmc_data[128] = { 0 };
char arr[13][12] = { 0 };
char cursor = 0;
//get GPRMC from raw data
if((xPtr = strstr(gps_data, "$GPRMC")) != NULL)
{
for(int i=0; xPtr[i-1] != '\n'; i++)
{
rmc_data[i] = xPtr[i];
if(rmc_data[i]=='\n') rmc_data[i]='\0';
}
//printf("%s\r\n", rmc_data);
//split rmc_data
xPtr = &arr[0][0]; //get pointer of arr[0][0]
for(int i=0; rmc_data[i] != '\0'; i++)
{
if(rmc_data[i]==',') xPtr = &arr[++cursor][0]; //change the offset of pointer when rmc_data[i]==','
else *xPtr++ = rmc_data[i];
}
for(int i=0; i<13; i++)
printf("%s\r\n", arr[i]);
printf("\r\n");
}
//GPRMC example
//header UTC time S latitude longtitude speed azimuth UTC date check sum
//$GPRMC,121252.000,A,3958.3032,N,11629.6046,E,15.15,359.95,070306,,,A*54
}
void UART02_IRQHandler(void)
{
//printf("UART0 interrupt happen.\r\n");
if(UART_GET_INT_FLAG(UART0, UART_ISR_TOUT_INT_Msk))
{
char i, str[46] = { 0 };
for(i=0; !(UART0->FSR & UART_FSR_RX_EMPTY_Msk); i++) str[i] = UART0->RBR;
strcat(gps_data, str);
printf("%s", gps_data);
fatch_gprmc();
flag=1;
}
if(UART_GET_INT_FLAG(UART0, UART_ISR_RDA_INT_Msk))
{
char i, str[46] = { 0 };
for(i=0; i<30; i++) str[i] = UART0->RBR;
if(flag==1) strcpy(gps_data, str);
else strcat(gps_data, str);
flag=0;
}
}
void UART0_Init()
{
/*---------------------------------------------------------------------------------------------------------*/
/* Init UART */
/*---------------------------------------------------------------------------------------------------------*/
/* Reset UART0 module */
SYS_ResetModule(UART0_RST);
/* Configure UART0 and set UART0 Baudrate */
UART_Open(UART0, 115200);
}
int main()
{
SYS_UnlockReg();
SYS_Init();
SYS_LockReg();
UART0_Init();
UART0->FCR &= ~(UART_FCR_RFITL_Msk);
UART0->FCR |= UART_FCR_RFITL_46BYTES;
UART_SetTimeoutCnt(UART0, 0xf0);
UART_EnableInt(UART0, UART_IER_RDA_IEN_Msk | UART_IER_TOUT_IEN_Msk);
printf("\r\nNUC220 ok\r\n");
PA10=1;
GPIO_SetMode(PA, BIT10, GPIO_PMD_OUTPUT);
while(1)
{
}
}
30>13>
執行結果:


留言
張貼留言