|
使用BCB编写的很小的东东,用API访问串口,
直接运行界面如下不好看只要能用就行(我是实用主义者,同时对那些写了很小的程序就要用户安装、改注册表。。。的人表示鄙视:))。
//定义头文件中的主要内容
class TForm1 : public TForm
{
__published: // IDE-managed Components
TButton *Button1;
TButton *Button2;
TButton *Button3;
TOpenDialog *OpenDialog1;
TProgressBar *ProgressBar1;
TEdit *Edit1;
TButton *Button4;
TLabel *Label1;
TRadioButton *RadioButton1;
TRadioButton *RadioButton2;
TButton *Button5;
TEdit *Edit2;
TMemo *Memo1;
TButton *Button6;
TEdit *Edit3;
TLabel *Label2;
TLabel *Label3;
TTimer *Timer1;
TMemo *Memo2;
void __fastcall Button5Click(TObject *Sender);
void __fastcall Button1Click(TObject *Sender);
void __fastcall FormCreate(TObject *Sender);
void __fastcall RadioButton1Click(TObject *Sender);
void __fastcall RadioButton2Click(TObject *Sender);
void __fastcall FormClose(TObject *Sender, TCloseAction &Action);
void __fastcall Button2Click(TObject *Sender);
void __fastcall Button3Click(TObject *Sender);
void __fastcall Button4Click(TObject *Sender);
void __fastcall Button6Click(TObject *Sender);
void __fastcall Timer1Timer(TObject *Sender);
void __fastcall Memo1DblClick(TObject *Sender);
private: // User declarations
public: // User declarations
unsigned char Buff[0x10000]; //文件内容缓冲区
DCB ComDCB;
HANDLE hComm;
DWORD BytesSent;
DWORD BytesRead;
COMSTAT ComStat;
DWORD dwBytesRead;
DWORD dwErrorFlags;
int BufLen; // 有效长度
unsigned char SendBytes[100];
unsigned char ucRxBuff[100];
unsigned char __fastcall ToHex(unsigned char dat);
__fastcall TForm1(TComponent* Owner);
};
//代码文件中的主要内容
unsigned char _fastcall TForm1::ToHex(unsigned char dat)
{//很笨办法实现的char转HEX,但执行效率不一定低。有空再改
unsigned char i;
switch (dat)
{
case '0':
i = 0;
break;
case '1':
i = 1;
break;
case '2':
i = 2;
break;
case '3':
i = 3;
break;
case '4':
i = 4;
break;
case '5':
i = 5;
break;
case '6':
i = 6;
break;
case '7':
i = 7;
break;
case '8':
i = 8;
break;
case '9':
i = 9;
break;
case 'a':
case 'A':
i = 0x0a;
break;
case 'b':
case 'B':
i = 0x0b;
break;
case 'c':
case 'C':
i = 0x0c;
break;
case 'd':
case 'D':
i = 0x0d;
break;
case 'e':
case 'E':
i = 0x0e;
break;
case 'f':
case 'F':
i = 0x0f;
break;
default:
i = dat;
break;
};
return i;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button5Click(TObject *Sender)
{
int addr,i,j;
BufLen = 0;
Form1->OpenDialog1->Execute();
for (i = 0;i<65536;i++) Buff = 0xff;
int iFileHandle = FileOpen(OpenDialog1->FileName, fmOpenRead);
Edit1->Text = OpenDialog1->FileName;
int iFileLength = FileSeek(iFileHandle,0,2);
FileSeek(iFileHandle,0,0);
unsigned char *pszBuffer = new unsigned char[iFileLength+1];
int iBytesRead = FileRead(iFileHandle, pszBuffer, iFileLength);
FileClose(iFileHandle);
int hexFileType = MessageBox(Form1->Handle,"INTEL HEX格式选择是(Y),BIN格式选择否(N)","是否HEX格式?",MB_YESNO);
if (IDNO == hexFileType)
{//BIN
if (iBytesRead>0x8000) iBytesRead = 0x8000;
for (i=0;i<iBytesRead;i++) {Buff = pszBuffer;};
BufLen = iBytesRead/32;
BufLen *= 32;
if (0 != (iBytesRead%32)) {BufLen += 32;};
}
else
{//HEX
i = 0;
while(1)
{
while ((':' != pszBuffer) && (i<iBytesRead)) {i++;};
if (i>=iBytesRead)
{
i = 0x8000;
while(Buff == 0xff) i--;
BufLen = i/32;
BufLen *= 32;
if (0 != (i%32)) {BufLen +=32;};
delete [] pszBuffer;
if ((0 != BufLen) && (hComm > 0))
{
Button2->Enabled = true;
Button3->Enabled = true;
Button4->Enabled = true;
}
else
{
Button2->Enabled = false;
Button3->Enabled = false;
Button4->Enabled = false;
};
return;
};
i++;
unsigned char cc = 16 * ToHex(pszBuffer[i++]);
cc += ToHex(pszBuffer[i++]);
addr = 16 * 16 * 16 * ToHex(pszBuffer[i++]);
addr += 16 * 16 * ToHex(pszBuffer[i++]);
addr += 16 * ToHex(pszBuffer[i++]);
addr += ToHex(pszBuffer[i++]);
j = 16 * ToHex(pszBuffer[i++]);
j += ToHex(pszBuffer[i++]);
if (0==j)
{
for (j=0;j<cc;j++)
{
if (addr<0x8000)
{
Buff[addr] = 16 * ToHex(pszBuffer[i++]);
Buff[addr++] += ToHex(pszBuffer[i++]);
};
};
};
};
};
if (0 != BufLen)
{
Button2->Enabled = true;
Button3->Enabled = true;
Button4->Enabled = true;
}
else
{
Button2->Enabled = false;
Button3->Enabled = false;
Button4->Enabled = false;
};
delete [] pszBuffer;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
Timer1->Enabled = false;
Label1->Caption = "正在擦除......";
Label1->Refresh();
SendBytes[0] = 'p'; //如MCU在32K模式则复位并进入4K BOOT
PurgeComm(hComm, PURGE_TXABORT| PURGE_RXABORT | PURGE_TXCLEAR| PURGE_RXCLEAR ) ; //清收发缓冲区
WriteFile(hComm,SendBytes,1,&BytesSent,NULL);
Sleep(500);
SendBytes[0] = 'E';
PurgeComm(hComm, PURGE_TXABORT| PURGE_RXABORT | PURGE_TXCLEAR| PURGE_RXCLEAR ) ; //清收发缓冲区
WriteFile(hComm,SendBytes,1,&BytesSent,NULL);
Form1->ProgressBar1->Position = 0;
Sleep(200);
ClearCommError(hComm,&dwErrorFlags,&ComStat);
if (ComStat.cbInQue > 1) ComStat.cbInQue = 1;
if (ReadFile(hComm,ucRxBuff,ComStat.cbInQue,&BytesRead,NULL) && (BytesRead >= 1))
{
if (0x00 == ucRxBuff[0])
{
Label1->Caption = "擦除后空白检查OK";
ProgressBar1->Position = ProgressBar1->Max;
return;
};
if (0xff == ucRxBuff[0])
{Label1->Caption = "擦除后空白检查不能通过!!!!!";return;};
ProgressBar1->Position = ucRxBuff[0];
while(1)
{
ClearCommError(hComm,&dwErrorFlags,&ComStat);
if (ComStat.cbInQue > 1) ComStat.cbInQue = 1;
if (ReadFile(hComm,ucRxBuff,ComStat.cbInQue,&BytesRead,NULL) && (BytesRead >= 1))
{
if (0x00 == ucRxBuff[0])
{
Label1->Caption = "擦除后空白检查OK";
ProgressBar1->Position = ProgressBar1->Max;
return;
};
if (0xff == ucRxBuff[0])
{Label1->Caption = "擦除后空白检查不能通过!!!!!";return;};
Form1->ProgressBar1->Position = ucRxBuff[0];
Label1->Caption = "正在空白检查......";
};
Sleep(1);
};
}
else
{
Label1->Caption = "通信超时!检查连接!";
};
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
Application->ShowMainForm=false;
AnsiString cap=Application->Title;
Application->Title="temp";
if (FindWindow(NULL,cap.c_str()))
{Application->Terminate();return;};
Application->Title=cap.c_str(); //检查如果已有本程序运行则返回
Application->ShowMainForm=true;
BufLen = 0;
CloseHandle(hComm);
hComm = CreateFile("COM1",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);//|FILE_FLAG_OVERLAPPED,0);
if ((int)hComm < 0)
{
hComm = CreateFile("COM2",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);//|FILE_FLAG_OVERLAPPED,0);
Form1->RadioButton1->Checked = false;
Form1->RadioButton2->Checked = true;
};
if ((int)hComm < 0)
{
MessageBox(Form1->Handle,"端口都不能被使用!","ERROR", MB_OK);
Label1->Caption = "请检查通信端口是否被其它程序占用";
Button1->Enabled = false;
Button2->Enabled = false;
Button3->Enabled = false;
Button4->Enabled = false;
Button6->Enabled = false;
return;
};
GetCommState(hComm,&ComDCB);
BuildCommDCB("57600,n,8,1",&ComDCB);
SetCommState(hComm,&ComDCB);
PurgeComm(hComm, PURGE_RXCLEAR|PURGE_TXCLEAR|PURGE_RXABORT|PURGE_TXABORT);
Label1->Caption = "等待命令...";
Button1->Enabled = true;
Button2->Enabled = false;
Button3->Enabled = false;
Button4->Enabled = false;
Button6->Enabled = true;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::RadioButton1Click(TObject *Sender)
{
CloseHandle(hComm);
hComm = CreateFile("COM1",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);//|FILE_FLAG_OVERLAPPED,0);
if ((int)hComm < 0)
{
MessageBox(Form1->Handle,"端口1不能被使用!","ERROR", MB_OK);
Label1->Caption = "请重新选择通信端口";
Button1->Enabled = false;
Button2->Enabled = false;
Button3->Enabled = false;
Button4->Enabled = false;
Button6->Enabled = false;
RadioButton1->Checked = false;
return;
};
GetCommState(hComm,&ComDCB);
BuildCommDCB("57600,n,8,1",&ComDCB);
SetCommState(hComm,&ComDCB);
PurgeComm(hComm, PURGE_RXCLEAR|PURGE_TXCLEAR|PURGE_RXABORT|PURGE_TXABORT);
Label1->Caption = "等待命令...";
Button1->Enabled = true;
Button6->Enabled = true;
if(0 != BufLen)
{
Button2->Enabled = true;
Button3->Enabled = true;
Button4->Enabled = true;
};
}
//---------------------------------------------------------------------------
void __fastcall TForm1::RadioButton2Click(TObject *Sender)
{
CloseHandle(hComm);
hComm = CreateFile("COM2",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);//|FILE_FLAG_OVERLAPPED,0);
if ((int)hComm < 0)
{
MessageBox(Form1->Handle,"端口2不能被使用!","ERROR", MB_OK);
Label1->Caption = "请重新选择通信端口";
Button1->Enabled = false;
Button2->Enabled = false;
Button3->Enabled = false;
Button4->Enabled = false;
Button6->Enabled = false;
RadioButton2->Checked = false;
return;
};
GetCommState(hComm,&ComDCB);
BuildCommDCB("57600,n,8,1",&ComDCB);
SetCommState(hComm,&ComDCB);
PurgeComm(hComm, PURGE_RXCLEAR|PURGE_TXCLEAR|PURGE_RXABORT|PURGE_TXABORT);
Label1->Caption = "等待命令...";
Button1->Enabled = true;
Button6->Enabled = true;
if(0 != BufLen)
{
Button2->Enabled = true;
Button3->Enabled = true;
Button4->Enabled = true;
};
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
if ((int)hComm <0) return;
CloseHandle(hComm);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
Timer1->Enabled = false;
unsigned short addr = 0;
int i;
Label1->Caption = "正在编程......";
Label1->Refresh();
while (addr < BufLen)
{
SendBytes[0] = 'P';
SendBytes[1]=addr/256;SendBytes[2]=addr;
PurgeComm(hComm, PURGE_TXABORT| PURGE_RXABORT | PURGE_TXCLEAR| PURGE_RXCLEAR ) ; //清收发缓冲区
if ((BufLen-addr)>=32)
{
SendBytes[3]=32;
for (i=4;i<36;i++)
{SendBytes=Buff[addr++];};
WriteFile(hComm,SendBytes,36,&BytesSent,NULL);
}
else {
SendBytes[3]=BufLen-addr;
for (i=4;i<(4+BufLen-addr);i++)
{SendBytes=Buff[addr++];};
WriteFile(hComm,SendBytes,4+BufLen-addr,&BytesSent,NULL);
}
i =0;
do
{
Sleep(1);
ClearCommError(hComm,&dwErrorFlags,&ComStat);
i++;
if (i>1000)
{
Label1->Caption ="通信出错!!!!!";
return;
}
} while (ComStat.cbInQue<2);
ReadFile(hComm,ucRxBuff,ComStat.cbInQue,&BytesRead,NULL);
ProgressBar1->Position = 128 *addr / BufLen;
};
Label1->Caption = "编程完成,请进行校验";
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button3Click(TObject *Sender)
{
Timer1->Enabled = false;
unsigned short addr = 0;
int i;
Label1->Caption = "正在检查校验数据......";
Label1->Refresh();
while (addr < BufLen)
{
SendBytes[0] = 'V';
SendBytes[1]=addr/256;SendBytes[2]=addr;
PurgeComm(hComm, PURGE_TXABORT| PURGE_RXABORT | PURGE_TXCLEAR| PURGE_RXCLEAR ) ; //清收发缓冲区
SendBytes[3]=32;
WriteFile(hComm,SendBytes,4,&BytesSent,NULL);
i =0;
do
{
Sleep(1);
ClearCommError(hComm,&dwErrorFlags,&ComStat);
i++;
if (i>1000)
{
Label1->Caption ="通信出错!!!!!";
return;
}
} while (ComStat.cbInQue < 33);
ReadFile(hComm,ucRxBuff,ComStat.cbInQue,&BytesRead,NULL);
if ('V' != ucRxBuff[0])
{
Label1->Caption ="接收出错!!!!!";
return;
};
for (i=1;i<33;i++)
{
if (Buff[addr++] != ucRxBuff)
{
Label1->Caption = "校验检查到错误 0x"+IntToHex(addr-1,4);
return;
};
};
ProgressBar1->Position = 128 *addr / BufLen;
};
Label1->Caption = "校验OK";
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button4Click(TObject *Sender)
{
Timer1->Enabled = false;
Button6->Enabled = false;
Button6->Refresh();
Form1->Button1Click(Form1);
Form1->Refresh();
if (Label1->Caption != "擦除后空白检查OK")
return;
Form1->Button2Click(Form1);
Form1->Refresh();
if (Label1->Caption != "编程完成,请进行校验")
return;
Form1->Button3Click(Form1);
Form1->Refresh();
if (Label1->Caption != "校验OK")
return;
SendBytes[0] = 'F';
PurgeComm(hComm, PURGE_TXABORT| PURGE_RXABORT | PURGE_TXCLEAR| PURGE_RXCLEAR ) ; //清收发缓冲区
WriteFile(hComm,SendBytes,1,&BytesSent,NULL);
Sleep(10);
Label1->Caption = "完成编程,并使MCU复位";
Button6->Enabled = true;
Timer1->Enabled = true;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button6Click(TObject *Sender)
{
int i = 0;
AnsiString s;
if (Edit3->Text.Length() != 1) return;
SendBytes[i++] = Edit3->Text.c_str()[0];
int j = 0;
while (j < Edit2->Text.Length())
{
s= "";
while ((Edit2->Text.c_str()[j] != ',') && (j < Edit2->Text.Length()))
{
s += Edit2->Text.c_str()[j++];
};
j++;
if (s.Length()==2) s = "0x"+s;
SendBytes[i++] = StrToInt(s);
};
//PurgeComm(hComm, PURGE_TXABORT| PURGE_RXABORT | PURGE_TXCLEAR| PURGE_RXCLEAR ) ; //清收发缓冲区
WriteFile(hComm,SendBytes,i,&BytesSent,NULL);
Timer1->Enabled = true;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
AnsiString s="";
AnsiString ss="";
Timer1->Enabled = false;
ClearCommError(hComm,&dwErrorFlags,&ComStat);
if (ComStat.cbInQue == 0)
{
Timer1->Enabled = true;
return;
};
ReadFile(hComm,ucRxBuff,ComStat.cbInQue,&BytesRead,NULL);
for (unsigned int i=0;i<BytesRead;i++)
{
s += IntToHex(ucRxBuff,2) + " ";
ss += " ";
ss += (char)ucRxBuff;
ss += " ";
};
Memo1->Lines->Append(s);
Memo2->Lines->Append(ss);
Timer1->Enabled = true;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Memo1DblClick(TObject *Sender)
{
Memo1->Clear();
Memo2->Clear();
//Memo1->Lines->Append("接收到的数据:");
}
//---------------------------------------------------------------------------