全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:16634
推到 Plurk!
推到 Facebook!

在Win32[BCB]下用Serial Port通訊的範例

 
jackkcg
站務副站長


發表:891
回覆:1050
積分:848
註冊:2002-03-23

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-02-08 23:37:49 IP:61.64.xxx.xxx 未訂閱
此為轉貼資料    http://netcity3.web.hinet.net/userdata/k1228341/art/bcb232.txt    ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Subject: 在Win32[BCB]下用Serial Port通訊的範例    發信人: vega6385.bbs@cszone.twbbs.org (simayi), 信區: programming 標  題: 在Win32[BCB]下用Serial Port通訊的範例 發信站: 程式設計樂園(CSZone) (Thu Jul 27 21:16:13 2000) 轉信站: cis_nctu!news.cis.nctu!freebsd.ntu!news.ntu!CSZone 來  源: octa2.ee.ntu.edu.tw    在Win32[BCB]下用Serial Port通訊的範例 /////////////////////////////////////////////// 下列的程式示範了如何在Win32下 用console mode做Serial Port通訊 關於與之通訊的硬體,請參考松崗 出版的"單晶片8051實務<增修版>" 一書,作者:吳一農,ISBN:957-22-3242-8 硬體線路及8051ASM CODE.請參照 書中第16章的部份.本程式能完全取代 16-19頁中的Qbasic程式,達到雙向傳輸的功用. 本程式在BCB5中能順利編譯執行!!    #include #include #include int main(int argc, char* argv[]) { HANDLE com2_handle ; //RS-232的Com2的handle DCB dcb ; //設定傳輸參數所需之結構 char buffer[10]; //讀取資料所需的緩衝區 DWORD read_bytes = 1 ; //每次讀取的byte數 com2_handle = CreateFile( "COM2" ,GENERIC_READ|GENERIC_WRITE , 0, NULL ,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); //開啟com2,設為一般讀取寫入,一般屬性,不使用非同步IO BuildCommDCB( "baud=4800 parity=N data=8 stop=2", &dcb ); //設定傳輸參數結構的內含值:鮑率:4800,無同位檢查,資料位元8,停止位元2 SetCommState( com2_handle , &dcb ); //設定傳輸參數 COMMTIMEOUTS time_out ; //設定讀寫逾時參數的結構 time_out.ReadIntervalTimeout = MAXDWORD ; //設為MAXDWORD:如果沒有資料供讀取,ReadFile函式將立即返回 time_out.ReadTotalTimeoutMultiplier = 0 ; time_out.ReadTotalTimeoutConstant = 0 ; //不使用讀取總和時間來判斷是否讀取逾時 time_out.WriteTotalTimeoutMultiplier = 5 ; time_out.WriteTotalTimeoutConstant = 50 ; //使用寫入總和時間來判斷是否寫入逾時,逾時WriteFile函式將立即返回 SetCommTimeouts( com2_handle , &time_out ) ; //設定com2讀寫逾時返回 printf("請撥動switch然後接收 或 按數字鍵0~9傳輸 或 可以按X結束\n"); while( 1 ) { ReadFile( com2_handle , buffer , read_bytes ,&read_bytes ,NULL); //由com2讀取1byte //因為ReadFile函式逾時的時候,不僅沒讀到資料(所以buffer[0]沒變動)就返回, //還會把read_bytes內含值改為0,因此read_bytes!= 0時表示有讀到資料 if(read_bytes!= 0) { //下面這一段顯示四個switch的狀態,用1與0表示ON/OFF //方法是有點拙,我也知道用<<和>>很快,可是實作時出了點狀況,所以用這個拙方法 int sw1,sw2,sw3,sw4 ; sw1 = (0-buffer[0]-113) / 8 ; sw2 = ((0-buffer[0]-113)- (sw1 * 8)) / 4 ; sw3 = ((0-buffer[0]-113)-(sw1*8)-(sw2*4)) / 2 ; sw4 = ((0-buffer[0]-113)-(sw1*8)-(sw2*4)-(sw3*2)) / 1 ; printf("由COM2得到Switch狀態 %d%d%d%d \n", sw1,sw2,sw3,sw4); printf("可以按X結束\n"); } else { read_bytes = 1 ; //因為ReadFile函式逾時的時候,不僅沒讀到資料(所以buffer[0]沒變動)就返回, //還會把read_bytes內含值改為0,所以我們要設回初值,不然下一輪會讀不到資料 //(因為內函值為0,表示要讀取0byte,所以讀不到資料) } if( kbhit() != 0 ) //如果鍵盤有被按到,kbhit函式傳回值不等於0 { int key ; //存放被按的鍵的鍵值 key = getch() ; //把被鍵值讀出來 if( key == 'x' ) { break ; //按下小寫x結束本程式 } else { switch( key ) //如果輸入數字鍵0~9,將之傳給8051實習板顯示出來 { case '0' : WriteFile( com2_handle , &key , read_bytes , &read_bytes ,NULL ); printf("傳送%c到UART的另一端\n",key); printf("可以按X結束\n"); break ; case '1' : WriteFile( com2_handle , &key , read_bytes , &read_bytes ,NULL ); printf("傳送%c到UART的另一端\n",key); printf("可以按X結束\n"); break ; case '2' : WriteFile( com2_handle , &key , read_bytes , &read_bytes ,NULL ); printf("傳送%c到UART的另一端\n",key); printf("可以按X結束\n"); break ; case '3' : WriteFile( com2_handle , &key , read_bytes , &read_bytes ,NULL ); printf("傳送%c到UART的另一端\n",key); printf("可以按X結束\n"); break ; case '4' : WriteFile( com2_handle , &key , read_bytes , &read_bytes ,NULL ); printf("傳送%c到UART的另一端\n",key); printf("可以按X結束\n"); break ; case '5' : WriteFile( com2_handle , &key , read_bytes , &read_bytes ,NULL ); printf("傳送%c到UART的另一端\n",key); printf("可以按X結束\n"); break ; case '6' : WriteFile( com2_handle , &key , read_bytes , &read_bytes ,NULL ); printf("傳送%c到UART的另一端\n",key); printf("可以按X結束\n"); break ; case '7' : WriteFile( com2_handle , &key , read_bytes , &read_bytes ,NULL ); printf("傳送%c到UART的另一端\n",key); printf("可以按X結束\n"); break ; case '8' : WriteFile( com2_handle , &key , read_bytes , &read_bytes ,NULL ); printf("傳送%c到UART的另一端\n",key); printf("可以按X結束\n"); break ; case '9' : WriteFile( com2_handle , &key , read_bytes , &read_bytes ,NULL ); printf("傳送%c到UART的另一端\n",key); printf("可以按X結束\n"); break ; default: break ; } } } } CloseHandle( com2_handle ); //關閉com2 return 0; } /////////////////////////////////// 改寫成BCB的版本如下 /////////////////////////////////// //--------------------------------------------------------------------------- #include #pragma hdrstop #include "uart_GUI_cpp.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" #include TForm1 *Form1; HANDLE com2_handle ; //RS-232的Com2的handle DCB dcb ; //設定傳輸參數所需之結構 char buffer[10]; //讀取資料所需的緩衝區 DWORD read_bytes = 1 ; //每次讀取的byte數 COMMTIMEOUTS time_out ; //設定讀寫逾時參數的結構 int key ; //存放被按的鍵的鍵值 char temp_string[256]; char temp_string2[256]; //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- void __fastcall TForm1::FormResize(TObject *Sender) { Width = 435 ; Height = 300 ; } //--------------------------------------------------------------------------- void __fastcall TForm1::Button11Click(TObject *Sender) { Form1->Close(); } //--------------------------------------------------------------------------- void __fastcall TForm1::FormCreate(TObject *Sender) { com2_handle = CreateFile( "COM2" ,GENERIC_READ|GENERIC_WRITE , 0, NULL ,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); //開啟com2,設為一般讀取寫入,一般屬性,不使用非同步IO BuildCommDCB( "baud=4800 parity=N data=8 stop=2", &dcb ); //設定傳輸參數結構的內含值:鮑率:4800,無同位檢查,資料位元8,停止位元2 SetCommState( com2_handle , &dcb ); //設定傳輸參數 time_out.ReadIntervalTimeout = MAXDWORD ; //設為MAXDWORD:如果沒有資料供讀取,ReadFile函式將立即返回 time_out.ReadTotalTimeoutMultiplier = 0 ; time_out.ReadTotalTimeoutConstant = 0 ; //不使用讀取總和時間來判斷是否讀取逾時 time_out.WriteTotalTimeoutMultiplier = 5 ; time_out.WriteTotalTimeoutConstant = 50 ; //使用寫入總和時間來判斷是否寫入逾時,逾時WriteFile函式將立即返回 SetCommTimeouts( com2_handle , &time_out ) ; //設定com2讀寫逾時返回 Memo1->Clear(); Memo2->Clear(); } //--------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { key = '1'; sprintf(temp_string,"%c",key); Memo1->Clear(); Memo1->SetSelTextBuf(temp_string); WriteFile( com2_handle , &key , read_bytes , &read_bytes ,NULL ); } //--------------------------------------------------------------------------- void __fastcall TForm1::Button2Click(TObject *Sender) { key = '2'; sprintf(temp_string,"%c",key); Memo1->Clear(); Memo1->SetSelTextBuf(temp_string); WriteFile( com2_handle , &key , read_bytes , &read_bytes ,NULL ); } //--------------------------------------------------------------------------- void __fastcall TForm1::Button10Click(TObject *Sender) { key = '0'; sprintf(temp_string,"%c",key); Memo1->Clear(); Memo1->SetSelTextBuf(temp_string); WriteFile( com2_handle , &key , read_bytes , &read_bytes ,NULL ); } //--------------------------------------------------------------------------- void __fastcall TForm1::Button3Click(TObject *Sender) { key = '3'; sprintf(temp_string,"%c",key); Memo1->Clear(); Memo1->SetSelTextBuf(temp_string); WriteFile( com2_handle , &key , read_bytes , &read_bytes ,NULL ); } //--------------------------------------------------------------------------- void __fastcall TForm1::Button4Click(TObject *Sender) { key = '4'; sprintf(temp_string,"%c",key); Memo1->Clear(); Memo1->SetSelTextBuf(temp_string); WriteFile( com2_handle , &key , read_bytes , &read_bytes ,NULL ); } //--------------------------------------------------------------------------- void __fastcall TForm1::Button5Click(TObject *Sender) { key = '5'; sprintf(temp_string,"%c",key); Memo1->Clear(); Memo1->SetSelTextBuf(temp_string); WriteFile( com2_handle , &key , read_bytes , &read_bytes ,NULL ); } //--------------------------------------------------------------------------- void __fastcall TForm1::Button6Click(TObject *Sender) { key = '6'; sprintf(temp_string,"%c",key); Memo1->Clear(); Memo1->SetSelTextBuf(temp_string); WriteFile( com2_handle , &key , read_bytes , &read_bytes ,NULL ); } //--------------------------------------------------------------------------- void __fastcall TForm1::Button7Click(TObject *Sender) { key = '7'; sprintf(temp_string,"%c",key); Memo1->Clear(); Memo1->SetSelTextBuf(temp_string); WriteFile( com2_handle , &key , read_bytes , &read_bytes ,NULL ); } //--------------------------------------------------------------------------- void __fastcall TForm1::Button8Click(TObject *Sender) { key = '8'; sprintf(temp_string,"%c",key); Memo1->Clear(); Memo1->SetSelTextBuf(temp_string); WriteFile( com2_handle , &key , read_bytes , &read_bytes ,NULL ); } //--------------------------------------------------------------------------- void __fastcall TForm1::Button9Click(TObject *Sender) { key = '9'; sprintf(temp_string,"%c",key); Memo1->Clear(); Memo1->SetSelTextBuf(temp_string); WriteFile( com2_handle , &key , read_bytes , &read_bytes ,NULL ); } //--------------------------------------------------------------------------- void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action) { CloseHandle( com2_handle ); } //--------------------------------------------------------------------------- void __fastcall TForm1::Timer1Timer(TObject *Sender) { Timer1->Enabled = false; ReadFile( com2_handle , buffer , read_bytes ,&read_bytes ,NULL); //由com2讀取1byte if(read_bytes!= 0) { //下面這一段顯示四個switch的狀態,用1與0表示ON/OFF //方法是有點拙,我也知道用<<和>>很快,可是實作時出了點狀況,所以用這個拙方法 int sw1,sw2,sw3,sw4 ; sw1 = ((0-buffer[0]-113) & 8)/8 ; sw2 = ((0-buffer[0]-113) & 4)/4 ; sw3 = ((0-buffer[0]-113) & 2)/2 ; sw4 = ((0-buffer[0]-113) & 1)/1 ; sprintf(temp_string2,"由COM2得到Switch狀態 %d%d%d%d \n", sw1,sw2,sw3,sw4); Memo2->Clear(); Memo2->SetSelTextBuf(temp_string2); while(read_bytes!= 0)//把緩衝區資料全讀完才跳出 { ReadFile( com2_handle , buffer , read_bytes ,&read_bytes ,NULL); //由com2讀取1byte sw1 = ((0-buffer[0]-113) & 8)/8 ; sw2 = ((0-buffer[0]-113) & 4)/4 ; sw3 = ((0-buffer[0]-113) & 2)/2 ; sw4 = ((0-buffer[0]-113) & 1)/1 ; sprintf(temp_string2,"由COM2得到Switch狀態 %d%d%d%d \n", sw1,sw2,sw3,sw4); Memo2->Clear(); Memo2->SetSelTextBuf(temp_string2); } read_bytes = 1 ; //因為ReadFile函式逾時的時候,不僅沒讀到資料(所以buffer[]沒變動)就返回, //還會把read_bytes內含值改為0,所以我們要設回初值,不然下一輪會讀不到資料 //(因為內函值為0,表示要讀取0byte,所以讀不到資料) } else { read_bytes = 1 ; //因為ReadFile函式逾時的時候,不僅沒讀到資料(所以buffer[]沒變動)就返回, //還會把read_bytes內含值改為0,所以我們要設回初值,不然下一輪會讀不到資料 //(因為內函值為0,表示要讀取0byte,所以讀不到資料) } Timer1->Enabled = true; } //--------------------------------------------------------------------------- -- ********************************************* * Simayi司馬仲達 simayi@kimo.com.tw ? * * CICQ : 663287 ICQ : 49827636 * * 歡迎大家一起討論程式設計的問題 * * C/C OWL ASM QB都可以討論喔!! * ********************************************* -- ※ Origin: 程式設計樂園 ◆ From: h117.s170.ts32.hinet.net ********************************************************* 哈哈&兵燹 最會的2大絕招 這個不會與那個也不會 哈哈哈 粉好 Delphi K.Top的K.Top分兩個字解釋Top代表尖端的意思,希望本討論區能提供Delphi的尖端新知 K.表Knowlege 知識,就是本站的標語:Open our mind to make knowledge together! 希望能大家敞開心胸,將知識寶庫結合一起
------
**********************************************************
哈哈&兵燹
最會的2大絕招 這個不會與那個也不會 哈哈哈 粉好

Delphi K.Top的K.Top分兩個字解釋Top代表尖端的意思,希望本討論區能提供Delphi的尖端新知
K.表Knowlege 知識,就是本站的標語:Open our mind
GrandRURU
站務副站長


發表:235
回覆:1655
積分:1753
註冊:2005-06-21

發送簡訊給我
#2 引用回覆 回覆 發表時間:2010-04-05 08:05:03 IP:111.250.xxx.xxx 訂閱
 另一篇有提到的

Simple Serial Communication with Borland Turbo C Explorer

Introduction

It's relatively easy to write a simple serial communications console program and many examples on the web abound. But things get more complicated in the event-driven GUI world of Windows. Turbo C Explorer does not come with a serial component so what do you do if you want a quick and simple program or just want to learn about serial communication? Here is an example application that you can write yourself in 5 minutes. Rather than using separate threads and complex overlapped I/O handling or intalling a component, this example uses a simple, easy to understand polled loop.
The example has 2 buttons, Start and Stop, and a TMemo text box. When the application is running, click Start to open a COM port. Once the port is open, incoming serial data will appear in the text box. Characters typed into the text box will be transmitted. Click Stop to close the COM port. That's it. The example code is explained below. You can either follow along and write your own version or simply download the Turbo C Explorer Simple Serial project directly. A complete code listing appears at the end of this page.

Create the Application

Open Turbo C Explorer and start a New Project. Select the icon for a VCL Forms Application. This will create a blank form and skeleton code for the application. From the Components palette, add two TButtons and a TMemo control to Form1. Name the buttons Butt"code"> DCB dcbCommPort; COMMTIMEOUTS CommTimeouts; DWORD BytesRead; Next we call the WIN32 API CreateFile() function to OPEN the port. The "COM1" string designates the port number. Change this string to any port on your machine (COM2, COM3, etc.) but don't change any of the other CreateFile() parameters. Doing so might make our simple example work incorrectly. If the COM port cannot be opened, an error message will be displayed in Memo1 and we return. You'll need to find out why the port didn't open. It could be caused by a COM port that is already in use by another program or a port that does not exist on your machine.
  
  hComm = CreateFile( "COM1",
          GENERIC_READ | GENERIC_WRITE,
          0,
          0,
          OPEN_EXISTING,
          0,
          0);      if (hComm == INVALID_HANDLE_VALUE) {
    Memo1->Lines->Add("Could not open comm port.");
    return;
  }    
The next group of functions configure the serial Device Control Block (DCB) which controls baud rate, parity, data bits, and stop bits among other things. We call the WIN32 API GetCommDCB() function to load existing DCB parameters into our dcbCommPort structure. We next call BuildCommDCB() with a string describing baud rate, parity, data bits, and stop bits. Although the DCB has many parameters, in our example we're keeping it simple by using the BuildCommDCB() function to populate the dcbCommPort structure for us. Finally, calling SetCommState() loads our parameters into the DCB for our open port. If it's successful, we move on, otherwise we close the port, print an error message, and return.
  dcbCommPort.DCBlength = sizeof(DCB);
  GetCommState(hComm, &dcbCommPort);      if(!BuildCommDCB("baud=9600 parity=N data=8 stop=1", &dcbCommPort)) {
    hComm = NULL;
    Memo1->Lines->Add("Cannot build comm DCB.");
    return;
  }      if(!SetCommState(hComm, &dcbCommPort)) {
    CloseHandle(hComm);
    hComm = NULL;
    Memo1->Lines->Add("Cannot set comm state.");
    return;
  }    
We next set the CommTimeouts. These settings control delays when trying to read from or write to the comm port. The values used in this example cause no delays when reading the port and a maximum delay of 250 ms when writing (Actually, the write delay will never occur in our example because we transmit characters individually without calling WriteFile().) We load our timeout values by calling SetCommTimeouts(). If no errors are returned, the comm port is now configured the way we want it.
  CommTimeouts.ReadIntervalTimeout = MAXDWORD;
  CommTimeouts.ReadTotalTimeoutConstant = 0;
  CommTimeouts.ReadTotalTimeoutMultiplier = 0;
  CommTimeouts.WriteTotalTimeoutConstant = 250;
  CommTimeouts.WriteTotalTimeoutMultiplier = 1;      if(!SetCommTimeouts(hComm, &CommTimeouts)) {
    CloseHandle(hComm);
    hComm = NULL;
    Memo1->Lines->Add("Cannot set timeouts.");
    return;
  }    
Before reading the comm port, we set CommFlag, disable the Start button, enable the Stop button, and finish by allowing text to be entered in Memo1 then give it focus.
  CommFlag = true;
  Butt false;
  Butt true;
  Memo1->ReadOnly = false;
  Memo1->SetFocus();    
We are now at the loop that is really the heart of our Turbo C serial communication application. The program will stay in this loop as long as CommFlag is true and it can only be made false by clicking the Stop button or closing the program. While in this loop, the program performs three significant tasks:
  • Process any events that occur elsewhere in the program.
  • Read the comm port with ReadFile().
  • If bytes were read, display them in Memo1.
Calling ProcessMessages() inside the loop allows the application to handle other events like typing in Memo1 or clicking the Stop button. Sleep() prevents our loop from consuming all available CPU cycles which would far exceed our requirements. Because the serial device driver within the Windows OS has its own internal buffer, we won't miss any incoming characters while still allowing CPU time for other applications. It's the polite thing to do.
The ReadFile() function tries to read 100 bytes into our global array InBuffer. Because of our CommTimeout settings, ReadFile() will return immediately with whatever is available from the Windows internal serial receive buffer even if it's empty. If ReadFile() received any characters, we null-terminate the string and display it in Memo1. Pretty simple.
  while(CommFlag) {
    Application->ProcessMessages();        Sleep(1)
    ReadFile(hComm, InBuffer, 100, &BytesRead, NULL);        if(BytesRead) {
      InBuffer[BytesRead] = 0;
      Memo1->SetSelTextBuf(InBuffer);
    }      }    
Clicking the Stop button or exiting the application will reset CommFlag and execution will fall through the loop. Code after the loop closes the COM port, restores the buttons to their previous state, and returns from the Butt0 to prevent it. If you want to see the characters (local echo) just omit that line of code.
  if(hComm) TransmitCommChar(hComm, Key);
  Key = 0;    

Final Thoughts

For the sake of clarity and simplicity, our example application omits a few things.
  • Memo1 cannot properly display a CR without a LF. TMemo has the quirky need for a CR-LF pair and they must be in that order. If a CR arrives by itself, you'll need to add the LF.
  • Memo1 holds a lot of characters but will eventually run out of memory and just stop displaying anything new that arrives. You can limit the number of characters it will display by setting the Memo1 MaxLength property but then it will just run out of space sooner. A better approach is to limit the number of lines without affecting the display.
  • We've only seen how to transmit single characters. WriteFile() is the function that can sends whole strings.

You are free to use all the information presented here. There are no restrictions. There's no support available but the program is simple enough that you probably won't need it. Send comments toturbocomments@simpleserial.com

Links

SimpleSerial.zip Download Turbo C Explorer Simple Serial Project.
Microsoft MSDN Serial Communication Resources WIN32 API serial communication reference.
www.turboexplorer.com/cpp Borland's FREE Turbo C Explorer

Full Code Listing

  //---------------------------------------------------------------------------      #include    #pragma hdrstop    #include "Main.h"   //---------------------------------------------------------------------------   #pragma package(smart_init)   #pragma resource "*.dfm"   TForm1 *Form1;    // Add these global variables   HANDLE hComm = NULL;   bool CommFlag;   char InBuffer[101];      //---------------------------------------------------------------------------   __fastcall TForm1::TForm1(TComponent* Owner)     : TForm(Owner)   {      }   //---------------------------------------------------------------------------   void __fastcall TForm1::Butt"comment" >// Add these local variables.        DCB dcbCommPort;     COMMTIMEOUTS CommTimeouts;     DWORD BytesRead;        // Open the port using WIN32 API CreateFile().     // Change COM1 for different port.     // Leave the remaining parameters alone for simple     // non-overlapped serial I/O.             hComm = CreateFile( "COM1",             GENERIC_READ | GENERIC_WRITE,             0,             0,             OPEN_EXISTING,             0,             0);           // If port cannot open, print error message and return.        if (hComm == INVALID_HANDLE_VALUE) {       Memo1->Lines->Add("Could not open comm port.");       return;     }        // Get the existing DCB parameters        dcbCommPort.DCBlength = sizeof(DCB);     GetCommState(hComm, &dcbCommPort);           // Use the WIN32 API BuildCommDCB() to load simple comm parameters     // into DCB. If it fails, print error message and return.             if(!BuildCommDCB("baud=9600 parity=N data=8 stop=1", &dcbCommPort)) {       hComm = NULL;       Memo1->Lines->Add("Cannot build comm DCB.");       return;     }           // Use the WIN32 API SetCommState() to set parameters from DCB.     // If it fails, close hComm, print error message, and return.        if(!SetCommState(hComm, &dcbCommPort)) {       CloseHandle(hComm);       hComm = NULL;       Memo1->Lines->Add("Cannot set comm state.");       return;     }           // Set CommTimeouts parameters.     // See ReadFile() function later for details.        CommTimeouts.ReadIntervalTimeout = MAXDWORD;     CommTimeouts.ReadTotalTimeoutConstant = 0;     CommTimeouts.ReadTotalTimeoutMultiplier = 0;     CommTimeouts.WriteTotalTimeoutConstant = 250;     CommTimeouts.WriteTotalTimeoutMultiplier = 1;           // Use the WIN32 API SetCommTimeouts() to set parameters from DCB.     // If it fails, close hComm, print error message, and return.        if(!SetCommTimeouts(hComm, &CommTimeouts)) {       CloseHandle(hComm);       hComm = NULL;       Memo1->Lines->Add("Cannot set comm timeouts.");       return;     }        // Set CommFlag and Button states. Allow typing in Memo1.        CommFlag = true;     Butt false;     Butt true;     Memo1->ReadOnly = false;     Memo1->SetFocus();        // Constantly loop while CommFlag is true.     // ProcessMessages() allows other other events within the program     // to be serviced. ReadFile() tries to read 100 bytes into InBuffer.     // Because of the timeouts we used earlier, ReadFile() will return     // immediately with whatever characters it has (up to 100). The     // BytesRead variable will contain the number of characters loaded     // into InBuffer.        // If BytesRead > 0, make the last charater in the received string = 0.     // This terminates the string. Notice that we dimensioned InBuffer[101]     // to accomodate the terminating 0 if necessary. Use SetSelTextBuff()     // to append the contents of InBuffer onto the end of text in Memo1.        // Pressing either the Stop button or Window close button will     // set CommFlag = false. That will end the loop.             while(CommFlag) {       Application->ProcessMessages();          Sleep(1)       ReadFile(hComm, InBuffer, 100, &BytesRead, NULL);          if(BytesRead) {         InBuffer[BytesRead] = 0;         Memo1->SetSelTextBuf(InBuffer);       }        }        // Close the comm port and set hComm to NULL.        CloseHandle(hComm);     hComm = NULL;        //Set button enables back to original state. Make Memo1 read-only.        Butt true;     Butt false;     Memo1->ReadOnly = true;      }   //---------------------------------------------------------------------------   void __fastcall TForm1::Butt"comment" >// If Stop button pressed...        CommFlag = false;   }   //---------------------------------------------------------------------------   void __fastcall TForm1::FormCloseQuery(TObject *Sender, bool &CanClose)   {     // If attempting to close the window...        CommFlag = false;   }   //---------------------------------------------------------------------------   void __fastcall TForm1::Memo1KeyPress(TObject *Sender, char &Key)   {     // If a Memo1 key is pressed, transmit it.     // TransmitCommChar() returns 0 if the previous character has not     // finished sending. Keep trying until non-zero is returned.          if(hComm) while(TransmitCommChar(hComm, Key) == 0);         // Set Key=0 so it will not echo in Memo1.     // Omit this line if you want local echo.          Key = 0;   }      //---------------------------------------------------------------------------   
系統時間:2017-12-13 9:31:27
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!