zoukankan      html  css  js  c++  java
  • 从win32的串口API编程学C++的点、线、面!(1)使用win32API让串口工作!

      我是一个初学者,由于工作需要编写一个使用win32 API的串口通讯程序!这一系列文记录了我学习整个过程和基中C++/C各种知识的点、面,我贴出来是想其中的错漏,请大家指正出,以便重构!(此节为第一篇,就要讲串口打开与写操作)

    //第一节内容包括:使用API打开串口 对串口写字符串

    编写第一个可以工作的串口程序!

    编写环境:win03+vs05

    程序流程:打开串口->设置DCB串口属性->写字符串

    这个程序非常简单,是我参照网上CDMA发短信程序写的!但是我认为,这是win32 API串口通讯入门的一个好示例!

      我编写程序前,使用2、3交叉线的RS232串口线将COM1和COM2口连接在一起了。不过现在新电脑都取消了串口了,可以使用USB转串口设备替换,效果是一样的。下载一个串口调试助手(我使用的是V2.1.exe),作为测试用例中的工具软件。在VS05中新建C++空console项目,在空项目中加入了一个C++文件。

      源文件很简单,主要串口API的应用,打开串口COM2->设置DCB串口属性(9600,n,8,1)->写字符串"1234567890",使用串口调试助手可以接收到字符串。涉及到C++的点不多,用了iostream和namespace,没用使用C++异常,iostream主是输出错误返回代码。

    知识点

    打开串口

      什么叫“打开串口”?说白了就是向操作系统申请使用串口资源,告诉操作系统:我(本进程)要使用哪个串口(资源),使用方式是什么。操作系统得到申请后,就帮你分配资源。如果别人用了,就告诉你:不行,有人用了,你不能用了!如果无人,就分配你一个许可证--返回句柄,告诉你:你用吧,这是许可证!具体函数是:CreateFile(),返回值就是句柄(许可证)。

    用以下代码分析下CreateFile函数的知识点

    HANDLE hCom =::CreateFile(  _T("COM2"),
            GENERIC_READ|GENERIC_WRITE, 
            0,
            0,
            OPEN_EXISTING,
            0,//FILE_FLAG_OVERLAPPED,
            0
             );

    使用串口资源时,第三个、第五个和第七个参数必须这样设定。最需要注意的是第六个参数,涉及同步和异步方式。实际应用中同步应用很少,多是异步操作。本例中使用的是同步。也就是说打开串口有两种方式:一种是同步(NonOverlapped),另一种是异步方式(Overlapped)。这其实也告诉操作系统本进程使用串口的方法!当第六个参数为0,即使用同步方法打开,在本例中的意思为:当程序在WriteFile()执中写字符串操作时,不响应任何调度,一直到写操作完成,WriteFile函数返回。其实,你就把这段同步操作理想成DOS下的程序就可以了!函数过程从main开始,一句一句的过程,从头执行到尾。关于同步与异步在后面几节会详细讲述下。


    以下源代码

    //SerialComm.cpp
    #include <iostream>
    #include <TCHAR.H>

    #include <windows.h>

    using namespace std;

    int main()
    {
     HANDLE hCom =::CreateFile(  _T("COM2"),
            GENERIC_READ|GENERIC_WRITE, 
            0,
            0,
            OPEN_EXISTING,
            0,//FILE_FLAG_OVERLAPPED,
            0
             );
     if(hCom ==INVALID_HANDLE_VALUE){
      DWORD dwError=::GetLastError();
      cout<<dwError<<endl;
      return false;
     }
       
     DCB dcb={0};
     dcb.DCBlength = sizeof(DCB);

     if(!::GetCommState(hCom,&dcb)){
      DWORD dwError=::GetLastError();
      cout<<dwError<<endl;
      return false;
     }

     dcb.BaudRate = 9600;
     dcb.ByteSize = 8;
     dcb.Parity = NOPARITY;
     dcb.StopBits =ONESTOPBIT;

     if(!::SetCommState(hCom,&dcb)){
      DWORD dwError=::GetLastError();
      cout<<dwError<<endl;
      return false;
     }
     if( !::PurgeComm( hCom, PURGE_RXCLEAR ) )    return false;
     DWORD dw;
     ::WriteFile(hCom,"1234567890",10,&dw,NULL);
     ::CloseHandle(hCom);
     return 0;
    }

  • 相关阅读:
    LeetCode题解之Flipping an Image
    LeetCode 之Find Minimum in Rotated Sorted Array
    LeetCode题解Transpose Matrix
    LeetCode 题解之Minimum Index Sum of Two Lists
    LeetCode题解之Intersection of Two Linked Lists
    LeetCode 题解之Add Two Numbers II
    LeetCode题解之Add two numbers
    href="#"与href="javascript:void(0)"的区别
    有关ie9 以下不支持placeholder属性以及获得焦点placeholder的移除
    ie7下属性书写不规范造成的easyui 弹窗布局紊乱
  • 原文地址:https://www.cnblogs.com/scarecrow/p/1330571.html
Copyright © 2011-2022 走看看