串口的通信Word下载.docx
- 文档编号:22420715
- 上传时间:2023-02-04
- 格式:DOCX
- 页数:10
- 大小:21.51KB
串口的通信Word下载.docx
《串口的通信Word下载.docx》由会员分享,可在线阅读,更多相关《串口的通信Word下载.docx(10页珍藏版)》请在冰豆网上搜索。
属性说明
CommPort
1
串口号,一般从1到4
InBufferSize
30720
接收缓冲区大小,为保持程序的稳定,建议设得值足够大
InputMode
0-Text
接收数据的类型,0表示文本类型,1表示二进制类型
InputLen
0
从接收缓冲区读取的字节数,0表示全部读取
OutBufferSize
512
发送缓冲区大小
Settings
4800,n,8,1
串口的参数设置,依次为波特率、奇偶校验(n-无校验,e-偶校验,o-奇校验)、数据位数、停
止位数
RThreshold
设定当接收几个字符时触发OnComm事件,0表示不产生事件,
1表示每接收一个字符就产生一个事件
SThreshold
设定在触发OnComm事件前,发送缓冲区内所允许的最少的字符数,
0表示发送数据时不产生事件,1表示当发送缓冲区空时产生OnComm事件
我们要求能在程序启动的同时就打开串口以便即时对从串口到达的数据进行接收、处理。
一般来说可以将下面
的打开端口的代码写在OnCreate()、OnInitialUpdate()、InitInstance
()等程序入口函数中:
……
if(!
m_Comm.GetPortOpen())
//检测是否已经打开过端口
m_Comm.SetPortOpen(TRUE);
//如没有打开则将端口打开
……
接下来的工作就是对数据的发送与接收了,这也是本文所要介绍的重点所在。
发送数据的代码原则上是可以写
到一个成员函数中被直接调用的,但这并不是一个良好的编程习惯:
我们应当把比较耗时的操作,如文件拷贝、打
印、端口传输等工作放到一个单独的线程当中,以避免其在工作时会引起整个进程的阻塞,以提高整个系统对CPU
的利用率。
例如我们可以在视类中菜单或按钮的响应函数中用AfxBeginThread(WriteProc,this)函数来开启一个名
为"
WriteProc"
的线程,由于在线程中还需要使用视类的函数和变量,为了不产生新的视类的实例对象,我们通过
该函数的第二个参数将指向当前的视类的指针this作为参数传递给线程。
在线程中可以用如下两种方法之中的一种
调用视类的成员函数:
((COLECommView*)
pParam)->
DoSendProc();
或是:
COLECommView*
view=(COLECommView*)
pParam;
View->
其中从pParam传来的变量就是指向视类的指针。
在线程中通过调用视类中的DoSendProc函数来完成对数据的发
送,正是由于该函数是被全局的线程所调用的,我们就不可以使用取编辑框上的数据时通常所用的UpdateData()函
数了,取而带之的是API
函数GetDlgItemText(),取到输入的数据后通过控件的SetOutput()
方法就把数据从串口
发出去了,其中发送数据必须经ColeVariant类将其转换为通用的VARIANT型变量。
实现
主要代码如下:
char
a[255];
HWND
hwnd=GetSafeHwnd();
:
GetDlgItemText(hwnd,IDC_EDIT1,a,255);
int
i=0;
CString
str;
while(a[i]!
='
\0'
)
{
str.Format("
%c"
a[i]);
m_SendData+=str;
i++;
}
10);
m_Comm.SetOutput(COleVariant(m_SendData));
……
至于数据的接收,我们可以通过让MS
Comm控件响应其OnComm事件来完成,通过ClassWizard加入其对事件的响
应后,通过下面的事件映射,当有字符到达时便会通知
OnComm()函数去处理,从而实现数据的异步接收:
BEGIN_EVENTSINK_MAP(COLECommView,
CFormView)
//{{AFX_EVENTSINK_MAP(COLECommView)
ON_EVENT(COLECommView,
IDC_MSCOMM1,
/*
OnComm
*/,
OnComm,
VTS_NONE)
//}}AFX_EVENTSINK_MAP
END_EVENTSINK_MAP()
void
COLECommView:
OnComm()
VARIANT
Input;
if(m_Comm.GetCommEvent()==2)//接收缓冲区内有字符
Input=m_Comm.GetInput();
//读取缓冲区内的数据
msg=Input.bstrVal;
if(msg.Right
(1)==str)
m_RecvData+=msg;
m_History.AddString(m_RecvData);
m_RecvData="
"
;
else
当数据被接收到接收缓冲区后,对于字符可以从VARIANT型结构变量的bstrVal成员变量中获取,VARIANT数据
结构相当复杂,并牵扯到COM(Component
Object
Model,组件对象模型)中的一些概念,具体详情请参阅Microsoft
Corpration发布的MSDN中的有关论述。
三、
测试与实验
编译运行程序之前有必要对机器的端口做一番检查,以确保端口的完好,可以用常见的DOS程序Comdebug来检
查。
在确认串口工作正常后,可用串口线将两台机器的串口相连,同时在两台机子上运行该程序,如果没有条件也
可只用一台微机,将其串口的2脚和3脚短接,使其处于自发自收状态。
经过数据的传输实验证明该程序是可靠、正
确的。
小结:
利用通讯控件可以很容易的编写出串行通信程序。
但相对来说通讯控件在VC中的使用要比在VB、Delphi
中复杂的多,要想对串口通讯开发出更多更灵活的使用方法还需要不断的实践中摸索。
本程序在
Windows
98下,由Microsoft
6.0编译通过。
二、直接用VC++访问串口。
在VC++中,串口和磁盘文件可以统一的方式来简单读写。
这两者几乎没有什么不同,只是在WINDOWS
9X下磁盘文件只能做同步访问,而串口只能做异步访问。
CreateFile:
用指定的方式打开指定的串口。
通常的方式为
m_hCom
=
CreateFile(
COM1"
GENERIC_READ
|
GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL
FILE_FLAG_OVERLAPPED,
NULL
);
m_hCom为文件句柄。
GENERIC_READ
GENERIC_WRITE指定可以对串口进行读写操作。
第三个参数0表示串口为独占打开。
OPEN_EXISTING表示当指定串口不存在时,程序将返回失败。
FILE_FLAG_OVERLAPPED则表示文件属性。
当打开串口时,必须指定
FILE_FLAG_OVERLAPPED,它表示文件或设备不会维护访问指针,则在读写时,必须使用OVERLAPPED
结构指定访问的文件偏移量。
ReadFile:
读取串口数据。
WriteFile:
向串口写数据。
CloseHandle:
关闭串口。
COMMTIMEOUTS:
COMMTIMEOUTS主要用于串口超时参数设置。
COMMTIMEOUTS结构如下:
typedef
struct
_COMMTIMEOUTS
{
DWORD
ReadIntervalTimeout;
ReadTotalTimeoutMultiplier;
ReadTotalTimeoutConstant;
WriteTotalTimeoutMultiplier;
WriteTotalTimeoutConstant;
}
COMMTIMEOUTS,*LPCOMMTIMEOUTS;
ReadIntervalTimeout:
两字符之间最大的延时,当读取串口数据时,一旦两个字符传输的时间差超过该时间,读取函数将返回现有的数据。
设置为0表示该参数不起作用。
ReadTotalTimeoutMultiplier:
读取每字符间的超时。
ReadTotalTimeoutConstant:
一次读取串口数据的固定超时。
所以在一次读取串口的操作中,其超时为ReadTotalTimeoutMultiplier乘以读取的字节数再加上
ReadTotalTimeoutConstant。
将ReadIntervalTimeout设置为MAXDWORD,并将ReadTotalTimeoutMultiplier
和ReadTotalTimeoutConstant设置为0,表示读取操作将立即返回存放在输入缓冲区的字符。
WriteTotalTimeoutMultiplier:
写入每字符间的超时。
WriteTotalTimeoutConstant:
一次写入串口数据的固定超时。
所以在一次写入串口的操作中,其超时为WriteTotalTimeoutMultiplier乘以写入的字节数再加上
WriteTotalTimeoutConstant。
SetCommTimeouts函数可以设置某设备句柄的超时参数,要得到某设备句柄的超时参数可以用GetCommTimeouts函数。
DCB:
DCB结构主要用于串口参数设置。
该结构太庞大,这里就不一一讲述了,有兴趣者可查看MSDN关于DCB的描述。
其中下面两个是比较重要的属性。
BaudRate:
串口的通讯速度。
一般设置为9600。
ByteSize:
字节位数。
一般设置为8。
DCB结构可以用SetCommState函数来设置,并可以用GetCommState来得到现有串口的属性。
SetupComm:
设置串口输入、输出缓冲区。
OVERLAPPED:
保存串口异步通讯的信息。
具体结构如下:
_OVERLAPPED
Internal;
InternalHigh;
Offset;
OffsetHigh;
HANDLE
hEvent;
OVERLAPPED;
Internal,InternalHigh是保留给系统使用的,用户不需要设置。
Offset,OffsetHigh是读写串口的偏移量,一般设置OffsetHigh为NULL,可以支持2GB数据。
hEvent读写事件,因为串口是异步通讯,操作可能被其他进程堵塞,程序可以通过检查该时间来得知是否读写完毕。
事件将在读写完成后,自动设置为有效。
通过以上这些函数和结构,我们就可以通过串口进行通讯了,现在我们具体看下面的实例:
BOOL
CSerial:
Open(
int
nPort,
nBaud
)
if(
m_bOpened
)
return(
TRUE
szPort[15];
DCB
dcb;
wsprintf(
szPort,
COM%d"
nPort
m_hComDev
m_hComDev
==
FALSE
memset(
&
m_OverlappedRead,
sizeof(
OVERLAPPED
m_OverlappedWrite,
COMMTIMEOUTS
CommTimeOuts;
CommTimeOuts.ReadIntervalTimeout
0xFFFFFFFF;
CommTimeOuts.ReadTotalTimeoutMultiplier
0;
CommTimeOuts.ReadTotalTimeoutConstant
CommTimeOuts.WriteTotalTimeoutMultiplier
CommTimeOuts.WriteTotalTimeoutConstant
5000;
SetCommTimeouts(
m_hComDev,
CommTimeOuts
m_OverlappedRead.hEvent
CreateEvent(
TRUE,
FALSE,
m_OverlappedWrite.hEvent
dcb.DCBlength
DCB
GetCommState(
dcb
dcb.BaudRate
nBaud;
dcb.ByteSize
8;
!
SetCommState(
||
!
SetupComm(
10000,
10000
){
dwError
GetLastError();
m_OverlappedRead.hEvent
=
CloseHandle(
m_OverlappedWrite.hEvent
CloseHandle(
return
FALSE;
m_bOpened
TRUE;
m_bOpened;
InBufferCount(
void
||
dwErrorFlags;
COMSTAT
ComStat;
ClearCommError(
m_hIDComDev,
dwErrorFlags,
ComStat
(int)ComStat.cbInQue;
ReadData(
*buffer,
DWORD
dwBytesRead)
return
bReadStatus;
ComStat.cbInQue
dwBytesRead
min(dwBytesRead,(DWORD)
ComStat.cbInQue);
bReadStatus
ReadFile(
buffer,
dwBytesRead,
dwBytesRead,
m_OverlappedRead
GetLastError()
ERROR_IO_PENDING
WaitForSingleObject(
m_OverlappedRead.hEvent,
2000
dwBytesRead;
SendData(
const
char
dwBytesWritten)
bWriteStat;
bWriteStat
WriteFile(
dwBytesWritten,
dwBytesWritten,
m_OverlappedWrite
bWriteStat){
if
(
{
m_OverlappedWrite.hEvent,
1000
dwBytesWritten;
上述函数基本实现串口的打开,读写操作。
本文章略去该串口类的说明和关闭函数。
读者应该能将这些内容写完。
接下来,你就可以在你的程序中调用该串口类了。
一、Microsoft
Control
Microsoft公司在WINDOWS中提供了一个串口通讯控件,用它,我们可以很简单的利用串口进行通讯。
在使用它之前,应将控件加在应用程序的对话框上。
然后再用ClassWizard
生成相应的对象。
现在我们可以使用它了。
该控件有很多自己的属性,你可以通过它的属性窗口来设置,也可以用程序设置。
我推荐用程序设置,这样更灵活。
SetCommPort:
指定使用的串口。
GetCommPort:
得到当前使用的串口。
SetSettings:
指定串口的参数。
一般设为默认参数"
9600,N,8,1"
。
这样方便与其他串口进行通讯。
GetSettings:
取得串口参数。
SetPortOpen:
打开或关闭串口,当一个程序打开串口时,另外的程序将无法使用该串口。
GetPo
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 串口 通信