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>
執行結果:
留言
張貼留言