WindowsAPI.docx

上传人:b****1 文档编号:304973 上传时间:2023-04-28 格式:DOCX 页数:13 大小:19.79KB
下载 相关 举报
WindowsAPI.docx_第1页
第1页 / 共13页
WindowsAPI.docx_第2页
第2页 / 共13页
WindowsAPI.docx_第3页
第3页 / 共13页
WindowsAPI.docx_第4页
第4页 / 共13页
WindowsAPI.docx_第5页
第5页 / 共13页
WindowsAPI.docx_第6页
第6页 / 共13页
WindowsAPI.docx_第7页
第7页 / 共13页
WindowsAPI.docx_第8页
第8页 / 共13页
WindowsAPI.docx_第9页
第9页 / 共13页
WindowsAPI.docx_第10页
第10页 / 共13页
WindowsAPI.docx_第11页
第11页 / 共13页
WindowsAPI.docx_第12页
第12页 / 共13页
WindowsAPI.docx_第13页
第13页 / 共13页
亲,该文档总共13页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

WindowsAPI.docx

《WindowsAPI.docx》由会员分享,可在线阅读,更多相关《WindowsAPI.docx(13页珍藏版)》请在冰点文库上搜索。

WindowsAPI.docx

WindowsAPI

1WindowsAPI通信函数方法

与通信有关的WindowsAPI函数共有26个,但主要有关的有:

CreateFile()用“comn”(n为串口号)作为文件名就可以打开串口。

ReadFile()读串口。

WriteFile()写串口。

CloseHandle()关闭串口句柄。

初始化时应注意CreateFile()函数中串口共享方式应设为0,串口为不可共享设备,其它与一般文件读写类似。

以下给出API实现的源代码。

1.1发送的例程

//声明全局变量

HANDLEm_hIDComDev;

OVERLAPPEDm_OverlappedRead,m_OverlappedWrite;

//初始化串口

voidCSerialAPIView:

:

OnInitialUpdate()

{

CView:

:

OnInitialUpdate();

CharszComParams[50];

DCBdcb;

Memset(&m_OverlappedRead,0,sizeof(OVERLAPPED));

Memset(&m_OverlappedWrite,0,sizeof(OVERLAPPED));

m_hIDComDev=NULL;

m_hIDComDev=CreateFile(“COM2”,GENERIC_READ│GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL│FILE_FLAG_OVERLAPPED,NULL);

if(m_hIDComDev==NULL)

{

AfxMessageBox(“Cannotopenserialport!

”);

gotoendd;

}

memset(&m_OverlappedRead,0,sizeof(OVERLAPPED));

memset(&m_OverlappedWrite,0,sizeof(OVERLAPPED));

COMMTIMEOUTSCommTimeOuts;

CommTimeOuts.ReadIntervalTimeout=0×FFFFFFFF;

CommTimeOuts.ReadTotalTimeoutMultiplier=0;

CommTimeOuts.ReadTotalTimeoutConstant=0;

CommTimeOuts.WriteTotalTimeoutMultiplier=0;

CommTimeOuts.WriteTotalTimeoutConstant=5000;

SetCommTimeouts(m_hIDComDev,&CommTimeOuts);

Wsprintf(szComparams,“COM2:

9600,n,8,1”);

m_OverlappedRead.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);

m_OverlappedWrite.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);

dcb.DCBlength=sizeof(DCB);

GetCommState(m_hIDComDev,&dcb);

dcb.BaudRate=9600;

dcb.ByteSize=8;

unsignedcharucSet;

ucSet=(unsignedchar)((FC_RTSCTS&FC_DTRDSR)!

=0);

ucSet=(unsignedchar)((FC_RTSCTS&FC_RTSCTS)!

=0);

ucSet=(unsignedchar)((FC_RTSCTS&FC_XONXOFF)!

=0);

if(!

SetCommState(m_hIDComDev,&dcb)‖

!

SetupComm(m_hIDComDev,10000,10000)‖

m_OverlappedRead.hEvent==NULL‖

m_OverlappedWrite.hEvent==NULL)

{

DWORDdwError=GetLastError();

if(m_OverlappedRead.hEvent!

=NULL)CloseHandle(m_OverlappedRead.hEvent);

if(m_OverlappedWrite.hEvent!

=NULL)CloseHandle(m_OverlappedWrite.hEvent);

CloseHandle(m_hIDComDev);

}

endd:

;

}

//发送数据

voidCSerialAPIView:

:

OnSend()

{

charszMessage[20]=“thankyouverymuch”;

DWORDdwBytesWritten;

for(inti=0;i<sizeof(szMessage);i++)

{

WriteFile(m_hIDComDev,(LPSTR)&szMessage[i],1,&dwBytesWritten,&m_OverlappedWrite);

if(WaitForSingleObject(m_OverlapperWrite,hEvent,1000))dwBytesWritten=0;

else{

GentOverlappedResult(m_hIDComDev,&m_OverlappedWrite,&dwBytesWritten,FALSE);

m_OverlappedWrite.Offset+=dwBytesWritten;

}

dwBytesWritten++;

}

}

1.2接收例程

DCBComDcb;//设备控制块

HANDLEhCom;//globalhandle

hCom=CreateFile("COM1",GENERIC_READ|GENERIC_WRITE,0,

NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);

if(hCom==INVALID_HANDLE_VALUE)

{

AfxMessageBox("无法打开串行口");

}

else

{

COMMTIMEOUTSCommTimeOuts;

SetCommMask(hCom,EV_RXCHAR);

SetupComm(hCom,4096,4096);/*设置收发缓冲区尺寸为4K*/

PurgeComm(hCom,PURGE_TXABORT|PURGE_RXABORT|

PURGE_TXCLEAR|PURGE_RXCLEAR);//清收发缓冲区

//以下初始化结构变量CommTimeOuts,设置超时参数CommTimeOuts.ReadIntervalTimeout=0×FFFFFFFF;

CommTimeOuts.ReadTotalTimeoutMultiplier=0;

CommTimeOuts.ReadTotalTimeoutConstant=4000;

CommTimeOuts.WriteTotalTimeoutMultiplier=0;

CommTimeOuts.WriteTotalTimeoutConstant=4000;

SetCommTimeouts(hCom,&CommTimeOuts);//设置超时参数

ComDcb.DCBlength=sizeof(DCB);

GetCommState(hCom,&ComDcb);//获取当前参数

ComDcb.BaudRate=9600;//波特率

ComDcb.ByteSize=8;//数据位

ComDcb.Parity=0;/*校验0~4=no,odd,even,mark,space*/

SetCommState(hCom,&ComDcb);

}//设置新的通信参数

接收可用定时器或线程等

DWORDdRead,dReadNum;

unsignedcharbuff[200];

dRead=ReadFile(hCom,buff,100,&dReadNum,NULL);//接收100个字符,

//dReadNum为实际接收字节数

2利用端口函数直接操作

这种方式主要是采用两个端口函数_inp(),_outp()实现对串口的读写,其中读端口函数的原型为:

int_inp(unsignedshotport)

该函数从端口读取一个字节,端口号为0~65535。

写端口的函数原型为:

int_outp(unsignedshotport,intdatabyte)

该函数向指定端口写入一个字节。

不同的计算机串口地址可能不一样,通过向串口的控制及收发寄存器进行读写,可以实现灵活的串口通信功能,由于涉及具体的硬件电路讨论比较复杂,在此不加赘述。

3MSComm控件

MSComm控件是微软开发的专用通信控件,封装了串口的所有功能,使用很方便,但在实际应用中要小心对其属性进行配置。

下面详细说明该类应用方法。

3.1MSComm控件的属性

CommPort:

设置串口号,类型short:

1-comm12-comm2.

Settings:

设置串口通信参数,类型CString:

B波特率,P奇偶性(N无校验,E偶校验,O奇校验),D字节有效位数,S停止位。

PortOpen:

设置或返回串口状态,类型BOOL:

TURE打开,FALSE关闭。

InputMode:

设置从接收缓冲区读取数据的格式,类型long:

0-Text1-Bin。

Input:

从接收缓冲区读取数据,类型VARIANT。

InBufferCount:

接收缓冲区中的字节数,类型:

short。

InBufferSize:

接收缓冲区的大小,类型:

short。

Output:

向发送缓冲区写入数据,类型:

VARIANT。

OutBufferCount:

发送缓冲区中的字节数,类型:

short。

OutBufferSize:

发送缓冲区的大小,类型:

short。

InputLen:

设置或返回Input读出的字节数,类型:

short。

CommEvent:

串口事件,类型:

short。

3.2程序示例

串口初始化

if(!

m_comm.GetPortOpen())

m_comm.SetPortOpen(TURE);/*打开串口*/

m_comm.SetSettings("4800,n,8,1");/*串口参数设置*/

m_comm.SetInputMode(0);/*设置TEXT缓冲区输入方式*/

m_comm.SetRthresHold

(1);/*每接收一个字符则激发OnComm()事件*/

接收数据

m_comm.SetInputLen

(1);/*每次读取一个字符

VARINATV1=m_comm.GetInput();

/*读入字符*/

m_V1=V1.bstrval;

发送字符m_comm.SetOutput(Colevariant("Hello");/*发送“Hello”*/

3.3注意

SetOutput方法可以传输文本数据或二进制数据。

用SetOutput方法传输文本数据,必须定义一个包含一个字符串的Variant。

发送二进制数据,必须传递一个包含字节数组的Variant到Output属性。

正常情况下,如果发送一个ANSI字符串到应用程序,可以以文本数据的形式发送。

如果发送包含嵌入控制字符、Null字符等的数据,要以二进制形式发送。

此处望引起读者注意,笔者曾经在此犯错。

4VC++类CSerial

4.1串行通信类CSerial简介

Cserial是由MuMegaTechnologies公司提供的一个免费的VC++类,可方便地实现串行通信。

以下为该类定义的说明部分。

classCSerial

{

public:

CSerial();

~CSerial();

BOOLOpen(intnPort=2,intnBaud=9600);

BOOLClose(void);

intReadData(void*,int);

intSendData(constchar*,int);

intReadDataWaiting(void);

BOOLIsOpened(void){return(m_bOpened);}

protected:

BOOLWriteCommByte(unsignedchar);

HANDLEm_hIDComDev;

OVERLAPPEDm_OverlappedRead,m_OverlappedWrite;

BOOLm_bOpened;

}

4.2串行通信类Cserial成员函数简介

1.CSerial:

Cserial是类构造函数,不带参数,负责初始化所有类成员变量。

2.CSerial:

:

Open这个成员函数打开通信端口。

带两个参数,第一个是埠号,有效值是1到4,第二个参数是波特率,返回一个布尔量。

3.CSerial:

:

Close函数关闭通信端口。

类析构函数调用这个函数,所以可不用显式调用这个函数。

4.CSerial:

:

SendData函数把数据从一个缓冲区写到串行端口。

它所带的第一个参数是缓冲区指针,其中包含要被发送的资料;这个函数返回已写到端口的实际字节数。

5.CSerial:

:

ReadDataWaiting函数返回等待在通信端口缓冲区中的数据,不带参数。

6.CSerial:

:

ReadData函数从端口接收缓冲区读入数据。

第一个参数是void*缓冲区指针,资料将被放入该缓冲区;第二个参数是个整数值,给出缓冲区的大小。

4.3应用VC类的一个实例

1.固定式EBM气溶胶灭火系统简介

固定式EBM气溶胶灭火装置分区启动器是专为EBM灭火装置设计的自动控制设备。

可与两线制感温、感烟探测器配套使用,当监测部位发生火情时,探测器发出电信号给分区启动器,经逻辑判断后发出声、光报警,延时后自动启动EBM灭火装置。

为了便于火灾事故的事后分析,需对重要的火警事件和关键性操作进行记录,记录应能从PC机读出来;PC机能控制、协调整个系统的工作,这些都涉及通信。

本例中启动器采用RS-485通信接口,系统为主从式网络,PC机为上位机。

具体的通信协议为:

(1)下位机定时向上传送记录的事件;

(2)应答发送,即PC机要得到最新事件记录,而传送时间未到时,PC机发送命令,下位机接收命令后,把最新记录传给上位机;(3)上位机发送其它命令如校时、启动、停止、手/自动等。

2.通信程序设计

部分上位机程序

(1)发送命令字程序,代码如下

voidCCommDlg:

:

OnSend()

{

CSerialSerial;

//构造串口类,初始化串行口

if(Serial.Open(2,9600))//if-1

//打开串行口2,波特率为9600bps

{

staticcharszMessage[]="0";

//命令码(可定义各种命令码)

intnBytesSent;

intcount=0;

resend:

nBytesSent=Serial.SendData(szMessage,strlen(szMessage));

//发送命令码

charrdMessage[20];

if(Serial.ReadDataWaiting())//if-2

{

Serial.ReadData(rdMessage,88);

//rdMessage定义接收字节存储区,为全局变量//

if((rdMessage[0]!

=0x7f)&&(count<3))

{

count++;

gotoresend

}

if(count>=3)

MessageBox(“发送命令字失败”);

}

else//if-2

MessageBox("接收数据错误");

}

else//if-1

MessageBox("串行口打开失败");

}

下位机通信程序:

#include

#include

#include

#definecount9

#definecom_code0x00

#definecom_code10xff

unsignedcharbuffer[count];

intpo,year,month,date,hour;

intminute,second,recordID;

intsum;

main()

{

/*初始化串口和定时器*/

TMOD=0×20;

TH1=0×fd;

TR1=0×01;

ET1=0×00;

ES=1;

EA=1;

/*待发送数据送缓冲区*/

buffer[0]=0×ff;//数据特征码

buffer[1]=count+1;//数据长度

buffer[2]=year;//年

buffer[3]=month;//月

buffer[4]=date;//日

buffer[5]=hour;//时

buffer[6]=minute;//分

buffer[7]=second;//秒

buffer[8]=recordID;//事件号

for(po=0;po

sum+=buffer[po];

buffer[9]=sum;//校验和

}

/*发送中断服务程序*/

voidsend(void)interrupt4using1

{

inti;

RI=0;

EA=0;

do

{

for(i=0;i<=count;i++)

{

SBUF=buffer[i];//发送数据和校验和//

while(TI==0);

TI=0;

}

while(RI==0);

RI=0;

}while(SBUF!

=0);//主机接收不正确,重新发送//

EA=1;

Return;

}

5应用总结

根据不同需要,选择合适的方法。

我们选用的用VC++类实现的上位机和下位机的串行通信方法具有使用简单、编写程序方便的特点。

经过半年多应用于EBM灭火系统的情况来看,该方法实现的系统运行稳定可靠,是一种值得推广的简单易行的通信方法。

参考文献

1KateGregoryVisualC++6开发使用手册.北京:

机械工业出版社,1999

2何立民.单片机的C语言应用程序设计.北京:

北京航空航天大学出版社,1997

3马风格.VC控件与串行通讯.1999现代计算机,2000(4)

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 初中教育 > 语文

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2