Serial Port Programming using Win32 API(转载)
In this tutorial we will learn How to communicate with an external device like a microcontroller board or modem using the Serial port of a windows PC(Windows XP,7). The software is written using C language and communicates with the Serial Port using Win32 API.
In Windows ,Serial ports are named as COM1,COM2 ,COM3.. etc .COM1 and COM2 usually refer to the hardware serial ports present in the PC while COM numbers in double digits likeCOM32,COM54,COM24.. etc are given to USB to Serial Converters or PCI serial port extenders.
If your PC does not have any hardware serial ports (RS232 DB9 ports), you can use USB to Serial Converter's like USB2SERIAL.
If you are interested in setting up an RS485 network controlled by your PC to control a robot or a sensor network ,you can use USB2SERIAL board (buy here).
The Board can also be used as an FT232 development board.
Sourcecodes
All the C sourefiles used in this tutorial can be downloaded from our GitHub Page.If you are new to Github Check this article to download code .
Compilers and IDE's used
To Compile the C file you can use either Visual Studio Express edition from Microsoft or MinGW(Windows port of GCC).
Visual Studio 2013 Express Edition for Desktop can be freely downloaded (its a large download) from Microsoft's website. Here is a short tutorial on how to setup a C project in VS 2013.
If you don't want to download the Visual Studio and want something simpler you can use MinGW, which is an open source port of GCC for windows environment. After you have installed the MinGW, package make sure to add gcc to system path so that you can call it from anywhere.
Finding out your COM port Number
To find out the COM number corresponding to your serial port, Open Device Manager by right clicking on My Computer icon and selecting Manage → Device Manager.Under Ports(COM & LPT) you can see the parallel and serial ports (COM) detected by your system.

If your PC has any hardware ports, it will be shown either as COM1 or COM2 under the Ports Section. I am using a FTDI based USB to Serial Converter (USB2SERIAL)which is recognized as COM24 (this may be different under your system). If you double click on COM24,you can see the details of the corresponding port.

Opening and Closing a Serial Port
In Windows we use the CreateFile() function to open a serial port.
CreateFile() is a Win 32 function which is used to create or open a file, stream or an IO device like serial port.On success CreateFile() will return a handle which is then used to refer the connection in all subsequent operations.
After opening a serial port using the CreateFile() function you should close it with CloseHandle()function, otherwise port will become unavailable to other programs.
Now let's write a small program to open and close a serial port on Windows. Open a text editor like notepad or Notepad++ and type the below code and save it as "serial.c".If you are using IDE like VS Express, use the one integrated with it.
|
#include<windows.h> hComm = CreateFile("\\\\.\\COM24", //port name if (hComm == INVALID_HANDLE_VALUE) CloseHandle(hComm);//Closing the Serial Port return 0; |
Find out the COM port corresponding to your system and substitute in CreateFile() instead of COM24.
Now compile and run the program by pressing F5 in Visual Studio
or
by running the following command for gcc (MingW).Please make sure that gcc is added to you system path.
D:\> gcc -o serial serial.c

Now let me explain the code ,
windows.h header file contain all the definitions, function prototypes and constants required by the program.
In Windows everything is controlled by using handles.In the first line
HANDLE hComm;
we declare a handle hcomm to access and control the serial port.
Next we open a connection to serial port using CreateFile() function. The CreateFile() function on success, returns a valid handle to the hComm variable.
CreateFile() function takes 7 arguments,
1. Name of the serial port to be opened here \\\\.\\COM24.
2. Mode of access, here Read and Write
3. Sharing options, Serial ports can't be shared so 0
4. NULL for Serial ports, used for File operations
5. Open the existing port, OPEN_EXISTING
6. Overlapped IO or Non overlapped IO, here 0 means we are using NonOverlapped IO. Overlapped IO is used for multithreaded programs where
several threads can interact with the port simultaneously.
7. NULL for Serial port, used for file operations
If the function succeeds in opening the serial port, it returns a valid handle to hcomm which is then used for error checking.
After that the connection to the port is closed using
CloseHandle(hComm);
Please note that in Windows, COM port numbers from COM1 to COM9 are reserved by the system. If you are using a serial port whose COM port number falls in that range, you don't need the back slashes (\\\\.\\)shown in the above code.
You can access the serial port like this,
hComm = CreateFile("COM1", // for COM1—COM9 only
GENERIC_READ | GENERIC_WRITE, //Read/Write
0, // No Sharing
NULL, // No Security
OPEN_EXISTING, // Open existing port only
0, // Non Overlapped I/O
NULL);
Configuring the DCB Structure
In Windows ,settings like Baud rate ,Number of start/Stop bits,data formats etc for the serial port are controlled by the DCB structure.
To Configure the DCB structure we use two functions,
GetCommState() function which retrieves the current control settings of the serial port and
SetCommState() function which configures the serial port with the new values in DCB structure provided by us.
First you declare a new structure of type DCB and initializes it.
DCB dcbSerialParams = { 0 }; // Initializing DCB structure
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
After that retrieve the current settings of the serial port using the GetCommState() function.
Status = GetCommState(hComm, &dcbSerialParams);
and set the values for Baud rate, Byte size, Number of start/Stop bits etc.
dcbSerialParams.BaudRate = CBR_9600; // Setting BaudRate = 9600
dcbSerialParams.ByteSize = 8; // Setting ByteSize = 8
dcbSerialParams.StopBits = ONESTOPBIT;// Setting StopBits = 1
dcbSerialParams.Parity = NOPARITY; // Setting Parity = None
if you want to change the Baud rate values prefix standard values with CBR like this CBR_4800,CBR_9600,CBR_192600 etc.
Number of Stop bits can be changed to ONESTOPBIT or TWOSTOPBITS.
Parity can also be changed to EVENPARITY,ODDPARITY,NOPARITY etc.
Now its time to configure the serial port according to the DCB structure using SetCommState()function.
SetCommState(hComm, &dcbSerialParams);
Setting Timeouts
Timeouts helps to prevent your program from waiting endlessly till data arrives. It helps the read or write calls to return after a set time period has elapsed.
COMMTIMEOUTS timeouts = { 0 };
timeouts.ReadIntervalTimeout = 50; // in milliseconds
timeouts.ReadTotalTimeoutConstant = 50; // in milliseconds
timeouts.ReadTotalTimeoutMultiplier = 10; // in milliseconds
timeouts.WriteTotalTimeoutConstant = 50; // in milliseconds
timeouts.WriteTotalTimeoutMultiplier = 10; // in milliseconds
All values are in milliseconds.
ReadIntervalTimeout Specifies the maximum time interval between arrival of two bytes. If the arrival time exceeds these limits the ReadFile() function returns.
ReadTotalTimeoutConstant is used to calculate the total time-out period for read operations. For each read operation, this value is added to the product of the ReadTotalTimeoutMultiplier member and the requested number of bytes.
ReadTotalTimeoutMultiplier is used to calculate the total time-out period for read operations. For each read operation, this value is multiplied by the requested number of bytes to be read.
WriteTotalTimeoutConstant similar to ReadTotalTimeoutConstant but for write operation.
WriteTotalTimeoutMultiplier similar to ReadTotalTimeoutMultiplier but for writeoperation.
After this you have to set the values using SetCommTimeouts() function.
Writing Data to Serial Port
Writing data to the opened serial port is accomplished by the WriteFile() function. WriteFile() function can be used to write both into the files and I/O ports.
|
char lpBuffer[] = "A"; Status = WriteFile(hComm, // Handle to the Serial port |
hComm Handle of the serial port to write.
lpBuffer[] character array containing the data to write into the serial port.
dNoOFBytestoWrite is the total number of bytes to be written into the serial port.Here we are using the sizeof() operator to find out that .
dNoOFBytestoWrite = sizeof(lpBuffer);
dNoOfBytesWritten is the total number of bytes written successfully to the port by theWriteFile() operation.
Now in the Zip File containing the source codes you can find "USB2SERIAL_Write_W32.c" which contains the complete code for writing into serial port. You can compile the code using Visual Studio Express or GCC.
If your PC does not have any hardware serial ports you can use any USB to Serial Converters(I am using USB2SERIAL).
I have interfaced a microcontroller board(MSP430G2553 on Launch Pad) to the serial port using a null modem cable like this

You can use any microcontroller of your choice like 8051,AVR or ARM(LPC2148).The Controller waits for a character to be received and lights up the corresponding LED. The code for MSP430 is included in the zip file.If you want to know how to configure the MSP430 controller UART you can check this tutorial.

Please note that if you are using a DB9 RS232 Serial Port of your PC, you will have to build a RS232 signal level converter at the microcontroller side to decode the RS232 signal.
Directly connecting the PC's RS232 Serial port to MSP430 's pins will damage the chip.
Here is the screen shot of the Program writing into serial port.

Reading from the Serial Port
Reading from the serial port is accomplished by the ReadFile() function.
One way to do that is to use polling where the ReadFile() continuously reads from the serial port and checks for any received characters.
Other way is to setup an event and let windows notify us when a character is received.
We are going to use the second method here, following are the steps.
1. Create an Event for a particular action like character reception, change in modem lines etc usingSetCommMask() function .
2. Ask windows to wait for the event set by SetCommMask() function using WaitCommEvent() and notify us when the condition happens.
3. Call ReadFile () to read the received data from the Serial port.
Functions used are
SetCommMask() is used to set the events to be monitored for a communication device. Here we are going to set the event as character received (EV_RXCHAR).The function takes two arguments, Handle of the serial port (hComm) and the code for the event (EV_RXCHAR) to be monitored.
Status = SetCommMask(hComm, EV_RXCHAR);
WaitCommEvent() is used to wait for the events set by SetCommMask() to happen, in this case reception of a character. The flow of execution of the program stops and the program waits until a character is received.
DWORD dwEventMask;
Status = WaitCommEvent(hComm, &dwEventMask, NULL);
dwEventMask contains a hex value indicating the event, which has caused WaitCommEvent() to return.
After WaitCommEvent() has returned, call ReadFile() function to read the received characters from the Serial Port Buffer.
|
char TempChar; //Temporary character used for reading do SerialBuffer[i] = TempChar;// Store Tempchar into buffer while (NoBytesRead > 0); |
ReadFile() function is similar to the WriteFile() function we had seen earlier,instead of writing we are reading from the serial port.
&TempChar Temporary variable used to store the byte read from serial port buffer.
sizeof(TempChar) used to calculate the number of bytes to read.
&NoBytesRead Bytes successfully read by the ReadFile().
Now in the Zip File containing the source codes you can find "USB2SERIAL_Read_W32.c" which contains the complete code for writing into serial port. You can compile the code using Visual Studio Express or GCC.
On running "USB2SERIAL_Read_W32.exe" ,The code will wait for the characters to be transmitted by the microcontroller.

Reset the Micro controller to transmit the string "Hello from MSP430".

原文地址:http://xanthium.in/Serial-Port-Programming-using-Win32-API
Serial Port Programming using Win32 API(转载)的更多相关文章
- Serial Port Programming on Linux(转载)
This is a tutorial on how to program the Serial Ports on your Linux box.Serial Ports are nice little ...
- C#调用Win32 api学习总结
从.NET平台调用Win32 API Win32 API可以直接控制Microsoft Windows的核心,因为API(Application Programming Interface)本来就是微 ...
- Detours简介 (拦截x86机器上的任意的win32 API函数)
Detours 当然是用detours,微软明显高腾讯一筹,同上,至今没失败过.写这种HOOK一定要再写个测试程序,不要直接HOOK你的目的程序,例如QQ,因为这样不方面更灵活的测试.说明一下:Det ...
- 【.Net】从.NET平台调用Win32 API
小序 Win32 API可以直接控制Microsoft Windows的核心,因为API(Application Programming Interface)本来就是微软留给我们直接控制 ...
- 使用Win32 API创建不规则形状&带透明色的窗口
前一阵突然想起了9月份电面某公司实习时的二面题,大概就是说怎么用Win32 API实现一个透明的窗口,估计当时我的脑残答案肯定让面试官哭笑不得吧.所以本人决定好好研究下这个问题.经过一下午的摸索,基本 ...
- MSComm控件与Win32 API操作串口有何区别?
MSComm控件与Win32 API操作串口有何区别? [问题点数:50分,结帖人shell_shell] 收藏帖子 回复 我是一个小兵,在战场上拼命! 结帖率 83.33% 我以前用MSCo ...
- ROS 进阶学习笔记(12) - Communication with ROS through USART Serial Port
Communication with ROS through USART Serial Port We always need to communicate with ROS through seri ...
- 控制台——对WIN32 API的使用(user32.dll)
Win32 API概念:即为Microsoft 32位平台的应用程序编程接口(Application Programming Interface).所有在Win32平台上运行的应用程序都可以调用这些函 ...
- Win32 API编程——前言
一丶什么是Win32 API? 微软为了保护操作系统的安全性和稳定性,把系统分为内核层和用户层(内核层的代码只能在当CPU的特权级为R0状态下执行,用户层的代码在CPU特权级为R0和R3都能执行),w ...
随机推荐
- asp.net <asp:Content>控件
<asp:Content ID="Content2" ContentPlaceHolderID="CPH_MainContent" runat=" ...
- Mybatis框架中实现双向一对多关系映射
学习过Hibernate框架的伙伴们很容易就能简单的配置各种映射关系(Hibernate框架的映射关系在我的blogs中也有详细的讲解),但是在Mybatis框架中我们又如何去实现 一对多的关系映射呢 ...
- 吉日嘎拉C#快速开发平台V4.0到V4.2升级记
目前我用的版本是4.0的,也有近2年没更新了,狠了狠心升级一下,没想到真的行动起来,也没那么难! 用了3天时间,将吉日嘎拉的代码升级到了4.2版本,并让原来的DotNet.WebApplication ...
- function的name属性
name属性是函数的一个非标准的属性. 通过这个属性,我们可以访问给定函数的名字.属性name的值永远等于跟在function关键字后的标识符. eg: function jenny(arg1,a ...
- php实现设计模式之 适配器模式
<?php /* * 适配器模式:将一个类的接口转换成客户希望的另外一个接口.Adapter模式使得原来由于接口不兼容而不能一起工作的那些类可以一起工作(结构型模式) * * 一个源接口,不符合 ...
- 从零开始学 Java - 数据库连接池的选择 Druid
我先说说数据库连接 数据库大家都不陌生,从名字就能看出来它是「存放数据的仓库」,那我们怎么去「仓库」取东西呢?当然需要钥匙啦!这就是我们的数据库用户名.密码了,然后我们就可以打开门去任意的存取东西了. ...
- 强大css3制作新浪LOGO 胜过PS
请使用支持CSS3的浏览器查看效果:http://keleyi.com/a/bjad/6lu3dgj8.htm 效果图: 完整代码如下: <html> <head> <t ...
- 认识DOM和一些方法
认识DOM 文档对象模型DOM(Document Object Model)定义访问和处理HTML文档的标准方法.DOM 将HTML文档呈现为带有元素.属性和文本的树结构(节点树). 先来看看下面代码 ...
- 天津政府应急系统之GIS一张图(arcgis api for flex)讲解(十)态势标绘模块
config.xml文件的配置如下: <widget label="态势标绘" icon="assets/images/impact_area_over.png&q ...
- Microsoft Dynamics CRM 分销行业解决方案
Microsoft Dynamics CRM 分销行业解决方案 方案亮点 360度动态渠道信息管理 充分的客户细分 全面的业务代表考核指标 业务代表管理和能力建设 业务代表过程管理 业务代表费用管理 ...