Thread: Serial Communications in C

  1. #1
    Registered User ExDigit's Avatar
    Join Date
    Jan 2002

    Serial Communications in C

    How is it possible to write to and read from the serial cable (aka null modem) in C (in Windows)? Assuming the cable is attatched to COM port 1 for example..

    I know that in QBasic (yeah, it's DOS, but hey) you'd do:

    OPEN "COM1:9600, N, 8, 1" FOR RANDOM AS #1
    CLOSE #1

    But how is this possible in C?

  2. #2
    HANDLE com1 =CreateFile( "COM1",
    0, /*mandatory*/
    OPEN_EXISTING, /* mandatory*/
    NULL}: /*mandatory*/

    opens a handle; then use ReadFile and WriteFile.

  3. #3
    Caffienated jinx's Avatar
    Join Date
    Oct 2001
    Also, what code would you use to send a file to a disk in the A:\ drive, using the ifstream/ofstream method?

  4. #4
    Registered User
    Join Date
    Dec 2001

    Platform SDK/Windows Base Services/Files and I/O/Communications

    in MSDN help for more about programming serial ports in Windows.

  5. #5
    Registered User (TNT)'s Avatar
    Join Date
    Aug 2001
    Hey Jinx

    To Use ofstream to output a file to drive a: do this:

    ofstream fin("a:\\file.txt", ios::app);
    //send text to be in file, or you could read file to send into buffer
    //then send the buffer into the output stream fin.
    fin<<"Hello This Is In The File :)"
    That should work, i think you need fstream.h but check with msdn.

    Hope that helps
    Last edited by (TNT); 01-04-2002 at 12:16 PM.
    You Can Stop Me, But You Cant Stop Us All

  6. #6
    Caffienated jinx's Avatar
    Join Date
    Oct 2001
    Nope. I have no errors, but also have no file on the a:\

  7. #7
    Just one more wrong move. -KEN-'s Avatar
    Join Date
    Aug 2001
    and for all of you without MSDN, here's what in there:

    Configuring a Communications Resource
    The following example opens a handle to COM1 and fills in a DCB structure with the current configuration. The DCB structure is then modified and used to reconfigure the device. 
    DCB dcb;
    HANDLE hCom;
    DWORD dwError;
    BOOL fSuccess;
    hCom = CreateFile( "COM1",
        0,    // comm devices must be opened w/exclusive-access 
        NULL, // no security attributes 
        OPEN_EXISTING, // comm devices must use OPEN_EXISTING 
        0,    // not overlapped I/O 
        NULL  // hTemplate must be NULL for comm devices 
    if (hCom == INVALID_HANDLE_VALUE) 
        dwError = GetLastError();
        // handle error 
    // Omit the call to SetupComm to use the default queue sizes.
    // Get the current configuration.
    fSuccess = GetCommState(hCom, &dcb);
    if (!fSuccess) 
        // Handle the error. 
    // Fill in the DCB: baud=9600, 8 data bits, no parity, 1 stop bit. 
    dcb.BaudRate = 9600;
    dcb.ByteSize = 8;
    dcb.Parity = NOPARITY;
    dcb.StopBits = ONESTOPBIT;
    fSuccess = SetCommState(hCom, &dcb);
    if (!fSuccess) 
        // Handle the error. 
    Monitoring Communications Events
    The following example code opens the serial port for overlapped I/O, creates an event mask to monitor CTS and DSR signals, and then waits for an event to occur. The WaitCommEvent function should be executed as an overlapped operation so the other threads of the process cannot perform I/O operations during the wait. 
    HANDLE hCom;
    BOOL fSuccess;
    DWORD dwEvtMask;
    hCom = CreateFile( "COM1",
        0,    // exclusive access 
        NULL, // no security attributes 
    if (hCom == INVALID_HANDLE_VALUE) 
        // Handle the error. 
    // Set the event mask. 
    fSuccess = SetCommMask(hCom, EV_CTS | EV_DSR);
    if (!fSuccess) 
        // Handle the error. 
    // Create an event object for use in WaitCommEvent. 
    o.hEvent = CreateEvent(
        NULL,   // no security attributes 
        FALSE,  // auto reset event 
        FALSE,  // not signaled 
        NULL    // no name 
    if (WaitCommEvent(hCom, &dwEvtMask, &o)) 
        if (dwEvtMask & EV_DSR) 
             // To do.
        if (dwEvtMask & EV_CTS) 
             // To do. 
    Modification of Communications Resource Settings
    When the CreateFile function opens a handle to a serial communications resource, the system initializes and configures the resource according to the values set up the last time the resource was opened. Preserving the previous settings enables the user to retain the settings specified through an mode command when the device is reopened. The values inherited from the previous open operation include the configuration settings of the device control block (a DCB structure) and the time-out values used in I/O operations. If the device has never been opened, it is configured with the system defaults.

    To determine the initial configuration of a serial communications resource, a process calls the GetCommState function, which fills in a serial port DCB structure with the current configuration settings. To modify this configuration, a process specifies a DCB structure in a call to the SetCommState function.

    Members of the DCB structure specify the configuration settings such as the baud rate, the number of data bits per byte, and the number of stop bits per byte. Other DCB members specify special characters and enable parity checking and flow control. When a process needs to modify only a few of these configuration settings, it should first call GetCommState to fill in a DCB structure with the current configuration. Then the process can adjust the important values in the DCB structure and reconfigure the device by calling SetCommState and specifying the modified DCB structure. This procedure ensures that the unmodified members of the DCB structure contain appropriate values. For example, a common error is to configure a device with a DCB structure in which the structure's XonChar member is equal to the XoffChar member.

    The BuildCommDCB function provides another way to modify a DCB structure. BuildCommDCB uses a string with the same form as the command-line arguments of the mode command to specify the baud rate, parity scheme, number of stop bits, and number of data bits. The remaining members of DCB are not changed by this function, except that the appropriate members are set to disable XON/XOFF and hardware flow control. BuildCommDCB only modifies a DCB structure; it does not reconfigure the device.

    A process can reconfigure a communications resource by using the GetCommProperties function to get information from a device driver about the configuration settings that it supports. The process can use this information to avoid specifying a configuration that is not supported.

    The SetCommState function reconfigures the communications resource, but it does not affect the internal output and input buffers of the specified driver. The buffers are not flushed, and pending read and write operations are not terminated prematurely.

    A process reinitializes a communications resource by using the SetupComm function, which performs the following tasks:

    Terminates pending read and write operations, even if they have not been completed.
    Discards unread characters and frees the internal output and input buffers of the driver associated with the specified resource.
    Reallocates the internal output and input buffers.
    A process is not required to call SetupComm. If it does not, the resource's driver initializes the device with the default settings the first time that the communications resource handle is used.

    Communications Resource Configuration
    The COMMCONFIG structure defines the configuration of a communications resource, serial or otherwise. The format of the structure varies depending on the type of communications resource (the provider subtype). The first few structure members are common to all communications resources; additional members are defined for specific provider subtypes. Specific service providers may extend the COMMCONFIG structure as well.

    An application can get and set the configuration of a communications resource by using the GetCommConfig and SetCommConfig functions. When opened, a communications resource is initialized using the default configuration for its provider subtype. To get and set the default configuration for a provider subtype, use the GetDefaultCommConfig and SetDefaultCommConfig functions.

    To prompt the user for configuration information, use the CommConfigDialog function. This function displays a dialog box defined by the service provider and fills in a COMMCONFIG structure based on user input.

    Modem Configuration
    Modem configuration functions enable you to configure a modem before making a connection. An application can set modem options and determine the features of a modem without using commands specific to any modem device. Following are the general features an application may set before making a call:

    Primary mode of operation (synchronous, asynchronous, and whether error control is enabled).
    V.42 error control (defined by CCITT recommendation V.42), including specific parameters. CCITT stands for the International Telegraph and Telephone Consultative Committee.
    V.42bis (defined by CCITT recommendation V.42bis) and MNP5 data compression.
    Time-out options, including call setup, inactivity, and buffered data delivery.
    Before setting a modem's configuration, an application should determine the capabilities of the modem device by using the GetCommProperties function. This function fills in a COMMPROP structure. This structure contains both a general portion, which applies to all communications devices, and a portion that is specific to each provider subtype. For modem devices, the provider-specific portion of the COMMPROP structure is a MODEMDEVCAPS structure.

    An application can get and set the current configuration of a modem by using the GetCommConfig and SetCommConfig functions, both of which use a COMMCONFIG structure. This structure contains both a general portion, which applies to all communications devices, and a portion that is specific to each provider subtype. For modem devices, the provider-specific portion of the COMMCONFIG structure is a MODEMSETTINGS structure.

    After configuring a modem, an application can use the Telephony Application Programming Interface (TAPI) to actually establish a connection.

    The modem configuration functions do not provide for long-term management and maintenance of a modem. Modem service providers should supply modem configuration dialog boxes for this purpose.

    A handle to a communications resource has an associated set of time-out parameters that affect the behavior of read and write operations. Time-outs can cause a ReadFile, ReadFileEx, WriteFile, or WriteFileEx operation to conclude when a time-out interval elapses, even though the specified number of characters have not been read or written. It is not treated as an error when a time-out occurs during a read or write operation (that is, the read or write function's return value indicates success). The count of bytes actually read or written is reported by ReadFile or WriteFile (or by the GetOverlappedResult or FileIOCompletionRoutine function, if the I/O was performed as an overlapped operation).

    When an application opens a communications resource, the system sets the resource's time-out values to the values in effect when the resource was last used. If the communications resource has never been opened, the system sets the time-out values to some default value. In either case, an application should always determine the current time-out values after opening the resource, and then explicitly set them to meet its requirements. To determine the current time-out values of a communications resource, use the GetCommTimeouts function. To change the time-out values, use the SetCommTimeouts function.

    Two types of time-outs are enabled by the time-out parameters. An interval time-out occurs when the time between the receipt of any two characters exceeds a specified number of milliseconds. Timing starts when the first character is received and is restarted when each new character is received. A total time-out occurs when the total amount of time consumed by a read operation exceeds a calculated number of milliseconds. Timing starts immediately when the I/O operation begins. Write operations support only total time-outs. Read operations support both interval and total time-outs, which can be used separately or combined.

    The time, in milliseconds, of the total time-out period for a read or write operation is calculated by using the multiplier and constant values from the COMMTIMEOUTS structure specified in the GetCommTimeouts or SetCommTimeouts function. The following formula is used:

    Timeout = (MULTIPLIER * number_of_bytes) + CONSTANT

    Using both a multiplier and a constant enables the total time-out period to vary, depending on the amount of data being requested. An application can use only the constant by setting the multiplier to zero, or use only the multiplier by setting the constant to zero. If both the constant and multiplier are zero, total time-out is not used.

    If all read time-out parameters are zero, read time-outs are not used, and a read operation is not complete until the requested number of bytes have been read or an error occurs. Similarly, if all write time-out parameters are zero, a write operation is not completed until the requested number of bytes have been written or an error occurs.

    If the read interval time-out parameter is the MAXDWORD value and both read total time-out parameters are zero, a read operation is completed immediately after reading whatever characters are available in the input buffer, even if it is empty.

    Interval timing forces a read operation to return when there is a lull in reception. A process using interval time-outs can set a fairly short interval parameter, so it can respond quickly to small, isolated bursts of one or a few characters, yet it can still collect large buffers of characters with a single call when data is received in a steady stream.

    Time-outs for a write operation can be useful when transmission is blocked by some kind of flow control or when the SetCommBreak function has been called to suspend character transmission.

    The following table summarizes the behavior of read operations based on the values specified for total and interval time-outs.

    Total Interval Behavior
    0 0 Returns when the buffer is completely filled. Time-outs are not used.
    T 0 Returns when the buffer is completely filled or when T milliseconds have elapsed since the beginning of the operation.
    0 Y Returns when the buffer is completely filled or when Y milliseconds have elapsed between the receipt of any two characters. Timing does not begin until the first character is received.
    T Y Returns when the buffer is completely filled or when either type of time-out occurs.

    Note, however, that timing is relative to the system controlling the physical device. For a remote device such as a modem, the timing is relative to the server system to which the modem is attached. Any network propagation delay is not factored in. For example, a client application might specify a total time-out that computes to be 500 milliseconds. When 500 milliseconds have elapsed at the server, a time-out error is returned to the client. If there is a 50 milliseconds network propagation delay, the client will not be notified of the time-out until approximately 50 milliseconds after the time-out actually occurred.

    The time-out parameters affect the behavior of overlapped read and write operations on a communications device. With overlapped I/O, the ReadFile, WriteFile, ReadFileEx, or WriteFileEx function can return before the operation has been completed. The time-out parameters can determine when the operation has been completed.

    Communication Functions
    The following functions are used with communications devices.


    Communication Structures
    The following structures are used with communications devices.


    I know that's not EVERYTHING in there, but there were way too many pages to put everything up.
    Last edited by -KEN-; 01-05-2002 at 09:59 AM.

  8. #8
    Registered User
    Join Date
    Jan 2002

    When writing a text file to the a: drive, you will need to include fstream.h or it will fail. Also, you may want to consider using an endl at the end of your output stream, like this:

    #include <fstream.h>

    void main(void)
    ofstream outfile("a:\\file.txt", ios::app); /*this will always append the file, if you want it to overwrite each time you can simply use ofstream outfile("a:\\file.txt"); or
    ofstream outfile("a:\\file.txt",ios::write);*/

    outfile << "Your text appears here" << endl;

    Hope that helps!


Popular pages Recent additions subscribe to a feed

Similar Threads

  1. serial port to poll on request
    By infineonintern in forum C++ Programming
    Replies: 2
    Last Post: 06-11-2009, 06:52 AM
  2. Lame null append cause buffer to crash
    By cmoo in forum C Programming
    Replies: 8
    Last Post: 12-29-2008, 03:27 AM
  3. Serial Communications w/API
    By john6304 in forum C++ Programming
    Replies: 2
    Last Post: 10-11-2005, 07:27 AM
  4. Serial Communications with win32 api
    By Blackthorne in forum C Programming
    Replies: 1
    Last Post: 01-26-2003, 12:45 PM
  5. DOS, Serial, and Touch Screen
    By jon_nc17 in forum A Brief History of
    Replies: 0
    Last Post: 01-08-2003, 04:59 PM