关于手机串口通讯(100分)

  • 主题发起人 主题发起人 didi413
  • 开始时间 开始时间
D

didi413

Unregistered / Unconfirmed
GUEST, unregistred user!
1.比如发送 AT+CMGL=0 指令给手机,手机收到指令后就会将未读的短信内容发到串口,随后
对串口读数据就可以读到手机的响应信息吗? 2.手机响应信息的格式是怎样排列的?如何
分离响应信息各项内容?

 
串口程序我后来研究了好久,写了下面的代码,后台生成一个线程监听串口,不影响前台工作。效果很好,一直用于GPS仪器的数据接收。

unit frmComm;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ComCtrls,GeoUtils,GeoGPS;
const MAXBLOCK = 160;
type
TComm = record
idComDev : THandle;
fConnected : Boolean;
end;
TCommForm = class(TForm)
ComboBox1: TComboBox;
Button1: TButton;
StatusBar1: TStatusBar;
Button2: TButton;
ComboBox2: TComboBox;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
public
{ Public declarations }
end;
TCommThread = Class(TThread)
protected
procedure Execute;override;
public
constructor Create;
end;
var
CommForm: TCommForm;
CommHandle : THandle;
Connected : Boolean;
CommThread : TCommThread;
implementation
{$R *.DFM}
uses
frmMain,frmMdiMapView;
procedure TCommThread.Execute;
var
dwErrorFlags,dwLength : DWORD;
ComStat : PComStat;
fReadStat : Boolean;
InChar : Char;
AbIn : String;
XX,YY : double; file://经度、纬度
VID : string; file://车号
begin
while Connected do begin
GetMem(ComStat,SizeOf(TComStat));
ClearCommError(CommHandle, dwErrorFlags, ComStat);
if (dwErrorFlags > 0) then begin
PurgeComm(CommHandle,(PURGE_RXABORT and PURGE_RXCLEAR));
// return 0;
end;
dwLength := ComStat.cbInQue;
if (dwLength> 0) then begin
fReadStat := ReadFile(CommHandle, InChar, 1,dwLength, nil);
if (fReadStat) then begin
if (InChar < > Chr(13)) and (Length(abIn) < MAXBLOCK+5 ) then AbIn := AbIn + InChar
else begin
...
{接收完毕,}
end;//if (fReadStat> 0){
end; file://if (dwLength> 0){
FreeMem(ComStat);
end;{while}
end;
constructor TCommThread.Create;
begin
FreeOnTerminate := TRUE;
inherited Create(FALSE); file://Createsuspended = false
end;
//
procedure TCommForm.Button1Click(Sender: TObject);
var
CommTimeOut : TCOMMTIMEOUTS;
DCB : TDCB;
fRetVal : Boolean;
begin
StatusBar1.SimpleText := '连接中...';
CommHandle := CreateFile(PChar(ComboBox1.Text),GENERIC_READ,0,nil,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL
, 0);
if CommHandle = INVALID_HANDLE_VALUE then begin
StatusBar1.SimpleText := '连接失败';
Exit;
end;
StatusBar1.SimpleText := '已同端口 '+ ComboBox1.Text + ' 连接!';
CommTimeOut.ReadIntervalTimeout := MAXDWORD;
CommTimeOut.ReadTotalTimeoutMultiplier := 0;
CommTimeOut.ReadTotalTimeoutConstant := 0;
SetCommTimeouts(CommHandle, CommTimeOut);
GetCommState(CommHandle,DCB);
DCB.BaudRate := 9600;
DCB.ByteSize := 8;
DCB.Parity := NOPARITY;
DCB.StopBits := ONESTOPBIT;
fRetVal := SetCommState(CommHandle, DCB);
if (fRetVal) then begin
Connected := TRUE;
try
CommThread := TCommThread.Create;
except
Connected := FALSE;
CloseHandle(CommHandle);
fRetVal := FALSE;
StatusBar1.SimpleText := '线程建立失败';
Exit;
end;
end
else begin
Connected := FALSE;
CloseHandle(CommHandle);
end;
end;
procedure TCommForm.Button2Click(Sender: TObject);
begin
Connected := FALSE;
CloseHandle(CommHandle);
{终止线程}
CommThread.Terminate;
StatusBar1.SimpleText := '关闭端口'+ComboBox1.Text;
end;
procedure TCommForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Connected := FALSE;
CloseHandle(CommHandle);
StatusBar1.SimpleText := '关闭端口'+ComboBox1.Text;
end;
end.
 
我的问题主要是:程序要读取手机中的短信内容。当发送 AT+CMGL=0 后,手机是否就会将未读的短信内容发到串口。
 
didi413,
>>当发送 AT+CMGL=0 后,手机是否就会将未读的短信内容发到串口

会的
 
在 超级终端 中,我写入
AT+CMGS=14(发送内容长度) {按回车}
> (输入PDU码) {按ctrl+Z}

超级终端 提示 +CME ERROR:003

请问我输入哪里错了?正确是如何输入的?
 
请回答!请回答!
 
长度不可能小于18的(发一个字的长度就是18),另外你的pdu编码可能编错了,贴出来看看。
 
你的长度肯定不对,

不过ERROR 003 应该是还有别的错误,这样的错误我还没遇到过
 
上面两位兄弟说的是对的。
在超级终端中:输入PDU码后,接着在键盘上直接按 Ctrl+Z,已经可以发送了。

但我现在的问题是:在代码中 输入 'ATCMGL=0'+#13#10 (读取未读信息)时 在串口
中收不到任何字符。但输入 'AT'+#13#10 会有‘OK’,说明已连通,错误在于命令行
的结束标志。 结束标志 #13#10 为什么不对? 正确是什么?
 
楼主:以#13#10结束是没有错的,我以前做过,并且能收到手机发回的信息。
我想问题不是在这里,我发送的是At+CMGL=4#13#10。用的是西门子的手机,
你好好查一查你的程序吧。

 
TO:yetxr

请帮忙看下哪里错了?
procedure TfSMSManager.BitBtn2Click(Sender: TObject);
var
ATInfo_str:string;
begin

ATInfo_str:=Edit1.Text; {Edit1.Text的内容为 ‘AT+CMGL=0’}
ATInfo_str:=ATInfo_str+#13#10;
Comm1.WriteCommData(pATInfo_str,SizeOf(pATInfo_str)) ;

Memo1.Lines.Add('Send:'+' '+ATInfo_str);
Memo1.Invalidate;
end;
其中 Comm1.WriteCommData(pATInfo_str,SizeOf(pATInfo_str)) ;为SPCOMM的函数原形为
function TComm.WriteCommData( pDataToWrite: PChar; dwSizeofDataToWrite: Word ): Boolean;

 
不好意思上面的
Comm1.WriteCommData(pATInfo_str,SizeOf(pATInfo_str)) ;
应改为
Comm1.WriteCommData(PChar(ATInfo_str),SizeOf(ATInfo_str)) ;
 
SizeOf不对吧,应该是Length(pAtInfo_str)
 
我已把SIZEOF 改为 LENGTH 了,谢谢chenxz。
我在程序中发 'AT+CMGS=17'+#13#10+'0891683108501905F011000D91683166060836F70008000265E9'+^Z+#13#10;
有错误提示 +CMS ERROR:038

而在超级终端发 'AT+CMGS=17' {按回车键}
出现 ‘>’后在 粘贴上'0891683108501905F011000D91683166060836F70008000265E9' {按CTRL+Z}
就可以发送。
我的代码错在哪里了?
 
应该分成两部分来发送,先是发送'AT+CMGS=17'+#13#10,然后等待“>”返回后再发送
pdu编码‘0891683108501905F011000D91683166060836F70008000265E9’+chr(26)就可以了。
 
先'AT+CMGS=17'+#13#10,然后sleep(100),你再发pdu编码
 
谢谢!结束此帖
 
各位你们说的超级终端指的是什么?怎么用delphi编发短消息的程序啊?有没有代码参考一下啊?
 
后退
顶部