由于工作需要用到windows下的串口编程,今天就去搜了下相关方面的内容,为了方便记忆,就写了个短小的程序,为方便回顾,也为了跟大家进行交流学习,就写了这个博客。
程序功能:
1:打开串口com2,设置它波特率;
2:设置串口的读超时限制;
3:循环监听串口com2,有数据就读出来,然后再写回去。
以下为示例程序:
#include<windows.h>
#include<iostream>
using namespace std;
HANDLE hCom; //全局变量,串口句柄
bool OpenCom(); //串口打开函数
bool setupdcb(int); //串口参数设置:如波特率这些。
int main()
{
<span style="white-space:pre"> </span>DWORD dwError = 0;
COMSTAT comstat;
BOOL bresult = true;
char readbuf[1024];
DWORD nread;
COMMTIMEOUTS timeouts;
timeouts.ReadIntervalTimeout = 20; //从接收第一个字符开始计时,读取两个字符间的时间间距大于 20 毫秒,认为此次读取完成,ReadFile返回。
timeouts.ReadTotalTimeoutConstant = 1000; //当ReadFile()阻塞1000毫秒,就超时,ReadFile()返回.
timeouts.ReadTotalTimeoutMultiplier = 0; //其实总的超时时间为: n = ReadTotalTimeoutConstant * 读取字节数 + ReadTotalTimeoutConstant.
timeouts.WriteTotalTimeoutConstant = 50;
timeouts.WriteTotalTimeoutMultiplier = 20;
if(!OpenCom())
<span style="white-space:pre"> </span>return -1;
if(!setupdcb(9600))
<span style="white-space:pre"> </span>return -1;
SetCommTimeouts(hCom,&timeouts); //利用tiumeouts 结构体,设置超时限制。
while(1)
{
memset(readbuf,0,1024);
ClearCommError(hCom,&dwError,&comstat); //清除串口错误或读取串口现在的状态,第三个参数尤为重要,它是一个结构体,有两个参数
<span style="white-space:pre"> </span>//comstat.cbInQue:输入缓存中的字节数
<span style="white-space:pre"> </span>//comstat.cbOutQue:输出缓存中的字节数,再此这个参数我没用到,搁置。
printf("in .... \n");
ReadFile(hCom,readbuf,1024,&nread,NULL); //读hCom(指com2口)1024个字节到 readbuf中,真实读到的字节数存在nread中。
<span style="white-space:pre"> </span>if (nread > 0)
{
printf("get serial data! %s, %d\n",readbuf, nread);
WriteFile(hCom,readbuf,strlen(readbuf),&nread,NULL); //往hCom(com2)写入readbuf里面的数据,长度为strlen(readbuf).
}
else
printf("timeout!\n");
}
<span style="white-space:pre"> </span>return TRUE;
}
bool OpenCom()
{
<span style="white-space:pre"> </span>hCom=CreateFile("COM2",//COM2口
GENERIC_READ|GENERIC_WRITE, //允许读和写
0, //独占方式
NULL,
OPEN_EXISTING, //打开而不是创建
0, //同步方式
NULL);
<span style="white-space:pre"> </span>if(hCom==(HANDLE)-1)
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>printf("打开COM失败!");
<span style="white-space:pre"> </span>return false;
<span style="white-space:pre"> </span>}
else
{
<span style="white-space:pre"> </span>printf("ok\n");
<span style="white-space:pre"> </span>return true;
}
}
bool setupdcb(int rate) //再此我只是变动波特率,其实很多参数都可以改(要改正确,不然电脑会蓝屏,它的自我保护吧应该。),修改DCB结构体就行。
{
<span style="white-space:pre"> </span>DCB dcb;
memset(&dcb, 0, sizeof(dcb));
if(!GetCommState(hCom,&dcb))
return false;
dcb.BaudRate = rate; //波特率。
dcb.fParity = 0;
dcb.Parity = 0;
dcb.ByteSize = 8; //数据位
dcb.StopBits = 0; //停止位
if(!SetCommState(hCom,&dcb))
return false;
printf("set dcb success!\n");
return true;
}
其实上面是一个C程序,由于时间关系我没把它改规范,过一两天我上一个较为规范的程序上来。