⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 基于LPC213X的GPS应用及使用状态机解码。全面替代LPC213x.h, 展示结构指针在ARM之特殊寄存器应用,特殊寄存器变量可在WATCH窗口中显示,为软件仿真提供最大的方便。
💻 C
📖 第 1 页 / 共 2 页
字号:
            RTC->RTC_CCR = 0; 
	        ch = str[0];
			val = ch - '0';
			RTC->RTC_DOW = val;//故意没校验,主要是验证$Date命令的正确性
            RTC->RTC_CCR = (1 << CLKEN) | (1 << CLKSRC);// 启动RTC
		  }
	      state = 0;//成功结束或失败!!!
		} 
		break;
      case 5://GPRMC语句分析状态
/*----------------------------------------------------------------------
NMEA0183语句(推荐定位信息(GPRMC))
$GPRMC,030545,A,3414.2522,N,10853.9838,E,0.0,0.0,300305,2.5,W*61

NMEA0183语句翻译
    $GPRMC,            讯息代码
<1> 030545,            UTC 时间   北京时间=UTC 时间+8小时=11:05:45
<2> A,                 定位状态, A=有效定位,V=无效定位
<3> 3414.2522,         纬度       北纬34.142522度
<4> N,                 纬度半球N(北半球)或S(南半球)
<5> 10853.9838,        经度       东经108.539838度
<6> E,                 经度半球E(东经)或W(西经)
<7> 0.0,               地面速率   0.0
<8> 0.0,               地面航向   0.0
<9> 300305,            UTC 日期   2005年03月30日
<10>2.5,               磁偏角     2.5度
<11>W                  磁偏角方向 E(东)或W(西)
    *61                总和检查码 *61
----------------------------------------------------------------------*/
		if (ch > ' '){
		  if (ch == '*') {//GPRMC语句解码参数部分结束
		    state = 7;//进入GPRMC语句校验分析状态 
	        str[count ++] = 0;//打印结束串
		  }
		  else {
            crc ^= ch;
	        if (ch != ',') {
	          str[count ++] = ch;
			}
			else {
	          str[count ++] = 0;//打印结束串
			}
		  }
		  if (str[count - 1] == 0) {//需要打印
		    switch(recno) {
			  case 1://030545,            UTC 时间   北京时间=UTC 时间+8小时=11:05:45
			    break;
			  case 2://A,                 定位状态, A=有效定位,V=无效定位
			    break;
			  case 3://3414.2522,         纬度       北纬34.142522度
			    break;
			  case 4://N,                 纬度半球N(北半球)或S(南半球)
			    break;
			  case 5://10853.9838,        经度       东经108.539838度
			    break;
			  case 6://E,                 经度半球E(东经)或W(西经)
			    break;
			  case 7://0.0,               地面速率   0.0
			    break;
			  case 8://0.0,               地面航向   0.0
			    break;
			  case 9://300305,            UTC 日期   2005年03月30日
			    break;
			  case 10://2.5,               磁偏角     2.5度
			    break;
			  case 11://W                  磁偏角方向 E(东)或W(西)
			    break;
			}
		    recno ++;
		    count = 0;
		  }
		}
		else {//防止\r\n死锁
		  state = 0;//
		}
    	break;
      case 6://GPGGA语句分析状态
/*----------------------------------------------------------------------
NMEA0183语句(卫星定位信息(GPGGA))
$GPGGA,030545,3414.2522,N,10853.9838,E,1,05,2.9,442.2,M,-29.4,M,,*69

NMEA0183语句翻译
     $GPGGA,           讯息代码
<1>  030545,           UTC 时间   北京时间=UTC 时间+8小时=11:05:45 
<2>  3414.2522,        纬度       北纬34.142522度
<3>  N,                纬度半球N(北半球)或S(南半球)
<4>  10853.9838,       经度       东经108.539838度
<5>  E,                经度半球E(东经)或W(西经)
<6>  1,                GPS 状态:0=未定位,1=非差分定位,2=差分定位,6=正在估算
<7>  05,               正在使用解算位置的卫星数量(00~12)(前面的0 也将被传输)
<8>  2.9,              HDOP水平精度因子(0.5~99.9)
<9>  442.2,            海拔高度442.2公尺(-9999.9~99999.9)
<10> M,                海拔高度单位公尺
<11> -29.4,            地表平均高度-29.4公尺
<12> M,                地表平均高度单位公尺
<13>  ,
     *69               总和检查码 *69
----------------------------------------------------------------------*/
		if (ch > ' '){
		  if (ch == '*') {//GPRMC语句解码参数部分结束
		    state = 7;//进入GPRMC语句校验分析状态 
	        str[count ++] = 0;//打印结束串
		  }
		  else {
            crc ^= ch;
	        if (ch != ',') {
	          str[count ++] = ch;
			}
			else {
	          str[count ++] = 0;//打印结束串
			}
		  }
		  if (str[count - 1] == 0) {//需要打印
		    switch(recno) {
			  case 1://030545,           UTC 时间   北京时间=UTC 时间+8小时=11:05:45 
			    break;
			  case 2://3414.2522,        纬度       北纬34.142522度
			    break;
			  case 3://N,                纬度半球N(北半球)或S(南半球)
			    break;
			  case 4://10853.9838,       经度       东经108.539838度
			    break;
			  case 5://E,                经度半球E(东经)或W(西经)
			    break;
			  case 6://1,                GPS 状态:0=未定位,1=非差分定位,2=差分定位,6=正在估算
			    break;
			  case 7://05,               正在使用解算位置的卫星数量(00~12)(前面的0 也将被传输)
			    break;
			  case 8://2.9,              HDOP水平精度因子(0.5~99.9)
			    break;
			  case 9://442.2,            海拔高度442.2公尺(-9999.9~99999.9)
			    break;
			  case 10://M,               海拔高度单位公尺
			    break;
			  case 11://-29.4,           地表平均高度-29.4公尺
			    break;
			  case 12://M,               地表平均高度单位公尺
			    break;
			  case 13:
			    break;
			  case 14:
			    break;
			}
		    recno ++;
		    count = 0;
		  }
		}
		else {//防止\r\n死锁
		  state = 0;//
		}
		break;
      case 7://GPRMC/GPGGA语句校验分析状态
	    if (((ch >= '0') && (ch <= '9')) || ((ch >= 'A') && (ch <= 'F'))) {
	      str[count ++] = ch;//合法数据
		}
		else if (ch == '\r') {
		  ch = str[count - 2];
		  if ((ch >= '0') && (ch <= '9')) ch -= '0';
		  else ch -= 'A' - 10;
		  sum = ch << 4;
		  ch = str[count - 1];
		  if ((ch >= '0') && (ch <= '9')) ch -= '0';
		  else ch -= 'A' - 10;
		  sum |= ch;
		  if (sum == crc) {
		    state = 8;//
		  }
		  else {
		    ch = crc >> 4;
		    if (ch <= 9) ch += '0';
		    else ch += 'A' - 10;
		    Uart.TxBuffer[Uart.TxCount ++] = ch;
		    ch = crc & 0x0f;
		    if (ch <= 9) ch += '0';
		    else ch += 'A' - 10;
		    Uart.TxBuffer[Uart.TxCount ++] = ch;
		    for (i = 0; prnstrb[i] != 0; i ++) {
		      Uart.TxBuffer[Uart.TxCount ++] = prnstrb[i];
		    }
            if (!Uart.TxBusy) {//发送器不忙可以立即发送
              VIC->SoftInt = (1 << VICIntSel_UART0);//模拟51的TI=1来引发发送中断
            }
  		      state = 0;//校验失败!!!
		    }
		}
		else {
		  state = 0;//
		}
		break;
	  case 8:
	    if (ch == '\n') {
		  for (i = 0; prnstrg[i] != 0; i ++) {
		    Uart.TxBuffer[Uart.TxCount ++] = prnstrg[i];
		  }
          if (!Uart.TxBusy) {//发送器不忙可以立即发送
            VIC->SoftInt = (1 << VICIntSel_UART0);//模拟51的TI=1来引发发送中断
          }
		  state = 0;//成功解码
		}
	    break;
	  default://其他状态出错
	    state = 0;
	}
  }
  VIC->SoftIntClr = (1 << VICIntSel_SoftInt22);
  VIC->VectAddr = 0;		// 向量中断结束
}

void SystemInit(void)
{
volatile unsigned int start;
  for (start = 0; start < 10000; start ++);
  if (SystemRamTest != 0x55aa) {
    SystemRamTest = 0x55aa;
  }
  VicInit();
  PortInit();
  UartInit();
  RtcInit();
}

void VicInit(void)
{
unsigned int i;
  VIC->IntEnable = 0;
  VIC->SoftIntClr = 0xffffffff;//清除所有软中断标志
  VIC->IntSelect   = 0;//全部中断为IRQ中断或默认中断
  for(i = 0;i < 16;i++) {
    VIC->VectCntls[i] = 0;
	VIC->VectAddrs[i] = 0; 
  }
}

void PortInit(void)
{
  PINSEL->PIN_SEL0 = 0x00000000;		// 设置管脚连接GPIO
  PINSEL->PIN_SEL1 = 0x00000000;		// 设置管脚连接GPIO
  PINSEL->PIN_SEL2 = 0x00000000;		// 设置管脚连接GPIO
}

void UartInit(void)
{
unsigned int Fdiv;
  Uart.TxCount = 0;
  Uart.RxCount = 0;
  Uart.TxdCount = 0;
  Uart.RxdCount = 0;
  Uart.TxBusy = 0;
  PINSEL->PIN_SEL0 |= (P0_0_TXD0 << P0_0_PINSEL) | (P0_1_RXD0 << P0_1_PINSEL); //设置I/O连接到UART0

  U0->LCR = 0x83;// DLAB=1,允许设置波特率
  Fdiv  = (Fpclk / 16) / UART_BPS;// 设置波特率38400
  U0->DLM = Fdiv / 256;
  U0->DLL = Fdiv % 256;
  U0->LCR = 0x03;
  U0->FCR = 0xc7;/* 初始化FIFO 接收14个字节就中断*/
  U0->IER = 0x07;/* 允许接收发送中断 */
  VIC->VectAddrs[0] = (unsigned int)IRQ_BOD;
  VIC->VectCntls[0]   = VICIntSel_Enable
                      | VICIntSel_BOD;
  VIC->VectAddrs[1] = (unsigned int)IRQ_UART0;
  VIC->VectCntls[1]   = VICIntSel_Enable//使能IRQ中断
                      | VICIntSel_UART0;//获取UART0的IRQ级别
  VIC->IntEnable |= (1 << VICIntSel_UART0)//使能UART0中断
                 |  (1 << VICIntSel_BOD);
}

void RtcInit(void)
{
  POWER->P_CONP |= (1 << PCRTC);
  RTC->RTC_CCR = 0; 
  RTC->RTC_CIIR = (1 << IMSEC);				    // 设置秒值的增量产生一次中断
  RTC->RTC_ILR = (1 << RTCALF) | (1 << RTCCIF);	// 清除RTC增量和报警中断标志
  RTC->RTC_CCR = (1 << CLKEN) | (1 << CLKSRC);				        // 启动RTC
  VIC->VectAddrs[2] = (unsigned int)IRQ_RTC;
  VIC->VectCntls[2]   = VICIntSel_Enable//使能RTC中断
                      | VICIntSel_RTC;//获取RTC的IRQ级别
  VIC->VectAddrs[3] = (unsigned int)IRQ_WriteRTC;
  VIC->VectCntls[3]   = VICIntSel_Enable
                      | VICIntSel_SoftInt22;
  VIC->IntEnable  |= (1 << VICIntSel_RTC)//使能RTC中断
                  |  (1 <<   VICIntSel_SoftInt22);
  Rtc.Year	= RTC->RTC_YEAR;
  Rtc.Month	= RTC->RTC_MONTH;
  Rtc.Doy	= RTC->RTC_DOY;
  Rtc.Hour	= RTC->RTC_HOUR;
  Rtc.Min	= RTC->RTC_MIN;
  Rtc.Sec	= RTC->RTC_SEC;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -