《Visual C++串口通信技术与工程实践》读书笔记Word格式.docx
《《Visual C++串口通信技术与工程实践》读书笔记Word格式.docx》由会员分享,可在线阅读,更多相关《《Visual C++串口通信技术与工程实践》读书笔记Word格式.docx(12页珍藏版)》请在冰豆网上搜索。
但是在Windows中由于Windows采用消息驱动和设备统一管理,以及利用消息队列进行程序控制。
所以DOS下的方法都不宜采用。
在Windows中为实现串口通信,Windows的SDK提供了完备的API函数和以中断方式驱动的通信驱动程序。
使编程变得较为容易,
Windows提供的标准通信API函数有很多。
一般来说要实现串口通信。
在32位模式下有以下4中方法:
1.应用CreateFile方式打开串口
根据直译你会以为是打开文件的。
其实非也。
API函数CreateFile()定义如下:
1.HANDLE
CreateFile(
2. LPCTSTR
lpFileName,
//文件名
3. DWORD
dwDesiredAccess,
//访问模式(写/读)
4. DWORD
dwShareMode,
//共享模式
5. LPSECURITY_ATTRIBUTES
lpSecurityAttributes,
//指向安全属性的指针,可为NULL
6. DWORD
dwCreationDisposition,
//创建方式
7. DWORD
dwFlagsAndAttributes,
//文件属性和标志
8. HANDLE
hTemplateFile
//用于复制文件句柄,通常为NULL;
9.
//如果不为零,则指定一个文件句柄。
新文件将从这个文件中复制扩展属性
10. );
打开一个通信端口时(如COM1),无论如何都要设置成OPEN_EXISTING(文件存在才打开)
这个函数代替了lOpen和lCreate函数,应该是我们的首选
下面实例编写打开COM1串口和使用他,直到关闭以ABCD分段。
A:
打开一个通信端口的例程(COM1)
[cpp]viewplaincopyprint?
1. HANDLE
hCom;
2. hCom
=
CreateFile("
COM1"
//文件名
3. GENERIC_READ|GENERIC_WRITE,
//允许写和读
4. 0,
//不共享了。
就独占了
5. NULL,
6. OPEN_EXISTING,
//打开而不是创建
7. FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,
//重叠方式
,一般的打开
8. NULL
//没有复制的文件属性
);
10. if(hCom
==
INVALID_HANDLE_VALUE)
11. {
12. MessageBox("
端口打开失败。
"
13. }
B:
串口的初始化
为什么要初始化,这个当然啦。
你要告诉你的端口。
你准备接收的是什么数据,这个什么就有。
频率,位数,检验,速率等信息了
我们使用一个DCB结构来保存我们的要求(就是串口的属性)
1.typedef
struct
_DCB{
2.
………
3.
//波特率,指定通信设备的传输速率。
这个成员可以是实际波特率值或者下面的常量值之一:
4.
DWORD
BaudRate;
5.CBR_110,CBR_300,CBR_600,CBR_1200,CBR_2400,CBR_4800,CBR_9600,CBR_19200,
CBR_38400,
6.CBR_56000,
CBR_57600,
CBR_115200,
CBR_128000,
CBR_256000,
CBR_14400
7.DWORD
fParity;
//
指定奇偶校验使能。
若此成员为1,允许奇偶校验检查
8.
…
9.BYTE
ByteSize;
通信字节位数,4—8
10.BYTE
Parity;
//指定奇偶校验方法。
此成员可以有下列值:
11.EVENPARITY
偶校验
NOPARITY
无校验
12.MARKPARITY
标记校验
ODDPARITY
奇校验
13.BYTE
StopBits;
//指定停止位的位数。
14.ONESTOPBIT
1位停止位
TWOSTOPBITS
2位停止位
15.ONE5STOPBITS
1.5位停止位
16.
17.
}
DCB;
winbase.h文件中定义了以上用到的常量。
如下:
1.#define
0
2.#define
1
3.#define
EVENPARITY
2
4.#define
ONESTOPBIT
5.#define
ONE5STOPBITS
6.#define
7.#define
CBR_110
110
8.#define
CBR_300
300
9.#define
CBR_600
600
10.#define
CBR_1200
1200
11.#define
CBR_2400
2400
12.#define
CBR_4800
4800
13.#define
CBR_9600
9600
14.#define
14400
15.#define
CBR_19200
19200
16.#define
CBR_38400
38400
17.#define
CBR_56000
56000
18.#define
CBR_57600
57600
19.#define
CBR_115200
115200
20.#define
CBR_128000
128000
21.#define
CBR_256000
256000
调用GetCommState();
BOOLGetCommState(
HANDLEhFile,//标识通讯端口的句柄,就是上面的hCom
LPDCBlpDCB//指向一个设备控制块(DCB结构)的指针
);
SetCommState函数设置COM口的设备控制块:
BOOLSetCommState(
HANDLEhFile,
//还是上面的hCom
LPDCBlpDCB
//你自己设置好的DCB
除了在BCD中的设置外,程序一般还需要设置I/O缓冲区的大小和超时。
Windows用I/O缓冲区来暂存串口输入和输出的数据。
如果通信的速率较高,则应该设置较大的缓冲区。
调用SetupComm函数可以设置串行口的输入和输出缓冲区的大小。
BOOLSetupComm(
HANDLEhFile,//通信设备的句柄
DWORDdwInQueue,//输入缓冲区的大小(字节数)
DWORDdwOutQueue//输出缓冲区的大小(字节数)
C:
利用ReadFile()和WriteFile()对串口端口进行读写操作。
完成数据传输的过程。
但是要考虑好传送过程超时问题;
下面设置下我们程序员对端口的超时定义,
利用一个COMMTIMEOUTS数据结构来保存我们定义的东西。
_COMMTIMEOUTS
{
ReadIntervalTimeout;
//读间隔超时
ReadTotalTimeoutMultiplier;
//读时间系数
ReadTotalTimeoutConstant;
//读时间常量
5.
WriteTotalTimeoutMultiplier;
写时间系数
6.
WriteTotalTimeoutConstant;
//写时间常量
7.}
COMMTIMEOUTS,*LPCOMMTIMEOUTS;
COMMTIMEOUTS结构的成员都以毫秒为单位。
总超时的计算公式是:
总超时=时间系数×
要求读/写的字符数+时间常量
例如,要读入10个字符,那么读操作的总超时的计算公式为:
读总超时=ReadTotalTimeoutMultiplier×
10+ReadTotalTimeoutConstant
在读写串口之前,还要用PurgeComm()函数清空缓冲区,该函数原型:
BOOLPurgeComm(
HANDLEhFile,//串口句柄
DWORDdwFlags//需要完成的操作
参数dwFlags指定要完成的操作,可以是下列值的组合:
PURGE_TXABORT中断所有写操作并立即返回,即使写操作还没有完成。
PURGE_RXABORT中断所有读操作并立即返回,即使读操作还没有完成。
PURGE_TXCLEAR清除输出缓冲区
PURGE_RXCLEAR清除输入缓冲区
BOOLReadFile
(
HANDLEhFile,//串口的句柄
//读入的数据存储的地址,
//即读入的数据将存储在以该指针的值为首地址的一片内存区
LPVOIDlpBuffer,
DWORDnNumberOfBytesToRead,//要读入的数据的字节数
//指向一个DWORD数值,该数值返回读操作实际读入的字节数
LPDWORDlpNumberOfBytesRead,
//重叠操作时,该参数指向一个OVERLAPPED结构,同步操作时,该参数为NULL。
LPOVERLAPPEDlpOverlapped
BOOLWriteFile
//写入的数据存储的地址,
//即以该指针的值为首地址的nNumberOfBytesToWrite
//个字节的数据将要写入串口的发送数据缓冲区。
LPCVOIDlpBuffer,
DWORDnNumberOfBytesToWrite,//要写入的数据的字节数
//指向指向一个DWORD数值,该数值返回实际写入的字节数
LPDWORDlpNumberOfBytesWritten,
//重叠操作时,该参数指向一个OVERLAPPED结构,
//同步操作时,该参数为NULL。
在用ReadFile和WriteFile读写串口时,既可以同步执行,也可以重叠执行。
在同步执行时,函数直到操作完成后才返回。
这意味着同步执行
时线程会被阻塞,从而导致效率下降。
在重叠执行时,即使操作还未完成,这两个函数也会立即返回,费时的I/O操作在后台进行
还要考虑
在使用ReadFile函数进行读操作前,应先使用ClearCommError函数清除错误。
ClearCommError函数的原型如下:
D:
BOOLClearCommError(
HANDLEhFile,//串口句柄
LPDWORDlpErrors,//指向接收错误码的变量
LPCOMSTATlpStat//指向通讯状态缓冲区
参数的说明
_COMSTAT
cst
fCtsHold
:
1;
Tx
等待
CTS
信号
TX和CTS都是端口引脚,所以要具体分析咯、拿端口来看看,根据说明书知道
fDsrHold
waiting
for
DSR
signal
fRlsdHold
RLSD
fXoffHold
waiting,
XOFF
char
rec'
'
d
fXoffSent
sent
7.
fEof
EOF
character
fTxim
Tx
fReserved
25;
reserved
10.
cbInQue;
bytes
in
input
buffer
11.
cbOutQue;
output
12.}
COMSTAT,
*LPCOMSTAT;
关闭串口了。
BOOLCloseHandle(
HANDLEhObject;
//handletoobjecttoclose
2:
使用现有的ActiveX控件实现端口通信。
就是微软的MSComm控件。
它是作为一个ocx来提供的,基本使用流程和直接使用API函数一样,要明白它就要看控件包含的函数。
3:
直接嵌入汇编法实现端口通信
刚刚我就给出一个汇编的代码了。
在C++上面都是可以用的(除了WindowsNT操作系统),但是要添加一些语句,下面通过一个实例说明:
intmain(intargc,char*argv[])
{
_asm
{
mov
dx,3FBH
al,80H
out
dx,al
}
4:
编写VXD或者WDM实现
这个要了解WalterOney的《SystemProgrammingforWindow95
》和《ProgrammingtheMiscrosoftWindowsDriverModel》