如何在Windows中进行串行通信? [英] How Do I Do A Serial Communication In Windows?

查看:84
本文介绍了如何在Windows中进行串行通信?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要编写一个用于串行通信的C代码,用于将数据字节从计算机发送到外部设备。我正在使用USB RS232转换器进行传输。需要注意什么?有人可以给我建议吗?

I need to write a C code for serial communication for sending bytes of data from computer to external device.i am using USB RS232 convertor for transmission. What needs to be taken care of? Can someone give me advice??

推荐答案

MSDN提供了一篇关于此的文章:SerialCommunications [ ^ ]。这是相当古老的(1995年),但仍然有效。



MSDN中也可以找到串行通信功能的概述:通讯功能 [ ^ ]。您还可以从左侧树中读取其他页面。



使用USB转RS232转换器提供的虚拟COM端口通常没有问题。
The MSDN provides an article about this: SerialCommunications[^]. It is quite old (1995) but still valid.

An overview of serial communication functions can be also found in the MSDN: Communication Functions[^]. You may also read the other pages from the tree on the left.

There are usually no problems using the virtual COM port provided by an USB to RS232 converter.


查看文章 Win32 SDK Serial Comm Made Easy 创建一个Win32上的串行通信和它的代码。在你明白这些端口很慢的情况下开始并不容易,所以你和你的应用必须等待答案。我使用了比重叠IO来解决这个问题。
Take a look on the article Win32 SDK Serial Comm Made Easy or Creating a Serial communication on Win32 amd its code. It isnt easy to start until you understand that theses ports are slow, so you and your app must wait for answers. I used than overlapped IO to solve that.


这里有一些代码来自一个简单的win32串口监视器,我把它一起用于Atmel系列微控制器,特别是用于使用与Arduinos。



我会留给你为你自己的控制台应用程序提取你想要的部分。正如你所看到的,我从不打扰实现Stop按钮 - 我只是杀了然后重启程序。 (我确实说它被黑了,记得!:))



代码也使用Code :: Blocks构建



编辑:注意onStartButton代码 - 刚才意识到我实际上并没有使用速度,停止位等值 - 我应该将它们设置为DCB。



1. main.cpp

Here's some code from a simple win32 serial-port monitor I hacked-together for use with the Atmel family of micro-controllers, specifically, for use with Arduinos.

I'll leave it to you to extract the parts you want for your own console app. As you can see, I never bothered to implement the Stop button - I just kill then restart the program. (I did say it was hacked-together, remember! :) )

The code was also built using Code::Blocks

pay attention to the onStartButton code - just realized I don't actually use the values for speed, stop bits etc - I should be setting these to the DCB.

1. main.cpp
#include <ctype.h>
#include <windows.h>
#include <commctrl.h>
#include <stdio.h>
#include "resource.h"

HINSTANCE hInst;


int availRates[] = {300, 600, 1200, 1800, 2400, 4800, 7200, 9600, 14400, 19200, 38400, 57600, 115200, 230400, 460800, 921600};
int numBits[] = {7,8};
int stopBits[] = {1,2};
const char *parity[] = {"Even", "Odd", "None", "Mark", "Space"};
HWND dlgHwnd;

typedef struct threadData_t
{
    HWND callbackWnd;

};

void initIntCombo(HWND combo, int *dataArray, int numElements)
{
    int i;
    char tmpStr[16];
    for (i=0; i<numElements; i++)
    {
        sprintf(tmpStr, "%d", dataArray[i]);
        SendMessage(combo, CB_ADDSTRING, 0, (LPARAM)tmpStr);
    }
}

void initStrCombo(HWND combo, const char *dataArray[], int numElements)
{
    for (int i=0; i<numElements; i++)
        SendMessage(combo, CB_ADDSTRING, 0, (LPARAM)dataArray[i]);//tmpStr);
}

void initPortCombo(HWND combo)
{
    int curPort;
    char mPortName[16];
    HANDLE hCom;

    for (curPort=1; curPort<=20; curPort++)
    {
        sprintf(mPortName, "\\\\.\\COM%d", curPort);
        hCom = CreateFile(mPortName, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
        if (hCom != INVALID_HANDLE_VALUE)
        {
            sprintf(mPortName, "COM%d", curPort);
            CloseHandle(hCom);
            SendMessage(combo, CB_ADDSTRING, 0, (LPARAM)mPortName);
        }
    }
}

void onStartButton()
{
    HWND baudCombo, dataBitsCombo, parityCombo, stopBitsCombo;
    int baud, nBits, stopBits;
    char parityLetter;
    char dcbString[32], dcbStrUsed[32];
    int selectedParityOption;

    baud = GetDlgItemInt(dlgHwnd, IDC_BAUDRATE_COMBO, NULL, true);
    nBits = GetDlgItemInt(dlgHwnd, IDC_DATABITS_COMBO, NULL, true);
    stopBits = GetDlgItemInt(dlgHwnd, IDC_STOPBITS_COMBO, NULL, true);

    selectedParityOption = SendDlgItemMessage(dlgHwnd, IDC_PARITY_COMBO, CB_GETCURSEL, 0, 0);
    parityLetter = tolower(parity[selectedParityOption][0]);

    sprintf(dcbString, "Success\r\n- %d,%c,%d,%d\r\n", baud, parityLetter, nBits, stopBits);
    sprintf(dcbStrUsed, "%d,%c,%d,%d", baud, parityLetter, nBits, stopBits);

    DCB dcb;
    FillMemory(&dcb, sizeof(dcb), 0);
    dcb.DCBlength = sizeof(dcb);
    if (!BuildCommDCB(dcbStrUsed, &dcb))
        SetWindowText(GetDlgItem(dlgHwnd, IDC_EDIT1) , "Failed");
    else
        //SetWindowText(GetDlgItem(dlgHwnd, IDC_EDIT1) , dcbString);
        SendDlgItemMessage(dlgHwnd, IDC_EDIT1, EM_REPLACESEL, true, (LPARAM)dcbString);
}


BOOL CALLBACK DlgMain(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch(uMsg)
    {
    case WM_INITDIALOG:
    {
        dlgHwnd = hwndDlg;
        initPortCombo(GetDlgItem(hwndDlg, IDC_PORTNAME_COMBO));

        initIntCombo(GetDlgItem(hwndDlg, IDC_BAUDRATE_COMBO), availRates, sizeof(availRates) / sizeof(availRates[0]));
        SendMessage(GetDlgItem(hwndDlg, IDC_BAUDRATE_COMBO), CB_SETCURSEL, 7, 0); // set 9600 bps

        initIntCombo(GetDlgItem(hwndDlg, IDC_DATABITS_COMBO), numBits, sizeof(numBits) / sizeof(numBits[0]));
        SendMessage(GetDlgItem(hwndDlg, IDC_DATABITS_COMBO), CB_SETCURSEL, 1, 0); // set 8 data bits

        initIntCombo(GetDlgItem(hwndDlg, IDC_STOPBITS_COMBO), stopBits, sizeof(stopBits) / sizeof(stopBits[0]));
        SendMessage(GetDlgItem(hwndDlg, IDC_STOPBITS_COMBO), CB_SETCURSEL, 0, 0); // set 1 stop bit

        initStrCombo(GetDlgItem(hwndDlg, IDC_PARITY_COMBO), parity, sizeof(parity) / sizeof(parity[0]));
        SendMessage(GetDlgItem(hwndDlg, IDC_PARITY_COMBO), CB_SETCURSEL, 2, 0); // set 9600 bps
    }
    return TRUE;

    case WM_CLOSE:
    {
        EndDialog(hwndDlg, 0);
    }
    return TRUE;

    case WM_DEVICECHANGE:
        SendDlgItemMessage(hwndDlg, IDC_PORTNAME_COMBO, CB_RESETCONTENT, 0, 0);
        initPortCombo(GetDlgItem(hwndDlg, IDC_PORTNAME_COMBO));
        break;

    case WM_COMMAND:
    {
        switch(LOWORD(wParam))
        {
            case IDC_BUTTON1:
                onStartButton();
                break;
            case IDC_BUTTON3:
                SetDlgItemText(hwndDlg, IDC_EDIT1, "");
                break;
        }
    }
    return TRUE;
    }
    return FALSE;
}


int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
    hInst=hInstance;
    InitCommonControls();
    return DialogBox(hInst, MAKEINTRESOURCE(DLG_MAIN), NULL, (DLGPROC)DlgMain);
}







2. resource.h




2. resource.h

#ifndef IDC_STATIC
#define IDC_STATIC (-1)
#endif

#define DLG_MAIN                                100
#define IDC_BUTTON3                             1000
#define IDC_DATABITS_COMBO                      1007
#define IDC_PORTNAME_COMBO                      1008
#define IDC_BAUDRATE_COMBO                      1009
#define IDC_PARITY_COMBO                        1010
#define IDC_STOPBITS_COMBO                      1011
#define IDC_BUTTON1                             1012
#define IDC_BUTTON2                             1013
#define IDC_EDIT1                               1014





3. resource.rc



3. resource.rc

// Generated by ResEdit 1.5.8
// Copyright (C) 2006-2011
// http://www.resedit.net

#include <windows.h>
#include <commctrl.h>
#include <richedit.h>
#include "resource.h"

//
// Dialog resources
//
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
DLG_MAIN DIALOG 0, 0, 369, 303
STYLE DS_3DLOOK | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_CAPTION | WS_VISIBLE | WS_POPUP | WS_SYSMENU
CAPTION "Serial Monitor v0.01"
FONT 8, "Ms Shell Dlg"
{
    GROUPBOX        "Serial Port settings", IDC_STATIC, 15, 14, 166, 116
    LTEXT           "Port Name", IDC_STATIC, 36, 29, 34, 8, SS_LEFT
    LTEXT           "Baud Rate", IDC_STATIC, 35, 48, 35, 8, SS_LEFT
    LTEXT           "Data Bits", IDC_STATIC, 40, 67, 30, 8, SS_LEFT
    LTEXT           "Parity", IDC_STATIC, 52, 88, 18, 8, SS_LEFT
    LTEXT           "Stop Bits", IDC_STATIC, 41, 107, 29, 8, SS_LEFT
    COMBOBOX        IDC_PORTNAME_COMBO, 93, 27, 75, 30, CBS_DROPDOWNLIST | CBS_HASSTRINGS
    COMBOBOX        IDC_BAUDRATE_COMBO, 93, 46, 75, 30, CBS_DROPDOWNLIST | CBS_HASSTRINGS
    COMBOBOX        IDC_DATABITS_COMBO, 93, 65, 75, 30, CBS_DROPDOWNLIST | CBS_HASSTRINGS
    COMBOBOX        IDC_PARITY_COMBO, 93, 86, 75, 30, CBS_DROPDOWNLIST | CBS_HASSTRINGS
    COMBOBOX        IDC_STOPBITS_COMBO, 93, 105, 75, 31, CBS_DROPDOWNLIST | CBS_HASSTRINGS
    PUSHBUTTON      "Start Listening", IDC_BUTTON1, 213, 30, 57, 14
    PUSHBUTTON      "Stop Listening", IDC_BUTTON2, 213, 48, 57, 14
    GROUPBOX        "Actions", IDC_STATIC, 196, 14, 158, 116
    EDITTEXT        IDC_EDIT1, 15, 143, 340, 147, ES_AUTOVSCROLL | ES_MULTILINE | ES_WANTRETURN
    PUSHBUTTON      "Clear", IDC_BUTTON3, 214, 66, 57, 14
}


这篇关于如何在Windows中进行串行通信?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆