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)
 {
  
 }
}

執行結果:

留言

這個網誌中的熱門文章

無法被取代的指針型三用電表(一):前言

關於新唐科技NuMicro ISP的介紹和使用方式

新唐火神板開箱實作(一):NuMaker-Volcano與NuEclipse IDE入門篇