Un lugar de encuentro para los programadores de habla hispana

Un lugar de encuentro para los programadores de habla hispana

Buscar

Entrar

Puedes acceder utilizando tu cuenta de usuario del foro.

Si no dispone de cuenta, puede crear una accediendo al formulario de registro del foro.



Cómo escribir en el puerto COM1 o COM2 Imprimir
Ideas - Delphi

Los puertos COM en Windows se tratan de manera similar a otros dispositivos (archivos en disco, pipes, etc.). Como cualquier otro dispositivo, un puerto necesita un manejador o 'Handle' para ser utilizado. Sería como un identificador del dispositivo. Este manejador te lo proporciona la función del API de Windows CreateFile() que, aunque parezca lo contrario, no se limita a "crear" y no trabaja sólo con "files", sino que permite hacer otras operaciones y con otros dispositivos. A esta función se le debe especificar el nombre del dispositivo a abrir (el archivo de disco, el puerto serie o paralelo, etc.).

Una vez obtenido el manejador, podemos leer y escribir en el dispositivo con las funciones del API de Windows ReadFile() y WriteFile(), respectivamente. Finalmente, se cierra el puerto con la función del API CloseHandle() (como se ve, demasiado 'file' para acabar con un 'handle': ¿porqué no un CloseFile()? Preguntadle a Microsoft :-)

En fin, ahí va un ejemplo de código:

 
uses
  Windows;    // Sobretodo
procedure TForm1.AbrirCom_Escribir_y_Leer;
const
  NombrePuerto = 'COM2';   // Por decir algo
var
  HandlePuerto: THandle;   // Manejador para el puerto
  Cadena: String;          // Para leer del puerto
  dwValor: DWORD;          // Tamaño de la lectura
  Sta: COMSTAT;            // Estado o tamaño del buffer de lectura
  bResult: Boolean;        // Parámetro de resultado
begin
  // ~~~~~~~~~~~~~~~~~~~
  // Apertura del puerto
  // ~~~~~~~~~~~~~~~~~~~
  //
  // El puerto ha de abrirse con acceso exclusivo. Es una de las razones de que haya
  // un sólo "Acceso telefónico a redes" que actúa de servidor del puerto. Generalmente
  // también se abre con acceso de lectura y escritura ya que es extraño tener que leer
  // o escribir sólo en él. Pero, claro, esto depende de lo que vayas a hacer con el
  // mismo. El "solapamiento" se produce sólo si hay varios procesos que pueden acceder
  // al puerto a la vez y se utiliza cuando la aplicación tiene, por ejemplo, un hilo
  // para leer y otro para escribir. Presupongo que no es el caso y que sólo hay un hilo.
  // El último parámetro ('hTemplate') no tiene efecto para los puertos de comunicaciones.
  //
  HandlePuerto := Windows.CreateFile(
                     PChar(NombrePuerto), { Nombre del puerto }
                     GENERIC_READ or
                     GENERIC_WRITE,       { Modo de apertura: Lectura/Escritura }
                     0,                   { Acceso exclusivo }
                     nil,                 { Sin atributos de seguridad }
                     OPEN_EXISTING,       { El puerto debe existir }
                     0,                   { Sin solapamiento de Lectura/Escritura }
                     0);                  { No hay "hTemplate" }
 
  // Comprobar que la apertura ha sido correcta
  if (INVALID_HANDLE_VALUE <> HandlePuerto) then
  begin
    // Vamos a ver si hay algo que leer...
    if (Windows.ClearCommError(HandlePuerto, dwValor, @Sta)) then
    begin
      if (0 < Sta.cbInQue) then    //... pues s&iacute;
      begin
        // ~~~~~~~~~~~~~~~
        // Leer del puerto
        // ~~~~~~~~~~~~~~~
        // Redimensionar la cadena de lectura
        SetLength(Cadena, (Sta.cbInQue + 1));
        bResult := Windows.ReadFile(
                       HandlePuerto,   { Handle del puerto }
                       PChar(Cadena)^, { Puntero a los datos a leer }
                       Sta.cbInQue,    { Tama&ntilde;o del buffer de lectura }
                       dwValor,        { N&uacute;mero de caracteres le&iacute;dos }
                       nil);           { No hay lecturas/escrituras solapadas }
 
        if (bResult) then  // Lectura correcta
        begin
          // Dimensionar la cadena al n&uacute;mero de bytes le&iacute;dos
          SetLength(Cadena, dwValor);
          // Aqu&iacute; se puede hacer lo que se quiera con 'Cadena'
        end;
      end;
    end;
 
    // ~~~~~~~~~~~~~~~~~~~~~
    // Escribir en el puerto
    // ~~~~~~~~~~~~~~~~~~~~~
    // En general, los puertos de comunicaciones esperan un retorno de carro
    // tras lo que se env&iacute;e. Tiene que ver con los b&uacute;feres del puerto: cuando
    // se llena el buffer hasta un nivel o se recibe el retorno de carro se
    // env&iacute;a el contenido del buffer al puerto. As&iacute; que, para asegurarse, se
    // termina la cadena a escribir por esos caracteres:
    Cadena := 'Probando la escritura' + #13#10;
    if (Windows.WriteFile(
           HandlePuerto,   { Handle del puerto }
           PChar(Cadena)^, { Datos a escribir }
           Length(Cadena), { Longitud de los datos }
           dwValor,        { N&uacute;mero de caracteres escritos }
           nil)            { Sin solapamiento de lecturas/escrituras }
       )
    then
    begin
      // Aqu&iacute; nos damos con un canto en los dientes:
      // la 'Cadena' se ha escrito en el puerto. Podemos comprobarlo si
      // miramos 'dwValor' ya que debe ser igual a 'Length(Cadena)'.
      // Si no lo es, algo ha ido mal.
    end;
 
    // ~~~~~~~~~~~~~~~~
    // Cerrar el puerto
    // ~~~~~~~~~~~~~~~~
    Windows.CloseHandle(HandlePuerto);
  end;
end;
 
 
 
Comentarios (0)
Para escribir un comentario debes estar registrado