📄 dcetest.cpp
字号:
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "DCETEST.h"
#include "Api232.h" //需要将"api232.lib"手工加入项目中
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
int CommPort,Baud=B9600,DelayTime=200;
int l;
char Senddata[205];
AnsiString buff;
bool Len=true;
void Rece(int);
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
int state;
CommPort=2;
state=sio_open(CommPort);
if (state<0)
{
//Application->MessageBox("在打开串口COM2时出现错误","不能打开串口",MB_OK);
CommPort=1;
state=sio_open(CommPort);
if (state<0)
{
//Application->MessageBox("在打开串口COM1和COM2时出现错误","不能打开串口",MB_OK);
Send->Text="COM1、COM2均被其它程序所打开,请关闭程序!";
Send->Enabled=false;
return;
}
else
ComboBox2->Text="COM1";
}
sio_ioctl(CommPort,B9600, P_NONE|BIT_8|STOP_1);
sio_flush(CommPort,2);
sio_cnt_irq(CommPort,Rece,1); //win95/NT中中断字符个数只能为"1"
buff=ComboBox2->Text; //DOS/WIN3X中个数不限于"1"
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ComboBox2Change(TObject *Sender)
{
sio_close(CommPort);
int state;
int PortBuff;
AnsiString str;
PortBuff=CommPort;
str=ComboBox2->Text; //此时为改变后的内容
str=str.Delete(1,3); //取出COM口号。
CommPort=StrToInt(str);
state=sio_open(CommPort);
if (state<0)
{
ShowMessage("串口已被其它程序打开,\n不存在或有其它故障!");//系统默认“PORT ALREDRY OPEN!”的提示
CommPort=PortBuff;
sio_open(CommPort);
sio_ioctl(CommPort,B9600, P_NONE|BIT_8|STOP_1);
sio_flush(CommPort,2);
sio_cnt_irq(CommPort,Rece,1);
Timer1->Enabled=true;
}
else
{
buff=ComboBox2->Text;
sio_ioctl(CommPort,B9600, P_NONE|BIT_8|STOP_1);
sio_flush(CommPort,2);
sio_cnt_irq(CommPort,Rece,1);
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ComboBox1Change(TObject *Sender)
{
int str;
AnsiString rate;
rate=ComboBox1->Text;
str=StrToInt(rate);
//Baud=StrToInt('B'+rate);含有字母的整形值不易赋值.
switch (str)
{
case 110:
//sio_ioctl(CommPort,B110, P_NONE|BIT_8|STOP_1);
Baud=B110;
break;
case 300:
//sio_ioctl(CommPort,B300, P_NONE|BIT_8|STOP_1);
Baud=B300;
break;
case 600:
Baud=B600;
//sio_ioctl(CommPort,B600, P_NONE|BIT_8|STOP_1);
break;
case 1200:
Baud=B1200;
//sio_ioctl(CommPort,B1200, P_NONE|BIT_8|STOP_1);
break;
case 2400:
Baud=B2400;
//sio_ioctl(CommPort,B2400, P_NONE|BIT_8|STOP_1);
break;
case 4800:
Baud=B4800;
//sio_ioctl(CommPort,B4800, P_NONE|BIT_8|STOP_1);
break;
case 9600:
Baud=B9600;
//sio_ioctl(CommPort,B9600, P_NONE|BIT_8|STOP_1);
break;
case 19200:
Baud=B19200;
//sio_ioctl(CommPort,B19200, P_NONE|BIT_8|STOP_1); //moxa 不支持14400、28800、56000
break;
case 38400:
Baud=B38400;
//sio_ioctl(CommPort,B38400, P_NONE|BIT_8|STOP_1);
break;
case 57600:
Baud=B57600;
//sio_ioctl(CommPort,B57600, P_NONE|BIT_8|STOP_1);
}
sio_ioctl(CommPort,Baud,P_NONE|BIT_8|STOP_1);
}
//---------------------------------------------------------------------------
void Rece(int)
{
bool i=true;
AnsiString rece="";
//int str;
//AnsiString rate;
//rate=Form1->ComboBox1->Text;
//str=StrToInt(rate);
//if (str>=1200)
// Sleep(300);//针对9600bps,200ms的延时可接收240个字符。
//else
// Sleep(1000); //采用延时方式效率不高且不方便。
while (sio_iqueue(CommPort)>0)
{
if (i)
{
Form1->Edit2->Text=Form1->Receive->Text;
Form1->Receive->Text="";
i=false;
Sleep(DelayTime);//初始延时delaytime 200ms
}
int state=0;
state=sio_getch(CommPort);
if (state<0) //当发送方为大于127以上的字符时,将接收为负数.
state=256+state; //加256后将得以校正,但是sio_getch函数的错误返回吗也为负数,因此有误码的可能.
rece=rece+IntToHex(state,2)+"-";
if (rece.Length()%5==0)
Sleep(10); //当数据长度为最大即200字节时,延时仅200/5*10=400ms
} //加上初始延时累计达600ms. 建议使用2400bps以上。
if (!i)
Form1->Receive->Text=rece;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::CloseBitClick(TObject *Sender)
{
sio_close(CommPort);
Close();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::SendChange(TObject *Sender)
{
if (Send->Text.Length()%3)
Button2->Enabled=false;
else
Button2->Enabled=true;
if (!Len)
{
Len=true;//必须先将Len恢复,否则事件将不断触发,直至清空
Send->Text=Send->Text.SubString(1,Send->Text.Length()-1);
Send->SelStart=Send->Text.Length();
//Len=true;//当Send->Text变化后,将不再执行其后的程序(即本行根本不执行)
} //而是立即进入事件(中断)。
else if (Send->Text.Length()%3==2)//在ONKEYDOWN事件处理中,变换还未发生,如字符串长度和
{ //字符串内容将在事件处理后变化.
Send->Text=Send->Text+'-'; //在ONCHANGE事件中,字符串内容则已经变化.
Send->SelStart=Send->Text.Length();
}
if (Send->Text.Length()>600)
{
ShowMessage("发送数据的最大长度为200字节!");
Send->Text=Send->Text.SubString(1,600); //在ONCHANGE事件中,字符串内容则已经变化.
Send->SelStart=Send->Text.Length();
}
SendLen->Text=Send->Text.Length()/3;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::SendKeyPress(TObject *Sender, char &Key)
{
if ((Key==13)&&(!(Send->Text.Length()%3))) //回删键引起中断,方向键等不引起中断
{
//if (Send->Text.Length()%3)//若余数为非0(非0为真、0为假),输入不完整,不发送。
// return;
// int l,CheckSum=0;
int CheckSum=0;
AnsiString s;
// char Senddata[205]; //最大发送长度200字节,预留5字节。
s=Send->Text;
l=s.Length()/3;
CheckSum=CheckSum+l+2; //帧长度=数据长+2(包括帧长度字节、校验码字节)
for (int i=0;i<l;i++)
{
CheckSum=CheckSum+StrToInt("0x"+s.SubString(3*i+1,2));
Senddata[i]=char(StrToInt("0x"+s.SubString(3*i+1,2)));
}
//int m=strlen(Senddata); //当遇到\x00时,认为数组已结束
Send->Clear();
Button2->Enabled=false;
if (Check1->Checked)
{
CheckSum=CheckSum%256;
s="7E-"+IntToHex(l+2,2)+"-"+s+IntToHex(CheckSum,2)+"-";
Senddata[l]=char(CheckSum);//最后一个字符为校验码
sio_putch(CommPort,126); //发送起始码
sio_putch(CommPort,l+2); //发送帧长度
l++; //数组发送长度加1,增加了校验码
}
Edit1->Text=s;
sio_write(CommPort,Senddata,l);//但是,发送长度"l"决定了将数据完全发送.
}
else if (iswcntrl(Key))
{
}
else if (!isxdigit(Key))//是否十六进制数字及控制字符,以括号内的整形值进行判断。
{
ShowMessage("输入不正确,应为十六进制数字!");
Len=false;
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
ComboBox2->Text=buff; //Interval 单位为毫秒,当值为“0”时,将不调用“on time"事件。
Timer1->Enabled=false;
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
Send->Clear();
Receive->Clear();
Edit1->Clear();
Edit2->Clear();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Edit1Change(TObject *Sender)
{
Edit1Len->Text=Edit1->Text.Length()/3;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ReceiveChange(TObject *Sender)
{
ReceiveLen->Text=Receive->Text.Length()/3;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Edit2Change(TObject *Sender)
{
Edit2Len->Text=Edit2->Text.Length()/3;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
if (!(Send->Text.Length()%3)) //回删键引起中断,方向键等不引起中断
{
// int l,CheckSum=0;
int CheckSum=0;
AnsiString s;
// char Senddata[205]; //最大发送长度200字节,预留5字节。
s=Send->Text;
l=s.Length()/3;
CheckSum=CheckSum+l+2; //帧长度=数据长+2(包括帧长度字节、校验码字节)
for (int i=0;i<l;i++)
{
CheckSum=CheckSum+StrToInt("0x"+s.SubString(3*i+1,2));
Senddata[i]=char(StrToInt("0x"+s.SubString(3*i+1,2)));
}
//int m=strlen(Senddata); //当遇到\x00时,认为数组已结束
Send->Clear();
Button2->Enabled=false;
if (Check1->Checked)
{
CheckSum=CheckSum%256;
s="7E-"+IntToHex(l+2,2)+"-"+s+IntToHex(CheckSum,2)+"-";
Senddata[l]=char(CheckSum);//最后一个字符为校验码
sio_putch(CommPort,126); //发送起始码
sio_putch(CommPort,l+2); //发送帧长度
l++; //数组发送长度加1,增加了校验码
}
Edit1->Text=s;
sio_write(CommPort,Senddata,l);//但是,发送长度"l"决定了将数据完全发送.
/*
do
{
sio_write(CommPort,Senddata,l);
Button2->Enabled=!(Button2->Enabled);
Sleep(DelayTime);
}
while(N7->Checked==true);
*/
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::N01Click(TObject *Sender)
{
N01->Checked=true;
DelayTime=0;
//N01->RadioItem=true;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::N1001Click(TObject *Sender)
{
N1001->Checked=true;
DelayTime=100;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::N2001Click(TObject *Sender)
{
N2001->Checked=true;
DelayTime=200;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::N3001Click(TObject *Sender)
{
N3001->Checked=true;
DelayTime=300;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::N5001Click(TObject *Sender)
{
N5001->Checked=true;
DelayTime=500;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::N10001Click(TObject *Sender)
{
N10001->Checked=true;
DelayTime=1000;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::N20001Click(TObject *Sender)
{
N20001->Checked=true;
DelayTime=2000;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::N50001Click(TObject *Sender)
{
N50001->Checked=true;
DelayTime=5000;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::N100001Click(TObject *Sender)
{
N100001->Checked=true;
DelayTime=10000;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::N101Click(TObject *Sender)
{
N101->Checked=true;
DelayTime=10;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::N201Click(TObject *Sender)
{
N201->Checked=true;
DelayTime=20;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::N501Click(TObject *Sender)
{
N501->Checked=true;
DelayTime=50;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::CheckBox1Click(TObject *Sender)
{
if(CheckBox1->Checked)
{
sio_close(CommPort);
N3->Checked=true;
}
else
{
N3->Checked=false;
sio_open(CommPort); //重新打开串口后,需要重新初始化.不过波特率改变后,初始化时需注意.
sio_ioctl(CommPort,Baud,P_NONE|BIT_8|STOP_1);
sio_flush(CommPort,2);
sio_cnt_irq(CommPort,Rece,1);
}
/*if(CheckBox1->Checked)
sio_cnt_irq(CommPort,Rece,2);//改变中断字符个数后,数据未被锁定.
else //中断定义没改变.
sio_cnt_irq(CommPort,Rece,1);*/
}
//---------------------------------------------------------------------------
void __fastcall TForm1::N2Click(TObject *Sender)
{
if(N2->Checked==false)
{
N2->Checked=true;
Check1->Checked=true;
}
else
{
N2->Checked=false;
Check1->Checked=false;
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::N5Click(TObject *Sender)
{
sio_close(CommPort);
Close();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::N7Click(TObject *Sender)
{
if(N7->Checked)
{
N7->Checked=false;
Timer2->Enabled=false;
}
else
{
N7->Checked=true;
Timer2->Interval=DelayTime;
Timer2->Enabled=true;
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::N3Click(TObject *Sender)
{
if(N3->Checked==false)
{
N3->Checked=true;
CheckBox1->Checked=true;
}
else
{
N3->Checked=false;
CheckBox1->Checked=false;
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Check1Click(TObject *Sender)
{
if(Check1->Checked)
{
N2->Checked=true;
}
else
{
N2->Checked=false;
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer2Timer(TObject *Sender)
{
sio_write(CommPort,Senddata,l);
Button2->Enabled=!(Button2->Enabled);
}
//---------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -