Você está na página 1de 2

Nº 2.

 Septiembre de 2008  COMUNICACIÓN POR EL PUERTO SERIAL UTILIZANDO C++ BUILDER 
AlterNEXT
Software Engineering 
   

COMUNICACIÓN POR EL PUERTO SERIAL


UTILIZANDO C++ BUILDER
1. Poner las propiedades del Memo de la siguiente forma: 
Alignment = alClient
MaxLength = 0
ScrollBars = ssVertical
WantReturns = true
WantTabs = false
WordWrap = true

2.  Añadir  un  nuevo  objeto  Thread  (…File  ‐>  New...).  Cuando 
pregunte el nombre para la clase, llamarlo TRead. 
 
Ahora se debería tener 2 units, una Unit1.cpp para el Form1, y una 
Unit2.cpp para el thread. 
 
3. Aquí hay una lista de los eventos a implementar: 
Form1 OnCreate
Form1 OnClose
 

E
Memo1 OnKeyPress

xiste  un  gran  número  de  casos  en  que  el  software  4. El código de la Unit1.cpp ... 
necesita  emitir  algún  tipo  de  salida  o  resultado  hacia  el  //‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ 
#include <vcl.h> 
exterior  del  mismo  hardware  donde  se  ejecuta,  o  bien  #pragma hdrstop 
#include "Unit1.h" 
necesita  recibir  algún  tipo  de  entrada  desde  algún  #include "Unit2.h" // CABECERA DE LA UNIT2 (THREAD) 
// VARIABLES GLOBALES 
dispositivo “externo”, y es bastante común que estos dispositivos  HANDLE hComm = NULL; 
externos  estén  conectados  al  hardware  de  computo  donde  se  TRead *ReadThread; 
COMMTIMEOUTS ctmoNew = {0}, ctmoOld; 
ejecuta el programa (CPU) a través de una conexión por el Puerto   
//‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ 
Serial, también conocida como interfaz RS‐232.  #pragma package(smart_init) 
#pragma resource "*.dfm" 
TForm1 *Form1; 
 
En  este  artículo  se  expone  una  manera  sencilla  de  conectarse  al  //‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ 
puerto  serial  y  enviar  o  recibir  señales  utilizando  el  lenguaje  de  __fastcall TForm1::TForm1(TComponent* Owner) 
: TForm(Owner) 
programación  C++  Builder  de  CodeGear.  Evidentemente  este  { 

articulo  está  destinado  a  personas  con  conocimientos  en   
//‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ 
programación  de  sistemas  y  familiarizados  con  el  entorno  de  void __fastcall TForm1::FormCreate(TObject *Sender) 
desarrollo RAD Studio. Tomar en cuenta los siguientes puntos para  { 
Memo1‐>Clear(); 
mejor compresión del código expuesto:  DCB dcbCommPort; 
// ABRE EL PUERTO 
// REEMPLAZAR "COM2" POR "COM1", "COM3", ETC. PARA ABRIR 
// OTRO PUERTO 
 Los  comentarios  dados  en  este  color  verde  son  para  hComm = CreateFile("COM2", 
GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0); 
entender el funcionamiento del ejemplo.  // SI EL PUERTO NO PUEDE ABRIRSE ... 
 El texto escrito en color azul, es el que genera el IDE y no  if(hComm == INVALID_HANDLE_VALUE)  
Application‐>Terminate(); 
debemos volver a copiar.  // ESTABLECEMOS LOS TIMEOUTS 
GetCommTimeouts(hComm,&ctmoOld); 
 El código de color rojo, es el que debemos introducir para  ctmoNew.ReadTotalTimeoutConstant = 100; 
ctmoNew.ReadTotalTimeoutMultiplier = 0; 
seguir el ejemplo.  ctmoNew.WriteTotalTimeoutMultiplier = 0; 
ctmoNew.WriteTotalTimeoutConstant = 0; 
SetCommTimeouts(hComm, &ctmoNew); 
// ESTABLECEMOS BAUD RATE, PARITY, WORD SIZE, Y STOP BITS. 
El  ejemplo  consiste  en  un  Form  con  un  objeto  Memo  (para  la  // HAY OTROS METODOS DE HACER ESTO, PERO ESTE ES EL MAS FACIL 
entrada/salida de texto) y un objeto Thread.  dcbCommPort.DCBlength = sizeof(DCB); 
GetCommState(hComm, &dcbCommPort); 
BuildCommDCB("9600,N,8,1", &dcbCommPort); 
SetCommState(hComm, &dcbCommPort); 
Se  empieza  con  un  nuevo  proyecto,  donde  situaremos  un  Memo  // ACTIVAMOS EL THREAD 
ReadThread = new TRead(false); 
en el Form1.  } 
 

Página  1  Álvaro Pinto Torrejón
http://www.alternext.com.bo  apinto@alternext.com.bo 
 
Nº 2. Septiembre de 2008  COMUNICACIÓN POR EL PUERTO SERIAL UTILIZANDO C++ BUILDER 
AlterNEXT
Software Engineering 
 
//‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ 
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action) 
6. El archivo cabecera Unit2.h ... 

// TERMINAMOS EL THREAD.  //‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ 
ReadThread‐>Terminate();  #ifndef Unit2H 
// ESPERAMOS QUE TERMINE Y CERRAMOS EL PUERTO  #define Unit2H 
Sleep(250);   
PurgeComm(hComm, PURGE_RXABORT);  //‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ 
SetCommTimeouts(hComm, &ctmoOld);  #include <Classes.hpp> 
CloseHandle(hComm);   
}  //‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ 
  class TRead : public TThread 
//‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐  { 
void __fastcall TForm1::Memo1KeyPress(TObject *Sender, char &Key)  private: 
{  protected: 
// TRANSMITE CUALQUIER COSA ESCRITA EN EL MEMO  void __fastcall DisplayIt(void); 
TransmitCommChar(hComm, Key);  void __fastcall Execute(); 
// ESTO PREVEE LA VISUALIZACION DE CARACTERES “BASURA” EN LA PANTALLA  public: 
if(Key != 13 && (Key < ' ' || Key > 'z'))  __fastcall TRead(bool CreateSuspended); 
Key = 0;  }; 
}  //‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ 
//‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐   
#endif 

5. El código fuente de la Unit2.cpp... 
//‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ 
#include <vcl.h>  Para  probar  el  ejemplo,  se  puede  enlazar  los  pines  2  y  3  del  RS‐
#pragma hdrstop 
// SE DEBE INCLUIR LA CABECERA DE LA UNIT1 
232,  o  bien,  escribir  algún  comando  Hayes  hacia  el  puerto  del 
#include "Unit1.h"  modem (un ATZ por ejemplo). 
#include "Unit2.h" 
extern HANDLE hComm; 
char InBuff[100]; 
#pragma package(smart_init) 
 
//‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ 
// Important: Methods and properties of objects in VCL can only be 
// used in a method called using Synchronize, for example: 
// 
// Synchronize(UpdateCaption); 
// 
// where UpdateCaption could look like: 
// 
// void __fastcall TRead::UpdateCaption() 
// { 
// Form1‐>Caption = "Updated in a thread"; 
// } 
 
//‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ 
__fastcall TRead::TRead(bool CreateSuspended) 
: TThread(CreateSuspended) 


 
//‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ 
void __fastcall TRead::DisplayIt() 

// EN ESTE EJEMPLO NO SE TIENE EN CUENTA CUANTO TEXTO HA ENTRADO EN EL 
// Memo1 QUE PUEDE SER SOLO DE 32K. 
// TAMPOCO SE HACE NADA CON LOS CARACTERES NO IMPRIMIBLES 
// MUESTRA EL TEXTO RECIBIDO 
Form1‐>Memo1‐>SetSelTextBuf(InBuff); 

 
//‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ 
void __fastcall TRead::Execute() 

//‐‐‐‐ Place thread code here ‐‐‐‐ 
DWORD dwBytesRead; 
// HACE QUE EL OBJETO TRHEAD SEA DESTRUIDO CUANDO EL THREAD TERMINA 
FreeOnTerminate = true; 
while(1){ 
// INTENTA LEER DEL PUERTO SERIE 
// Y SI HAY ALGO LO VISUALIZA 
ReadFile(hComm, InBuff, 50, &dwBytesRead, NULL); 
if(dwBytesRead){ 
InBuff[dwBytesRead] = 0; // ACABA LA CADENA EN 
NULO 
Synchronize(DisplayIt); 



//‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐

Página  2  Álvaro Pinto Torrejón
http://www.alternext.com.bo  apinto@alternext.com.bo 
 

Você também pode gostar