//********************************************************* //该函数接收1个字符,转换成功后输出相应的数,否则输出-1 //********************************************************* function Hex(c: char): Integer; var x: Integer; begin if (Ord(c) >= Ord('0')) and (Ord(c) <= Ord('9')) then x:= Ord(c) - Ord('0') else if (Ord(c) >= Ord('a')) and (Ord(c) <= Ord('f')) then x:= Ord(c) - Ord('a') + 10 else if (Ord(c) >= Ord('A')) and (Ord(c) <= Ord('F')) then x:= Ord(c) - Ord('A') + 10 else x:= -1; //输入错误 Result:= x; end;//******************************************************************* //该函数接收1~2个,字符转换成功后输出对应16进制数的值,否则输出-1 //******************************************************************* function HexToInt(Str: string): Integer; var tmpInt1, tmpInt2: Integer; begin if Length(Str) = 1 then begin Result:= Hex(Str[1]); end else if Length(Str) = 2 then begin tmpInt1:= Hex(Str[1]); tmpInt2:= Hex(Str[2]); if (tmpInt1 = -1) or (tmpInt2 = -1) then Result:= -1 else Result:= tmpInt1 * 16 + tmpInt2; end else Result:= -1; //输入错误,转换失败 end;//**************************** //字符串转换成16进制字符串 //**************************** function StrToHexStr(const S: string): string; var i: Integer; begin for i:= 1 to Length(S) do begin if i = 1 then Result:= IntToHex(Ord(S[1]), 2) else Result:= Result + ' ' + IntToHex(Ord(S[i]), 2); end; end;//*************************** //该函数去掉字符串中所有空格 //*************************** function TrimAll(Str: string): string; var mLen, i: Integer; begin mLen:= Length(Str); //初始化返回值 Result:= ''; for i:= 0 to mLen do begin //是空格就去掉 if Str[i] = '' then Continue; Result:= Result + Str[i]; end; end;//***************** //程序的初始化 //***************** procedure TFrmMain.FormCreate(Sender: TObject); begin MSComm.InBufferSize:= 0; MSComm.OutBufferSize:= 0; CmbComPort.ItemIndex:= 0; HexRecv:= False; RXNum:= 0; TXNum:= 0; CheckHexRecv.Checked:= True; CheckHexSend.Checked:= True; ShpSerialPort.Brush.Color:= clRed; Panel1.Enabled:= True; end;//打开或者关闭串口,并变换指示灯的状态 procedure TFrmMain.BtnOpenPortClick(Sender: TObject); var ComSetting: string;begin if not MSComm.PortOpen then begin //打开串口 MSComm.CommPort:= CmbComPort.ItemIndex + 1; //默认值为 '4800,e,8,1' ComSetting:= CmbBaudSpeed.Text; ComSetting:= ComSetting + ',' + CmbParityBits.Text; ComSetting:= ComSetting + ',' + CmbDataBits.Text; ComSetting:= ComSetting + ',' + CmbStopBits.Text; MSComm.Settings:= ComSetting; MSComm.PortOpen:= True; //变换各个组件的状态 ShpSerialPort.Brush.Color:= clLime; //指示灯变绿 BtnOpenPort.Caption:= '关闭串口'; end else begin //关闭串口 //变换各个组件的状态 MSComm.PortOpen:= False; ShpSerialPort.Brush.Color:= clRed; //指示灯变红 Panel1.Enabled:= True; BtnOpenPort.Caption:= '打开串口'; end; end;//开启定时器,定时发送数据 procedure TFrmMain.CheckAutoSendClick(Sender: TObject); begin if CheckAutoSend.Checked then if EdtSend.Text = '' then begin ShowMessage('请输入要发送的命令!'); CheckAutoSend.Checked:= False; EdtSend.SetFocus; end else begin Timer.Interval:= StrToInt(EdtTimeInterval.Text); Timer.Enabled:= True; end else begin Timer.Enabled:= False; end; end;//处理控件的该事件,获取底层交换的数据和连线的状态 procedure TFrmMain.MSCommComm(Sender: TObject); var i, InputLen: Integer; tmpInt: Integer; tmpvar: Variant; InputStr, RecvStr: string; begin InputLen:= 0; if MSComm.CommEvent = 2 then begin InputLen:= MSComm.InBufferCount; //接收二进制数据,转换为十六进制显示 if HexRecv then begin tmpvar:= MSComm.Input; InputStr:= ''; for i:= 0 to InputLen - 1 do begin tmpInt:= tmpvar[i]; InputStr:= InputStr + UpperCase(IntToHex(tmpInt, 2)) + #32; end; end //直接接收字符 else begin InputStr:= MSComm.Input; end; MemRecv.Text:= MemRecv.Text + InputStr; end; //加入数据显示模块 RecvStr:= MemRecv.Text; RXNum:= RXNum + InputLen; ShowRX; end;//设置MSComm控件的数据接收的方式 procedure TFrmMain.CheckHexRecvClick(Sender: TObject); begin if CheckHexRecv.Checked then begin MSComm.InputMode:= 1; HexRecv:= True; end else begin MSComm.InputMode:= 0; HexRecv:= False; end; end;procedure TFrmMain.ShowRX; begin StatusBar.Panels[1].Text:= 'RX:' + IntToStr(RXNum); end;//设置参数HexSend的值,以告诉程序如何发送数据 procedure TFrmMain.CheckHexSendClick(Sender: TObject); begin HexSend:= CheckHexSend.Checked; end;//发送数据 procedure TFrmMain.BtnSendClick(Sender: TObject); var Len: Integer; i, Count, MaxCount, tmpInt: Integer; tmpvar: Variant; tmpStr, Output: string; begin Len:= 0; Count:= 1; MaxCount:= 1; if not MSComm.PortOpen then begin ShowMessage('没有打开串口!'); Exit; end else begin //发送二进制数,需要使用Variant变量矩阵,矩阵大小自动调节 if HexSend then begin Output:= EdtSend.Text; Len:= Length(Output); if Len > 0 then begin i:= 1; //创建一个Variant数组 tmpvar:= VarArrayCreate([1, 1], varByte); while (i < Len) do begin //转换为16进制 tmpStr:= Copy(Output, i, 2); tmpStr:= LowerCase(tmpStr); tmpInt:= HexToInt(tmpStr); if tmpInt = -1 then begin ShowMessage('发送的数据格式有问题!'); Exit; end else begin if Count = (MaxCount + 1) then begin Inc(MaxCount); //增大Variant数组 VarArrayRedim(tmpvar, MaxCount); //Resizes a Variant Array end; tmpvar[Count]:= tmpInt; Inc(Count); end; i:= i + 2; end; MSComm.Output:= tmpvar; end end else MSComm.Output:= EdtSend.Text; end; TXNum:= TXNum + Len div 2; ShowTX; end;procedure TFrmMain.ShowTX; begin StatusBar.Panels[2].Text:= 'TX:' + IntToStr(TXNum); end;//清空数据显示区 procedure TFrmMain.BtnClearClick(Sender: TObject); begin MemRecv.Text:= ''; end;//定时器在指定的事件内触发该事件,实现数据的定时发送 procedure TFrmMain.TimerTimer(Sender: TObject); begin //如果串口已经打开,则发送数据 if MSComm.PortOpen then BtnSendClick(Sender); end;//清空发送区后重新填写 procedure TFrmMain.BtnReFillClick(Sender: TObject); begin EdtSend.Text:= ''; EdtSend.SetFocus; end;procedure TFrmMain.TimerStatusTimer(Sender: TObject); var tmpTime: string; begin tmpTime:= DateTimeToStr(Now()); StatusBar.Panels[3].Text:= '今天是:' + DateToStr(Date()) + #32 + #32 + '当前时间为:' + Copy(tmpTime, 11, 9); end;procedure TFrmMain.BtnStopShowClick(Sender: TObject); beginend;end.
//*********************************************************
//该函数接收1个字符,转换成功后输出相应的数,否则输出-1
//*********************************************************
function Hex(c: char): Integer;
var
x: Integer;
begin
if (Ord(c) >= Ord('0')) and (Ord(c) <= Ord('9')) then
x:= Ord(c) - Ord('0')
else if (Ord(c) >= Ord('a')) and (Ord(c) <= Ord('f')) then
x:= Ord(c) - Ord('a') + 10
else if (Ord(c) >= Ord('A')) and (Ord(c) <= Ord('F')) then
x:= Ord(c) - Ord('A') + 10
else
x:= -1; //输入错误
Result:= x;
end;//*******************************************************************
//该函数接收1~2个,字符转换成功后输出对应16进制数的值,否则输出-1
//*******************************************************************
function HexToInt(Str: string): Integer;
var
tmpInt1, tmpInt2: Integer;
begin
if Length(Str) = 1 then
begin
Result:= Hex(Str[1]);
end
else if Length(Str) = 2 then
begin
tmpInt1:= Hex(Str[1]);
tmpInt2:= Hex(Str[2]);
if (tmpInt1 = -1) or (tmpInt2 = -1) then
Result:= -1
else
Result:= tmpInt1 * 16 + tmpInt2;
end
else
Result:= -1; //输入错误,转换失败
end;//****************************
//字符串转换成16进制字符串
//****************************
function StrToHexStr(const S: string): string;
var
i: Integer;
begin
for i:= 1 to Length(S) do
begin
if i = 1 then
Result:= IntToHex(Ord(S[1]), 2)
else
Result:= Result + ' ' + IntToHex(Ord(S[i]), 2);
end;
end;//***************************
//该函数去掉字符串中所有空格
//***************************
function TrimAll(Str: string): string;
var
mLen, i: Integer;
begin
mLen:= Length(Str);
//初始化返回值
Result:= '';
for i:= 0 to mLen do
begin
//是空格就去掉
if Str[i] = '' then
Continue;
Result:= Result + Str[i];
end;
end;//*****************
//程序的初始化
//*****************
procedure TFrmMain.FormCreate(Sender: TObject);
begin
MSComm.InBufferSize:= 0;
MSComm.OutBufferSize:= 0;
CmbComPort.ItemIndex:= 0;
HexRecv:= False;
RXNum:= 0;
TXNum:= 0;
CheckHexRecv.Checked:= True;
CheckHexSend.Checked:= True;
ShpSerialPort.Brush.Color:= clRed;
Panel1.Enabled:= True;
end;//打开或者关闭串口,并变换指示灯的状态
procedure TFrmMain.BtnOpenPortClick(Sender: TObject);
var
ComSetting: string;begin
if not MSComm.PortOpen then
begin
//打开串口
MSComm.CommPort:= CmbComPort.ItemIndex + 1;
//默认值为 '4800,e,8,1'
ComSetting:= CmbBaudSpeed.Text;
ComSetting:= ComSetting + ',' + CmbParityBits.Text;
ComSetting:= ComSetting + ',' + CmbDataBits.Text;
ComSetting:= ComSetting + ',' + CmbStopBits.Text;
MSComm.Settings:= ComSetting;
MSComm.PortOpen:= True;
//变换各个组件的状态
ShpSerialPort.Brush.Color:= clLime; //指示灯变绿
BtnOpenPort.Caption:= '关闭串口';
end
else
begin
//关闭串口
//变换各个组件的状态
MSComm.PortOpen:= False;
ShpSerialPort.Brush.Color:= clRed; //指示灯变红
Panel1.Enabled:= True;
BtnOpenPort.Caption:= '打开串口';
end;
end;//开启定时器,定时发送数据
procedure TFrmMain.CheckAutoSendClick(Sender: TObject);
begin
if CheckAutoSend.Checked then
if EdtSend.Text = '' then
begin
ShowMessage('请输入要发送的命令!');
CheckAutoSend.Checked:= False;
EdtSend.SetFocus;
end
else
begin
Timer.Interval:= StrToInt(EdtTimeInterval.Text);
Timer.Enabled:= True;
end
else
begin
Timer.Enabled:= False;
end;
end;//处理控件的该事件,获取底层交换的数据和连线的状态
procedure TFrmMain.MSCommComm(Sender: TObject);
var
i, InputLen: Integer;
tmpInt: Integer;
tmpvar: Variant;
InputStr, RecvStr: string;
begin
InputLen:= 0;
if MSComm.CommEvent = 2 then
begin
InputLen:= MSComm.InBufferCount; //接收二进制数据,转换为十六进制显示
if HexRecv then
begin
tmpvar:= MSComm.Input;
InputStr:= '';
for i:= 0 to InputLen - 1 do
begin
tmpInt:= tmpvar[i];
InputStr:= InputStr + UpperCase(IntToHex(tmpInt, 2)) + #32;
end;
end
//直接接收字符
else
begin
InputStr:= MSComm.Input;
end;
MemRecv.Text:= MemRecv.Text + InputStr;
end;
//加入数据显示模块
RecvStr:= MemRecv.Text;
RXNum:= RXNum + InputLen;
ShowRX;
end;//设置MSComm控件的数据接收的方式
procedure TFrmMain.CheckHexRecvClick(Sender: TObject);
begin
if CheckHexRecv.Checked then
begin
MSComm.InputMode:= 1;
HexRecv:= True;
end
else
begin
MSComm.InputMode:= 0;
HexRecv:= False;
end;
end;procedure TFrmMain.ShowRX;
begin
StatusBar.Panels[1].Text:= 'RX:' + IntToStr(RXNum);
end;//设置参数HexSend的值,以告诉程序如何发送数据
procedure TFrmMain.CheckHexSendClick(Sender: TObject);
begin
HexSend:= CheckHexSend.Checked;
end;//发送数据
procedure TFrmMain.BtnSendClick(Sender: TObject);
var
Len: Integer;
i, Count, MaxCount, tmpInt: Integer;
tmpvar: Variant;
tmpStr, Output: string;
begin
Len:= 0;
Count:= 1;
MaxCount:= 1;
if not MSComm.PortOpen then
begin
ShowMessage('没有打开串口!');
Exit;
end
else
begin
//发送二进制数,需要使用Variant变量矩阵,矩阵大小自动调节
if HexSend then
begin
Output:= EdtSend.Text;
Len:= Length(Output);
if Len > 0 then
begin
i:= 1;
//创建一个Variant数组
tmpvar:= VarArrayCreate([1, 1], varByte);
while (i < Len) do
begin
//转换为16进制
tmpStr:= Copy(Output, i, 2);
tmpStr:= LowerCase(tmpStr);
tmpInt:= HexToInt(tmpStr);
if tmpInt = -1 then
begin
ShowMessage('发送的数据格式有问题!');
Exit;
end
else
begin
if Count = (MaxCount + 1) then
begin
Inc(MaxCount);
//增大Variant数组
VarArrayRedim(tmpvar, MaxCount); //Resizes a Variant Array
end;
tmpvar[Count]:= tmpInt;
Inc(Count);
end;
i:= i + 2;
end;
MSComm.Output:= tmpvar;
end
end
else
MSComm.Output:= EdtSend.Text;
end;
TXNum:= TXNum + Len div 2;
ShowTX;
end;procedure TFrmMain.ShowTX;
begin
StatusBar.Panels[2].Text:= 'TX:' + IntToStr(TXNum);
end;//清空数据显示区
procedure TFrmMain.BtnClearClick(Sender: TObject);
begin
MemRecv.Text:= '';
end;//定时器在指定的事件内触发该事件,实现数据的定时发送
procedure TFrmMain.TimerTimer(Sender: TObject);
begin
//如果串口已经打开,则发送数据
if MSComm.PortOpen then
BtnSendClick(Sender);
end;//清空发送区后重新填写
procedure TFrmMain.BtnReFillClick(Sender: TObject);
begin
EdtSend.Text:= '';
EdtSend.SetFocus;
end;procedure TFrmMain.TimerStatusTimer(Sender: TObject);
var
tmpTime: string;
begin
tmpTime:= DateTimeToStr(Now());
StatusBar.Panels[3].Text:= '今天是:' + DateToStr(Date()) + #32 + #32 +
'当前时间为:' + Copy(tmpTime, 11, 9);
end;procedure TFrmMain.BtnStopShowClick(Sender: TObject);
beginend;end.
另外可以参考国防科技大学huangxiaobing?写的一个控件。