Link to home
Start Free TrialLog in
Avatar of DanRaposo
DanRaposoFlag for United States of America

asked on

A simple windows app to open and write to COM1

Hi experts,

I was hoping someone could just provide a simple Visual Studio C++ app that just opens and writes a series of hex values out the COM1 port.  I am linux programmer and have never touch VS.  I am trying to wirte a test app that simulates a device to test an embedded device that I have programed.  This app needs to be run on a windows machine that is why I am using Visual c++.

Thanks
Avatar of jkr
jkr
Flag of Germany image

See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwbgen/html/msdn_serial.asp ("Serial Communications in Win32"), this article comes with full source code that demonstrates (among other things) what you want.
BTW, see also

http://www.codeproject.com/system/chaiyasit_t.asp ("Creating a Serial communication on Win32")
http://www.codeproject.com/system/SerialPortComm.asp ("Non Overlapped Serial Port Communication using Win32")

and finally

http://www.codeproject.com/system/serial.asp ("Serial library for C++")
Avatar of DanRaposo

ASKER

ok, so I checked that stuff out and this is what I came up with

// IGT_Sim.cpp : Defines the entry point for the console application.
//

#include "StdAfx.h"
#include <iostream.h>
#include <stdio.h>
#include <windows.h>


int main()
{
      HANDLE HdComm;
      DWORD DwError;
      DCB Dcb;
      char Msg[128];
      DWORD RealNum;

      printf("Starting the IGT Sim\n");

      // Open the COMM port.
      HdComm = CreateFile( "//.//COM1", GENERIC_READ | GENERIC_WRITE, 0,
                                          NULL, OPEN_EXISTING, 0, NULL );
      if ( HdComm == INVALID_HANDLE_VALUE ) // If COMM port can't be opened, then ...
      {
            DwError = GetLastError();  // Display error code, and abort.
            FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, 0, DwError, 0, (char *)Msg, 124, 0 );
            printf( "Cannot Open Port COM1 !\nError Code: %d, - %s.\n", DwError, Msg );

            return 1;
      }
      else
      {
            printf("COM port opened successfully");
      }

      // Initialize COMM port.
      SetupComm( HdComm, 1024, 1024 );
      GetCommState( HdComm, &Dcb );
      Dcb.BaudRate = BAUD_9600;
      Dcb.Parity = NOPARITY;
      Dcb.ByteSize = 8;
      //Dcb.StopBits = ONESTOPBIT;
      SetCommState( HdComm, &Dcb );

      char message[5] = {0x32, 0x00, 0x01, 0x61, 0x52};

      while (1) {
            WriteFile( HdComm, message, 5, &RealNum, NULL );
            printf("%d\n", RealNum);
            Sleep(300);
      }
      CloseHandle( HdComm );
      return 0;
}

It tells me that it is writing 5 bytes, but I am not seeing it go over the serial connection.  Could someone let me know what is wrong with this?

Thanks
Try to 'FlushFileBuffers(HdComm);' to ensure they're actually sent over the port.
sorry to be stupid, but where should i put that.  I put it in my while but didn't see anything.
Yes, that would be the place. But, I think I spotted the problem. By using

     SetupComm( HdComm, 1024, 1024 );

you make the UART buffer up to 1024 bytes - use

     SetupComm( HdComm, 0, 0);

insted to eliminate the buffering.
hmmm still didn't work
here is my code now....

// IGT_Sim.cpp : Defines the entry point for the console application.
//

#include "StdAfx.h"
#include <iostream.h>
#include <stdio.h>
#include <windows.h>


int main()
{
      HANDLE HdComm;
      DWORD DwError;
      DCB Dcb;
      char Msg[128];
      DWORD RealNum;

      printf("Starting the IGT Sim\n");

      // Open the COMM port.
      HdComm = CreateFile( "COM1", GENERIC_READ | GENERIC_WRITE, 0,
                                     NULL, OPEN_EXISTING, 0, NULL );
      if ( HdComm == INVALID_HANDLE_VALUE ) // If COMM port can't be opened, then ...
      {
            DwError = GetLastError();  // Display error code, and abort.
            FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, 0, DwError, 0, (char *)Msg, 124, 0 );
            printf( "Cannot Open Port COM1 !\nError Code: %d, - %s.\n", DwError, Msg );

            return 1;
      }
      else
      {
            printf("COM port opened successfully");
      }

      // Initialize COMM port.
      SetupComm( HdComm, 0, 0 );
      GetCommState( HdComm, &Dcb );
      Dcb.BaudRate = BAUD_9600;
      Dcb.Parity = NOPARITY;
      Dcb.ByteSize = 8;
      Dcb.StopBits = ONESTOPBIT;
      SetCommState( HdComm, &Dcb );

      char message[5] = {0x32, 0x00, 0x01, 0x61, 0x52};

      while (1) {
            WriteFile( HdComm, (char*)message, 5, &RealNum, NULL );
            printf("%d\n", RealNum);
            Sleep(300);
            FlushFileBuffers(HdComm);
      }
      CloseHandle( HdComm );
      return 0;
}
ASKER CERTIFIED SOLUTION
Avatar of jkr
jkr
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
i believe so...here are the settings on the other end....in the embedded linux board

this->fd = ACE_OS::open( this->serialPort, O_RDWR | O_NDELAY );
   if (fd != -1) {
      tcgetattr( fd, &stTermios );
      memset( &stTermios, 0, sizeof(stTermios));
      cfsetispeed( &stTermios, B9600 );
      cfsetospeed( &stTermios, B9600 );

      stTermios.c_cc[VMIN] = 1;
      stTermios.c_cc[VTIME] = 0;
      stTermios.c_cflag &= ~(PARENB|CSTOPB|CSIZE|CRTSCTS); // 8 bits, no parity, Disable hardware flow control
      stTermios.c_cflag |= (CLOCAL | CREAD |CS8);          // Select 8 data bits
      stTermios.c_lflag &= ~(ICANON | ECHO | ISIG);        // set raw mode for input
      stTermios.c_iflag &= ~(IXON | IXOFF | IXANY|INLCR|ICRNL|IUCLC);   //no software flow control
      stTermios.c_oflag &= ~OPOST;                         //raw output

      if ( tcsetattr( this->fd, TCSAFLUSH, &stTermios ) != 0 ) {
         fbError=errno;
      }
   } else {
      fbError = errno;
   }
SWEET!!!

BuildCommDCB("baud=9600 parity=N data=8 stop=1",&Dcb);

fixed the problem...working now!

Thanks!
Great! ;o)