NUC200 NUC220接收&處理GPS之資料

透過MCU的UART接收GPS的資料,然後透過字串處理解讀NMEA GPRMC

  1. #include "stdlib.h"
  2. #include "stdio.h"
  3. #include "string.h"
  4. #include "NUC200Series.h"
  5.  
  6. #define PLL_CLOCK 48000000
  7.  
  8. char gps_data[512] = { 0 };
  9. int flag = 0;
  10.  
  11. struct {
  12. char _gprmc[10];
  13. char utc_time[10];
  14. char status[10];
  15. char latitude_value[10];
  16. char latitude[10];
  17. char longtitude_value[10];
  18. char longtitude[10];
  19. char speed[10];
  20. char azimuth_angle[10];
  21. char utc_date[10];
  22. char declination_value[10];
  23. char declination[10];
  24. char check_sum[10];
  25. } gprmc = { 0 };
  26.  
  27. void SYS_Init(void)
  28. {
  29. /*---------------------------------------------------------------------------------------------------------*/
  30. /* Init System Clock */
  31. /*---------------------------------------------------------------------------------------------------------*/
  32.  
  33. /* Enable Internal RC 22.1184MHz clock */
  34. CLK_EnableXtalRC(CLK_PWRCON_OSC22M_EN_Msk);
  35.  
  36. /* Waiting for Internal RC clock ready */
  37. CLK_WaitClockReady(CLK_CLKSTATUS_OSC22M_STB_Msk);
  38.  
  39. /* Set core clock as PLL_CLOCK from PLL */
  40. CLK_EnablePLL(CLK_PLLCON_PLL_SRC_HIRC, PLL_CLOCK);
  41.  
  42. CLK_WaitClockReady(CLK_CLKSTATUS_PLL_STB_Msk);
  43.  
  44. /* Switch HCLK clock source to Internal RC and HCLK source divide 1 */
  45. CLK_SetHCLK(CLK_CLKSEL0_HCLK_S_HIRC, CLK_CLKDIV_HCLK(1));
  46.  
  47. /* Enable UART module clock */
  48. CLK_EnableModuleClock(UART0_MODULE);
  49.  
  50. /* Select UART module clock source */
  51. CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART_S_HIRC, CLK_CLKDIV_UART(1));
  52.  
  53. /* Update System Core Clock */
  54. SystemCoreClockUpdate();
  55.  
  56. /*---------------------------------------------------------------------------------------------------------*/
  57. /* Init I/O Multi-function */
  58. /*---------------------------------------------------------------------------------------------------------*/
  59.  
  60. /* Set GPB multi-function pins for UART0 RXD(PB.0) and TXD(PB.1) */
  61. SYS->GPB_MFP &= ~(SYS_GPB_MFP_PB0_Msk | SYS_GPB_MFP_PB1_Msk);
  62. SYS->GPB_MFP |= SYS_GPB_MFP_PB0_UART0_RXD | SYS_GPB_MFP_PB1_UART0_TXD;
  63. }
  64.  
  65.  
  66. void fatch_gprmc(void)
  67. {
  68. char *xPtr;
  69. char rmc_data[128] = { 0 };
  70. char arr[13][12] = { 0 };
  71. char cursor = 0;
  72. //get GPRMC from raw data
  73. if((xPtr = strstr(gps_data, "$GPRMC")) != NULL)
  74. {
  75. for(int i=0; xPtr[i-1] != '\n'; i++)
  76. {
  77. rmc_data[i] = xPtr[i];
  78. if(rmc_data[i]=='\n') rmc_data[i]='\0';
  79. }
  80. //printf("%s\r\n", rmc_data);
  81. //split rmc_data
  82. xPtr = &arr[0][0]; //get pointer of arr[0][0]
  83. for(int i=0; rmc_data[i] != '\0'; i++)
  84. {
  85. if(rmc_data[i]==',') xPtr = &arr[++cursor][0]; //change the offset of pointer when rmc_data[i]==','
  86. else *xPtr++ = rmc_data[i];
  87. }
  88.  
  89. for(int i=0; i<13; i++)
  90. printf("%s\r\n", arr[i]);
  91. printf("\r\n");
  92. }
  93.  
  94. //GPRMC example
  95. //header UTC time S latitude longtitude speed azimuth UTC date check sum
  96. //$GPRMC,121252.000,A,3958.3032,N,11629.6046,E,15.15,359.95,070306,,,A*54
  97. }
  98.  
  99. void UART02_IRQHandler(void)
  100. {
  101. //printf("UART0 interrupt happen.\r\n");
  102. if(UART_GET_INT_FLAG(UART0, UART_ISR_TOUT_INT_Msk))
  103. {
  104. char i, str[46] = { 0 };
  105. for(i=0; !(UART0->FSR & UART_FSR_RX_EMPTY_Msk); i++) str[i] = UART0->RBR;
  106. strcat(gps_data, str);
  107. printf("%s", gps_data);
  108. fatch_gprmc();
  109. flag=1;
  110. }
  111. if(UART_GET_INT_FLAG(UART0, UART_ISR_RDA_INT_Msk))
  112. {
  113. char i, str[46] = { 0 };
  114. for(i=0; i<30; i++) str[i] = UART0->RBR;
  115. if(flag==1) strcpy(gps_data, str);
  116. else strcat(gps_data, str);
  117. flag=0;
  118. }
  119. }
  120.  
  121. void UART0_Init()
  122. {
  123. /*---------------------------------------------------------------------------------------------------------*/
  124. /* Init UART */
  125. /*---------------------------------------------------------------------------------------------------------*/
  126. /* Reset UART0 module */
  127. SYS_ResetModule(UART0_RST);
  128.  
  129. /* Configure UART0 and set UART0 Baudrate */
  130. UART_Open(UART0, 115200);
  131. }
  132.  
  133. int main()
  134. {
  135. SYS_UnlockReg();
  136. SYS_Init();
  137. SYS_LockReg();
  138. UART0_Init();
  139. UART0->FCR &= ~(UART_FCR_RFITL_Msk);
  140. UART0->FCR |= UART_FCR_RFITL_46BYTES;
  141. UART_SetTimeoutCnt(UART0, 0xf0);
  142. UART_EnableInt(UART0, UART_IER_RDA_IEN_Msk | UART_IER_TOUT_IEN_Msk);
  143. printf("\r\nNUC220 ok\r\n");
  144. PA10=1;
  145. GPIO_SetMode(PA, BIT10, GPIO_PMD_OUTPUT);
  146. while(1)
  147. {
  148. }
  149. }

執行結果:

留言

這個網誌中的熱門文章

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

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

科風 BNT-1000AP 黑武士系列不斷電系統開箱拆解、簡易評測及經驗分享