用VC++6.0實現(xiàn)PC機(jī)與單片機(jī)之間串行通信的方法

字號:

摘 要 詳細(xì)介紹了在Windows環(huán)境下應(yīng)用VC++實現(xiàn)PC機(jī)與單片機(jī)的幾種串行通信方法,給出了用Visual C++6.0編寫的PC機(jī)程序和用C51編寫的單片機(jī)通信程序。經(jīng)實際應(yīng)用系統(tǒng)運(yùn)行穩(wěn)定可靠。
    關(guān)鍵詞 Visual C++ 類 串行通信
    工業(yè)控制領(lǐng)域(如DCS系統(tǒng)),經(jīng)常涉及到串行通信問題。為了實現(xiàn)微機(jī)和單片機(jī)之間的數(shù)據(jù)交換,人們用各種不同方法實現(xiàn)串行通信,如DOS下采用匯編語言或C語言,但在Windows 環(huán)境下卻存在一些困難和不足。在Windows操作系統(tǒng)已經(jīng)占據(jù)統(tǒng)治地位的情況下(何況有些系統(tǒng)根本不支持DOS如Windows2000)開發(fā)Windows 環(huán)境下串行通信技術(shù)就顯得日益重要。
    VC++6.0是微軟公司于1998年推出的一種開發(fā)環(huán)境,以其強(qiáng)大的功能,友好的界面,32位面向?qū)ο蟮某绦蛟O(shè)計及Active X的靈活性而受廣大軟件開發(fā)者的青睞,被廣泛應(yīng)用于各個領(lǐng)域。應(yīng)用VC++開發(fā)串行通信目前通常有如下幾種方法:一是利用Windows API通信函數(shù);二是利用VC的標(biāo)準(zhǔn)通信函數(shù)_inp、_inpw、_inpd、_outp、_outpw、_outpd等直接對串口進(jìn)行操作;三是使用Microsoft Visual C++的通信控件(MSComm);四是利用第三方編寫的通信類。以上幾種方法中第一種使用面較廣,但由于比較復(fù)雜,專業(yè)化程度較高,使用較困難;第二種需要了解硬件電路結(jié)構(gòu)原理;第三種方法看來較簡單,只需要對串口進(jìn)行簡單配置,但是由于使用令人費(fèi)解的VARIANT 類,使用也不是很容易;第四種方法是利用一種用于串行通信的CSerial類(這種類是由第三方提供),只要理解這種類的幾個成員函數(shù),就能方便的使用。筆者利用CSerial類很方便地實現(xiàn)了在固定式EBM氣溶膠滅火系統(tǒng)分區(qū)啟動器(單片機(jī)系統(tǒng))與上位機(jī)的通信。以下將結(jié)合實例,給出實現(xiàn)串行通信的幾種方法。
    1 Windows API通信函數(shù)方法
    與通信有關(guān)的Windows API函數(shù)共有26個,但主要有關(guān)的有:
    CreateFile() 用 “comn”(n為串口號)作為文件名就可以打開串口。
    ReadFile() 讀串口。
    WriteFile() 寫串口。
    CloseHandle() 關(guān)閉串口句柄。初始化時應(yīng)注意CreateFile()函數(shù)中串口共享方式應(yīng)設(shè)為0,串口為不可共享設(shè)備,其它與一般文件讀寫類似。以下給出API實現(xiàn)的源代碼。
    1.1 發(fā)送的例程
    //聲明全局變量
    HANDLE m_hIDComDev;
    OVERLAPPED m_OverlappedRead, m_Over lappedWrite;
    //初始化串口
    void CSerialAPIView::OnInitialUpdate()
    {
    CView::OnInitialUpdate();
    Char szComParams[50];
    DCB dcb;
    Memset(&m_OverlappedRead, 0, sizeof (OVERLAPPED));
    Memset(&m_OverlappedWrite, 0, sizeof (OVERLAPPED));
    m_hIDComDev = NULL;
    m_hIDComDev = CreateFile(“COM2”, GENERIC_READ│GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL│FILE_FLAG_OVERLAPPED, NULL);
    if (m_hIDComDev == NULL)
    {
    AfxMessageBox(“Can not open serial port!”);
    goto endd;
    }
    memset(&m_OverlappedRead, 0, sizeof (OVERLAPPED));
    memset(&m_OverlappedWrite, 0, sizeof (OVERLAPPED));
    COMMTIMEOUTS CommTimeOuts;
    CommTimeOuts. ReadIntervalTimeout=0×FFFFFFFF;
    CommTimeOuts. ReadTotalTimeoutMultiplier = 0;
    CommTimeOuts. ReadTotalTimeoutConstant = 0;
    CommTimeOuts. WriteTotalTimeoutMultiplier = 0;
    CommTimeOuts. WriteTotalTimeoutConstant = 5000;
    SetCommTimeouts(m_hIDComDev, &CommTimeOuts);
    Wsprintf(szComparams, “COM2:9600, n, 8, 1”);
    m_OverlappedRead. hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    m_OverlappedWrite. hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    dcb. DCBlength = sizeof(DCB);
    GetCommState(m_hIDComDev, &dcb);
    dcb. BaudRate = 9600;
    dcb. ByteSize= 8;
    unsigned char ucSet;
    ucSet = (unsigned char) ((FC_RTSCTS&FC_DTRDSR) != 0);
    ucSet = (unsigned char) ((FC_RTSCTS&FC_RTSCTS) ! = 0);
    ucSet = (unsigned char) ((FC_RTSCTS&FC_XONXOFF) ! = 0);
    if (!SetCommState(m_hIDComDev, &dcb)‖
    !SetupComm(m_hIDComDev,10000,10000)‖
    m_OverlappedRead. hEvent ==NULL‖
    m_OverlappedWrite. hEvent ==NULL)
    {
    DWORD dwError = GetLastError();
    if (m_OverlappedRead. hEvent != NULL) CloseHandle(m_OverlappedRead. hEvent);
    if (m_OverlappedWrite. hEvent != NULL) CloseHandle(m_OverlappedWrite. hEvent);
    CloseHandle(m_hIDComDev);
    }
    endd:
    ;
    }