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

📄 sms_pudunit.pas

📁 用串口通信实现手机短信的收发的例子(带源码)
💻 PAS
📖 第 1 页 / 共 3 页
字号:
{ SMSPDUproc }
/// <summary>
/// 短信收发控件
/// </summary>
/// <author> agamem </author>
/// <date> 2005-7-12 </date>
unit SMS_PUDUnit;
interface   
uses
  Windows,Messages,SysUtils,Variants,Classes,Graphics,Controls,Forms,Dialogs,SPComm,ExtCtrls,StrUtils;//,csintf;
type
  /// <summary>
  /// 用户信息编码方式
  /// td7_Bit : 7-bit编码,只能用于发送英文字符,160个字符
  /// td8_Bit : 8-bit编码,可用于发送透明数据
  /// tdUCS2  : Unicode编码,可发送中英文,限制在70个字符
  /// </summary>
  TTP_DCS = (td7_Bit, td8_Bit, tdUCS2);
  /// <summary>
  /// 短信模块控制状态
  /// </summary>
  TSMSState = (NORMAL, ATE, ATCMGF, ATCNMI, ATCMGS_1, ATCMGS_2,ATCMGR,ATCMGD);
  /// <summary>
  /// 数据监视事件
  /// </summary>
  TSMSMonitor=procedure(Sender:TObject;RevString:string) of object;
  /// <summary>
  /// 接收短信通知事件
  /// </summary>
  TSMSRev=procedure(Sender:TObject;mSMSC,mPhoneID,mInfo:string;mGTime:TDateTime) of object;
  /// <summary>
  /// 短信控件
  /// </summary>
  TSMSPDUproc = class(TComponent)
  private
    /// <summary>
    /// 串口控件
    /// </summary>
    SMScomm:TComm;
    /// <summary>
    /// 超时判断计时器
    /// </summary>
    OTTimer:TTimer;
    /// <summary>
    /// PDU包信息长度
    /// </summary>
    FCMGSLen:string;
    /// <summary>
    /// 用户信息编码模式(短消息编码模式)
    /// </summary>
    FTP_DCS:TTP_DCS;
    /// <summary>
    /// 目标号码
    /// </summary>
    FTP_DA:string;
    /// <summary>
    /// 短消息中心号码
    /// </summary>
    FSMSC:string;
    /// <summary>
    /// 透明数据短消息
    /// </summary>
    FTP_UDByte:array of Byte;
    /// <summary>
    /// 字符数据短消息
    /// </summary>
    FTP_UDStr:string;
    /// <summary>
    /// PUD包
    /// </summary>
    FPUDStr:string;
    /// <summary>
    /// 波特率
    /// </summary>
    FBaudRate:DWORD;
    /// <summary>
    /// 串口号
    /// </summary>
    FCommName:string;
    /// <summary>
    /// 数据位
    /// </summary>
    FByteSize:TByteSize;
    /// <summary>
    /// 校验位
    /// </summary>
    FParity:TParity;
    /// <summary>
    /// 停止位
    /// </summary>
    FStopBits:TStopBits;
    /// <summary>
    /// 激活控件
    /// </summary>
    FActive:Boolean;
    /// <summary>
    /// 当前收到短消息的编号
    /// </summary>
    FCurrSMSIndex:Integer;
    /// <summary>
    /// 当前短消息机的状态
    /// </summary>
    CurrState:TSMSState;
    /// <summary>
    /// 超时/错误 重发计数
    /// </summary>
    ReSendCount:Integer;
    /// <summary>
    /// 超时判断计数
    /// </summary>
    tver:Integer;
    /// <summary>
    /// 串口接收监视
    /// </summary>
    FOnRevMonitor: TSMSMonitor;
    /// <summary>
    /// 串口发送监视
    /// </summary>
    FOnSndMonitor: TSMSMonitor;
    /// <summary>
    /// 接收短消息后是否删除短消息
    /// </summary>
    FDelAfterRev: Boolean;
    /// <summary>
    /// 收到短消息事件
    /// </summary>
    FOnReceiveSMS: TSMSRev;
    procedure setTP_DCS(const Value:TTP_DCS);
    procedure setSMSC(const Value:string);
    procedure setTP_DA(const Value:string);
    /// <summary>
    /// 获取PUD包
    /// </summary>
    function getPUDStr:string;
    procedure SetBaudRate(const Value:DWORD);
    procedure SetByteSize(const Value:TByteSize);
    procedure SetStopBits(const Value:TStopBits);
    procedure SetCommName(const Value:string);
    procedure SetParity(const Value:TParity);
    procedure setActive(const Value:Boolean);
    /// <summary>
    /// 串口接收事件
    /// </summary>
    procedure SMSReceiveData(Sender:TObject; Buffer:Pointer;
      BufferLength:Word);
    /// <summary>
    /// 初始化短信机
    /// </summary>
    procedure resetSMS();
    /// <summary>
    /// 数据写入串口
    /// </summary>
    procedure sendStrToComm(str:string);
    /// <summary>
    /// 超时计数器事件
    /// </summary>
    procedure OTTimerTimer(Sender:TObject);
    /// <summary>
    /// PDU包解码
    /// </summary>
    procedure DecodePUD(s:string);
  protected

  public

    constructor Create(AOwner:TComponent); override;
    destructor Destroy; override;
    /// <summary>
    /// 设置发送的内容 透明数据
    /// </summary>
    procedure setTP_UD(value:array of Byte); overload;
    /// <summary>
    /// 设置发送的内容 字符数据
    /// </summary>
    procedure setTP_UD(value:string); overload;
    /// <summary>
    /// 发送消息
    /// </summary>
    procedure SendSM; overload;
    /// <summary>
    /// 发送消息
    /// </summary>
    procedure SendSM(mTP_DA,Info:string);overload;
  published
   /// <summary>
   ///用户信息编码方式(TP-DCS)
   /// </summary>
    property TP_DCS:TTP_DCS read FTP_DCS write setTP_DCS;
    /// <summary>
    /// SMSC地址,短消息中心号码
    /// </summary>
    property SMSC:string read FSMSC write setSMSC;
    /// <summary>
    /// 目标地址(TP-DA),目标号码
    /// </summary>
    property TP_DA:string read FTP_DA write setTP_DA;
    /// <summary>
    /// 取得PUD包
    /// </summary>
    property PUDStr:string read getPUDStr;
    /// <summary>
    /// PUD包长度
    /// </summary>
    property CMGSLen:string read FCMGSLen;
    /// <summary>
    /// 串口
    /// </summary>
    property CommName:string read FCommName write SetCommName;
    /// <summary>
    /// 波特率
    /// </summary>
    property BaudRate:DWORD read FBaudRate write SetBaudRate;
    /// <summary>
    /// 数据位
    /// </summary>
    property ByteSize:TByteSize read FByteSize write SetByteSize;
    /// <summary>
    /// 校验
    /// </summary>
    property Parity:TParity read FParity write SetParity;
    /// <summary>
    /// 停止位
    /// </summary>
    property StopBits:TStopBits read FStopBits write SetStopBits;
    /// <summary>
    /// 激活短消息控件
    /// </summary>
    property Active:Boolean read FActive write setActive;
    /// <summary>
    /// 回收数据监视
    /// </summary>
    property OnRevMonitor:TSMSMonitor read FOnRevMonitor write FOnRevMonitor;
    /// <summary>
    /// 发送数据监视
    /// </summary>
    property OnSndMonitor:TSMSMonitor read FOnSndMonitor write FOnSndMonitor;
    /// <summary>
    /// 错误信息
    /// </summary>
    property OnError:TSMSMonitor read FOnSndMonitor write FOnSndMonitor;
    /// <summary>
    /// 读出短消息后删除
    /// </summary>
    property DelAfterRev:Boolean read FDelAfterRev write FDelAfterRev;
    /// <summary>
    /// 收到短消息后触发事件
    /// </summary>
    property OnReceiveSMS:TSMSRev read FOnReceiveSMS write FOnReceiveSMS;
  end;
procedure Register;
implementation

{ SMSPDUproc }
/// <summary>
/// 延时
/// </summary>
/// <param name="MSecs">需要延时的毫秒</param>
procedure Delay(MSecs: Longint);
//延时函数,MSecs单位为毫秒(千分之1秒)
var
    FirstTickCount, Now: Longint;
begin
    FirstTickCount := GetTickCount();
    repeat
        Application.ProcessMessages;
        Now := GetTickCount();
    until (Now - FirstTickCount >= MSecs) or (Now < FirstTickCount);
end;
function GB5ToUniCode(Value:WideString):string;
var
  I, Len:Integer;
  S:string;
begin
  Result := '';
  Len := Length(Value);
  I := 1;
  while I <= Len do
  begin
    FmtStr(S, '%4.4X', [ord(Value[I])]); //BCD转换
    Result := Result + S;
    Inc(I);
  end;
end;
//******************************************************************************
// Function/Procedure : HexToInt
// Purpose            : 把十六进制转换成十进制
// Inputs             : 十六进制字符
// Return             : 十进制数
//******************************************************************************
function HexToInt(HexStr:String):Integer;
begin
  Result:=StrToInt('$'+HexStr);
end;
//******************************************************************************
// Function/Procedure : UniCodeToGB5
// Purpose            : 把十六进制的字符数组转换成UNICODE字符
// Inputs             : 十六进制的字符数组
// Return             : UNICODE字符
//******************************************************************************
function UniCodeToGB5(s:String):WideString;
var
  P:PWord;
  I,RealLen:Integer;
  sStr:WideChar;
begin
  New(p);
  RealLen:=Length(s) div 4; //计算UNICODE真实长度
  for I:=0 to RealLen - 1 do begin

    P^:=HexToInt(Copy(s,4*I+1,4));
    Move(P^,sStr,2);
    Result:=Result+sStr;
  end;
  Dispose(P);
end;
//******************************************************************************
// Function/Procedure : ChangeLeftAndRight
// Purpose            : 将一个字符串在位置上进行奇数位与偶数
//                      位的交换,字符串长度为奇数位时自动补F
// Inputs             : 字符串
// Return             : 字符串
//******************************************************************************

function ChangeLeftAndRight(Value:string):string;
var
  I:Integer;
  S:Char;
begin
  Result := Trim(Value);
  if Length(Result) = 0 then Exit;
  if Length(Result) mod 2 = 1 then Result := Result + 'F';

  I := 1;
  while I < Length(Result) do begin
    S := Result[I];
    Result[I] := Result[I + 1];
    Result[I + 1] := S;
    I := I + 2;
  end;
end;
//******************************************************************************
// Function/Procedure : ResumeOrder
// Purpose            : ChangeOrder反向操作
// Inputs             : 字符串
// Return             : 字符串
//******************************************************************************
function ResumeOrder(OriStr:String):String;
var
  I:Integer;
  sStr:String;
begin
  sStr:='';
  for i:=1 to (Length(OriStr) Div 2) do
      sStr:=sStr+OriStr[I*2]+OriStr[I*2-1];
  Result:=StringReplace(sStr,'F','',[rfReplaceAll]);
end;

function gsmEncode7bit(pSrc:string; nSrcLength:Integer):string;
var
  nSrc:Integer; // 源字符串的计数值

  nChar:Integer; // 当前正在处理的组内字符字节的序号,范围是0-7
  nLeft:byte; // 上一字节残余的数据
  tmpChar:Byte;
  procChar:byte;
  s, pDst:string;
  i:Integer;
begin

  // 计数值初始化
  nSrc := 0;
  nLeft := 0;
  // 将源串每8个字节分为一组,压缩成7个字节
  // 循环该处理过程,直至源串被处理完
  // 如果分组不到8字节,也能正确处理
  i := 1;
  pDst := '';
  while (nSrc <= nSrcLength) do
  begin
    // 取源字符串的计数值的最低3位
    nChar := nSrc and 7;

    // 处理源串的每个字节
    if (nChar = 0) then
    begin
      // 组内第一个字节,只是保存起来,待处理下一个字节时使用
      nLeft := Byte(pSrc[i]);
    end
    else
    begin
      // 组内其它字节,将其右边部分与残余数据相加,得到一个目标编码字节
      procChar := Byte(pSrc[i]);
      tmpChar := (procChar shl (8 - nChar)) or nLeft;
      fmtstr(s, '%2.2X', [tmpChar]);
      pDst := pDst + s;

⌨️ 快捷键说明

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