用C#读取GPS数据的基类(适用于wince操作系统)

using System;
using System.Runtime.InteropServices;
using System.Text;
namespace BaseStationPDA
{
  class GPs
  {
    public
    string PortNum;

    public
    int BaudRate;

    public byte ByteSize;

    public byte Parity;
    // 0-4=no,odd,even,mark,space
    public byte StopBits;
    // 0,1,2 = 1, 1.5, 2
    public
    int ReadTimeout;
    //comm port win32 file handle
    private
    int hComm = -1;

    public bool Opened = false;
    //win32 api constants
    private const u
    int GENERIC_READ = 0x80000000;

    private const u
    int GENERIC_WRITE = 0x40000000; private const
    int OPEN_EXISTING = 3;

    private const
    int INVALID_HANDLE_VALUE = -1;
    [StructLayout( LayoutKind.Sequential )]
    public struct DCB
    {
      //taken from c struct in platform sdk
      public
      int DCBlength;
      // sizeof( DCB )
      public
      int BaudRate;
      // 指定当前波特率 current baud rate
      // these are the c struct bit fields, bit twiddle flag to set
      public
      int fBinary;
      // 指定是否允许二进制模式,在windows95中必须主TRUE binary mode, no EOF check
      public
      int fParity;
      // 指定是否允许奇偶校验 enable parity checking
      public
      int fOutxCtsFlow;
      // 指定CTS是否用于检测发送控制,当为TRUE是CTS为OFF,发送将被挂起. CTS output flow control
      public
      int fOutxDsrFlow;
      // 指定CTS是否用于检测发送控制 DSR output flow control
      public
      int fDtrControl;
      // DTR_CONTROL_DISABLE值将DTR置为OFF, DTR_CONTROL_ENABLE值将DTR置为ON, DTR_CONTROL_HANDSHAKE允许DTR"握手" DTR flow control type
      public
      int fDsrSensitivity;
      // 当该值为TRUE时DSR为OFF时接收的字节被忽略 DSR sensitivity
      public
      int fTXContinueOnXoff;
      // 指定当接收缓冲区已满,并且驱动程序已经发送出XoffChar字符时发送是否停止.TRUE时,在接收缓冲区接收到缓冲区已满的字节XoffLim且驱动程序已经发送出XoffChar字符中止接收字节之后,发送继续进行. FALSE时,在接收缓冲区接收到代表缓冲区已空的字节XonChar且驱动程序已经发送出恢复发送的XonChar之后,发送继续进行.XOFF continues Tx
      public
      int fOutX;
      // TRUE时,接收到XoffChar之后便停止发送接收到XonChar之后将重新开始 XON/XOFF out flow control
      public
      int fInX;
      // TRUE时,接收缓冲区接收到代表缓冲区满的XoffLim之后,XoffChar发送出去接收缓冲区接收到代表缓冲区空的XonLim之后,XonChar发送出去 XON/XOFF in flow control
      public
      int fErrorChar;
      // 该值为TRUE且fParity为TRUE时,用ErrorChar 成员指定的字符代替奇偶校验错误的接收字符 enable error replacement
      public
      int fNull;
      // eTRUE时,接收时去掉空(0值)字节 enable null stripping
      public
      int fRtsControl;
      // RTS flow control
      /*RTS_CONTROL_DISABLE时,RTS置为OFF
      RTS_CONTROL_ENABLE时, RTS置为ON
      RTS_CONTROL_HANDSHAKE时,
       当接收缓冲区小于半满时RTS为ON
        当接收缓冲区超过四分之三满时RTS为OFF
      RTS_CONTROL_TOGGLE时,
       当接收缓冲区仍有剩余字节时RTS为ON ,否则缺省为OFF*/
      public
      int fAbortOnError;
      // TRUE时,有错误发生时中止读和写操作 abort on error
      public
      int fDummy2;
      // 未使用 reserved
      public u
      int flags;

      public ushort wReserved;
      // 未使用,必须为0 not currently used
      public ushort XonLim;
      // 指定在XON字符发送这前接收缓冲区中可允许的最小字节数 transmit XON threshold
      public ushort XoffLim;
      // 指定在XOFF字符发送这前接收缓冲区中可允许的最小字节数 transmit XOFF threshold
      public byte ByteSize;
      // 指定端口当前使用的数据位 number of bits/byte, 4-8
      public byte Parity;
      // 指定端口当前使用的奇偶校验方法,可能为:EVENPARITY,MARKPARITY,NOPARITY,ODDPARITY 0-4=no,odd,even,mark,space
      public byte StopBits;
      // 指定端口当前使用的停止位数,可能为:ONESTOPBIT,ONE5STOPBITS,TWOSTOPBITS 0,1,2 = 1, 1.5, 2
      public
      char XonChar;
      // 指定用于发送和接收字符XON的值 Tx and Rx XON
      character
      public
      char XoffChar;
      // 指定用于发送和接收字符XOFF值 Tx and Rx XOFF
      character
      public
      char ErrorChar;
      // 本字符用来代替接收到的奇偶校验发生错误时的值 error replacement
      character
      public
      char EofChar;
      // 当没有使用二进制模式时,本字符可用来指示数据的结束 end of input
      character
      public
      char EvtChar;
      // 当接收到此字符时,会产生一个事件 received event
      character
      public ushort wReserved1;
      // 未使用 reserved;
      do not use
    }
    [StructLayout( LayoutKind.Sequential )]
    private struct COMMTIMEOUTs
    {
      public
      int ReadIntervalTimeout;

      public
      int ReadTotalTimeoutMultiplier;

      public
      int ReadTotalTimeoutConstant;

      public
      int WriteTotalTimeoutMultiplier;

      public
      int WriteTotalTimeoutConstant;
    }

    [StructLayout( LayoutKind.Sequential )]
    private struct OVERLAPPED
    {
      public
      int Internal;

      public
      int InternalHigh;

      public
      int Offset;

      public
      int OffsetHigh;

      public
      int hEvent;
    }
    [DllImport( "coredll.dll" )]
    private static extern
    int CreateFile(
    string lpFileName,
    // 要打开的串口名称
    u
    int dwDesiredAccess,
    // 指定串口的访问方式,一般设置为可读可写方式
    int dwShareMode,
    // 指定串口的共享模式,串口不能共享,所以设置为0
    int lpSecurityAttributes, // 设置串口的安全属性,WIN9X下不支持,应设为NULL
    int dwCreationDisposition,
    // 对于串口通信,创建方式只能为OPEN_EXISTING
    int dwFlagsAndAttributes,
    // 指定串口属性与标志,设置为FILE_FLAG_OVERLAPPED( 重叠I/O操作 ),指定串口以异步方式通信
    int hTemplateFile
    // 对于串口通信必须设置为NULL
    );
    [DllImport( "coredll.dll" )]
    private static extern bool GetCommState(
    int hFile, //通信设备句柄
    ref DCB lpDCB
    // 设备控制块DCB
    );
    [DllImport( "coredll.dll" )]
    private static extern bool BuildCommDCB(
    string lpDef, // 设备控制字符串
    ref DCB lpDCB
    // 设备控制块
    );
    [DllImport( "coredll.dll" )]
    private static extern bool SetCommState(
    int hFile, // 通信设备句柄
    ref DCB lpDCB
    // 设备控制块
    );
    [DllImport( "coredll.dll" )]
    private static extern bool GetCommTimeouts(
    int hFile,
    // 通信设备句柄 handle to comm device
    ref COMMTIMEOUTS lpCommTimeouts // 超时时间 time-out values
    );
    [DllImport( "coredll.dll" )]
    private static extern bool SetCommTimeouts(
    int hFile,
    // 通信设备句柄 handle to comm device
    ref COMMTIMEOUTS lpCommTimeouts // 超时时间 time-out values
    );
    [DllImport( "coredll.dll" )]
    private static extern bool ReadFile(
    int hFile,
    // 通信设备句柄 handle to file
    byte[] lpBuffer,
    // 数据缓冲区 data buffer
    int nNumberOfBytesToRead, // 多少字节等待读取 number of bytes to read
    ref
    int lpNumberOfBytesRead, // 读取多少字节 number of bytes read
    ref OVERLAPPED lpOverlapped
    // 溢出缓冲区 overlapped buffer
    );
    [DllImport( "coredll.dll" )]
    private static extern bool WriteFile(
    int hFile,
    // 通信设备句柄 handle to file
    byte[] lpBuffer,
    // 数据缓冲区 data buffer
    int nNumberOfBytesToWrite,
    // 多少字节等待写入 number of bytes to write
    ref
    int lpNumberOfBytesWritten, // 已经写入多少字节 number of bytes written
    ref OVERLAPPED lpOverlapped
    // 溢出缓冲区 overlapped buffer
    );
    [DllImport( "coredll.dll" )]
    private static extern bool CloseHandle(
    int hObject
    // handle to object
    );
    [DllImport( "coredll.dll" )]
    private static extern u
    int GetLastError( );

    public void Open( )
    {
      DCB dcbCommPort = new DCB( );
      COMMTIMEOUTS ctoCommPort = new COMMTIMEOUTS( );
      // 打开串口 OPEN THE COMM PORT.
      hComm = CreateFile( PortNum ,GENERIC_READ | GENERIC_WRITE,0, 0,OPEN_EXISTING,0,0 );
      // 如果串口没有打开,就打开 IF THE PORT CANNOT BE OPENED, BAIL OUT.
      if( hComm == INVALID_HANDLE_VALUE )
      {
        throw( new ApplicationException( "非法操作,不能打开串口!" ) );
      }
      // 设置通信超时时间 SET THE COMM TIMEOUTS.
      GetCommTimeouts( hComm,ref ctoCommPort );
      ctoCommPort.ReadTotalTimeoutConstant = ReadTimeout;
      ctoCommPort.ReadTotalTimeoutMultiplier = 0;
      ctoCommPort.WriteTotalTimeoutMultiplier = 0;
      ctoCommPort.WriteTotalTimeoutConstant = 0;
      SetCommTimeouts( hComm,ref ctoCommPort );
      // 设置串口 SET BAUD RATE, PARITY, WORD SIZE, AND STOP BITS.
      GetCommState( hComm, ref dcbCommPort );
      dcbCommPort.BaudRate=BaudRate;
      dcbCommPort.flags=0;
      //dcb.fBinary=1;
      dcbCommPort.flags|=1;
      if ( Parity>0 )
      {
        //dcb.fParity=1
        dcbCommPort.flags|=2;
      }
      dcbCommPort.Parity=Parity;
      dcbCommPort.ByteSize=ByteSize;
      dcbCommPort.StopBits=StopBits;
      if ( !SetCommState( hComm, ref dcbCommPort ) )
      {
        //u
        int ErrorNum=GetLastError( );
        throw( new ApplicationException( "非法操作,不能打开串口!" ) );
      }
      //unremark to see if setting took correctly
      //DCB dcbCommPort2 = new DCB( );
      //GetCommState( hComm, ref dcbCommPort2 );
      Opened = true;
    }

    public void Close( )
    {
      if ( hComm!=INVALID_HANDLE_VALUE )
      {
        CloseHandle( hComm );
      }
    }

    public byte[] Read( int NumBytes )
    {
      byte[] BufBytes;
      byte[] OutBytes;
      BufBytes = new byte[NumBytes];
      if ( hComm!=INVALID_HANDLE_VALUE )
      {
        OVERLAPPED ovlCommPort = new OVERLAPPED( );

        int BytesRead=0;
        ReadFile( hComm,BufBytes,NumBytes,ref BytesRead,ref ovlCommPort );
        try
        {
          OutBytes = new byte[BytesRead];
          Array.Copy( BufBytes,0,OutBytes,0,BytesRead );
        }
        catch
        {
          return BufBytes;
        }
      }
      else
      {
        throw( new ApplicationException( "串口未打开!" ) );
      }
      return OutBytes;
      //
      return BufBytes;
    }

    public void Write( byte[] WriteBytes )
    {
      if ( hComm!=INVALID_HANDLE_VALUE )
      {
        OVERLAPPED ovlCommPort = new OVERLAPPED( );

        int BytesWritten = 0;
        WriteFile( hComm,WriteBytes,WriteBytes.Length,ref BytesWritten,ref ovlCommPort );
      }
      else
      {
        throw( new ApplicationException( "串口未打开!" ) );
      }
    }

    public
    string GetGPS( string strGPS,
    string strFind )
    {
      ///从GPS中读取的数据中,找出想要的数据
      ///GPs
      string原始字符串,
      ///strFind要查找的内容,X:经度,Y:纬度,T:时间,V:速度,是数字从1开始,即以“,”分隔的位置
      ///返回查找到指定位置的字符串
      string handerStr="$GPRMC";
      //GPS串头
      int findHander=strGPS.IndexOf( handerStr );
      //看是否含有GPS串头
      if ( findHander<0 )
      {
        return "-1";
      }
      else
      {
        strGPS=strGPS.Sub
        string( findHander,strGPS.Length-findHander );

        string[] ArryTmp=strGPS.Split( ",".ToCharArray( ) );
        try
        {
          if( ArryTmp[2]=="V" )
          {
            return "V";
            //没有信号
          }
          else
          {
            switch( strFind )
            {
              case "X":
              return DM2DD( ArryTmp[5] );
              case "Y":
              return DM2DD( ArryTmp[3] );
              case "T":
              return T2Time( ArryTmp[9],ArryTmp[1] );
              case "V":
              return Convert.ToString( Convert.ToDouble( ArryTmp[7] )* 1.852 );
              default:
              return "V";
            }
          }
        }
        catch
        {
          return "V";
        }
      }
    }

    public
    string T2Time( string strDate,
    string strTime )
    {
      string dT="20"+strDate.Sub
      string( 4,2 )+"-"+strDate.Sub
      string( 2,2 )+"-"+strDate.Sub
      string( 0,2 );

      string TT=Convert.ToString( Convert.ToInt32( strTime.Sub
      string( 0,2 ) ) )+":"+strTime.Sub
      string( 2,2 )+":"+strTime.Sub
      string( 4,2 );
      DateTime T=Convert.ToDateTime( dT+" "+TT );
      T=T.AddHours( 8 );
      return T.ToString( );
    }

    public
    string DM2DD( string DegreeMinutes )
    {
      //转换NMEA协议的“度分”格式为十进制“度度”格式
      string sDegree;

      string sMinute;

      string sReturn="";
      if( DegreeMinutes.IndexOf( "." )==4 )
      {
        //DegreeMinutes = Replace( DegreeMinutes, ".", "" )
        //DM2DD = CDbl( Left( DegreeMinutes, 2 ) ) + CDbl( Left( CStr( CDbl( Right( DegreeMinutes, Len( DegreeMinutes ) - 2 ) ) / 60 ), 8 ) ) / 10000
        DegreeMinutes=DegreeMinutes.Replace( ".","" );
        double sDegree1=Convert.ToDouble( DegreeMinutes.Sub
        string( 0,2 ) );
        double sDegree2=Convert.ToDouble( DegreeMinutes.Sub
        string( 2,DegreeMinutes.Length-2 ) );

        string sTmp=Convert.ToString( sDegree2/60 );
        sDegree2=Convert.ToDouble( sTmp.Sub
        string( 0,sTmp.Length ) );
        sDegree2=sDegree2/10000;
        sDegree=Convert.ToString( sDegree1+sDegree2 );
        if( sDegree.Length>11 )
        sDegree=sDegree.Sub
        string( 0,11 );
        sReturn=sDegree;
      }
      else if( DegreeMinutes.IndexOf( "." )==5 )
      {
        //DegreeMinutes = Replace( DegreeMinutes, ".", "" )
        //DM2DD = CDbl( Left( DegreeMinutes, 2 ) ) + CDbl( Left( CStr( CDbl( Right( DegreeMinutes, Len( DegreeMinutes ) - 2 ) ) / 60 ), 8 ) ) / 10000
        DegreeMinutes=DegreeMinutes.Replace( ".","" );
        double sMinute1=Convert.ToDouble( DegreeMinutes.Sub
        string( 0,3 ) );
        double sMinute2=Convert.ToDouble( DegreeMinutes.Sub
        string( 3,DegreeMinutes.Length-2 ) );

        string sTmp=Convert.ToString( sMinute2/60 );
        sMinute2=Convert.ToDouble( sTmp.Sub
        string( 0,sTmp.Length ) );
        sMinute2=sMinute2/10000;
        sMinute=Convert.ToString( sMinute1+sMinute2 );
        if( sMinute.Length>10 )
        sMinute=sMinute.Sub
        string( 0,10 );
        sReturn=sMinute;
      }
      return sReturn;
    }

    public bool ScanPort( )
    {
      try
      {
        if ( Opened )
        {
          Close( );
          Open( );
        }
        else
        {
          Open( );
          //打开串口
        }
        byte[] bytRead=Read( 512 );
        Close( );
        if( Encoding.ASCII.GetString( bytRead,0,bytRead.Length ).IndexOf( "$GP" )>=0 )
        return true;
        else
        return false;
      }
      catch
      {
        return false;
      }
    }
  }
  class HexCon 
  {
    // 把十六进制字符串转换成字节型和把字节型转换成十六进制字符串 converter hex
    string to byte and byte to hex
    string 
    public static
    string ByteToString( byte[] InBytes )
    {
      string StringOut="";
      foreach ( byte InByte in InBytes )
      {
        StringOut=StringOut + String.Format( "
        {
          0:X2
        }
        ",InByte );
      }
      return StringOut;
    }

    public static byte[] StringToByte( string InString )
    {
      string[] ByteStrings;
      ByteStrings = InString.Split( " ".ToCharArray( ) );
      byte[] ByteOut;
      ByteOut = new byte[ByteStrings.Length-1];
      for ( int i = 0;
      i==ByteStrings.Length-1;
      i++ )
      {
        ByteOut[i] = Convert.ToByte( ( "0x" + ByteStrings[i] ) );
      }
      return ByteOut;
    }
  }
}

时间: 2025-01-30 17:31:08

用C#读取GPS数据的基类(适用于wince操作系统)的相关文章

基于SQLServer的数据层基类C#源码

server|sqlserver|数据 /***************************************************** * 文 件 名:DBObject.cs * 功能描述:定义数据层基类. * 创 建 人:夏春涛 xchuntao@163.com qq:23106676 * 创建时间:2004-08-11 11:05 *****************************************************/ using System;using

基于ODP的数据层基类C#源码

数据 #region usingusing System;using System.Configuration;using System.Data;using Oracle.DataAccess.Client;#endregion namespace WIS.Base.Data{ /// <summary> /// <table style="font-size:12px"> /// <tr><td><b>文 件 名</

ASP.NET创建自定义数据控制器基类

无论什么时候,你在写代码时都会发现其实你在一遍又一遍地编写着同样类型的代码,现在是时候停下来考虑一下你是否正在浪费者大量的时间.昨天,我发现在创建一个数据库驱动的ASP.NET MVC应用程序时,我的确处在这样一种情形中.我不得不为应用程序中的每一个数据库表进行标准的操作--显示数据.更新数据.插入数据.删除数据.一遍又一遍地编写完全相同的代码,这种可怕的现象赋予我灵感,让我写下了今天这篇ASP.NET MVC Tip. MVC控制器就是一个类(Visual Basic或C#类).既然是类,就可

SQLServer2000数据访问基类

server|server2000|sql|sqlserver|访问|数据 using System;using System.IO;using System.Data;using System.Data.SqlClient;using System.Configuration;using System.Collections; namespace SQLServerBase{    /// <summary>    ///内部类:存储过程的返回值记录类    /// </summary

Asp.Net 通用数据操作类 (附通用数据基类)第1/2页_实用技巧

文章内容为本站编辑,创作.你可以任意转载.发布.使用但请务必以明文标注文章原始出处及本声明 http://www.opent.cn  作者:浪淘沙此贴的方法会持续更新, 此文件要引用与数据操作的基类 using System; using System.Data; using System.Configuration; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.Web

Asp.Net 数据操作类(附通用数据基类)_实用技巧

using System; using System.Data; using System.Configuration; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; namespace EC {

MVC+LINQToSQL的Repository模式之(二)数据基类

namespace Data.TEST{    /// <summary>    /// 数据操作基类    /// </summary>    public abstract class TESTRepositoryBase    {        /// <summary>        /// 数据库基类        /// </summary>        protected Entity.TEST.LinqTESTDataContext _db

Entity Framework 实体框架的形成之旅--基类接口的统一和异步操作的实现(3)

在本系列的第一篇随笔<Entity Framework 实体框架的形成之旅--基于泛型的仓储模式的实体框架(1)>中介绍了Entity Framework 实体框架的一些基础知识,以及构建了一个简单的基于泛型的仓储模式的框架:在随笔<Entity Framework 实体框架的形成之旅--利用Unity对象依赖注入优化实体框架(2)>则持续优化这个仓储模式的实体框架,主要介绍业务逻辑层的构建,以及利用Unity和反射进行动态的对象注册.本篇主要介绍基类接口的统一和异步操作的实现等方

iOS数据持久化之二——归档与设计可存储化的数据模型基类

iOS数据持久化之二--归档与设计可存储化的数据模型基类 一.引言         在上一篇博客中,我们介绍了用plist文件进行数据持久化的方法.虽然简单易用,但随着开发的深入,你会发现,这种方式还是有很大的局限性.试想,如果我们可以将用户的登录返回信息模型,游戏中角色的属性信息模型进行直接的持久化存取,那是不是非常爽的事,幸运的是,我们可以通过归档,来设计一个这样的数据模型. 二.先来精通归档吧         归档也是iOS提供给开发者的一种数据存储的方式,事实上,几乎所有的数据类型都可以