1 Windows API通信函数方法
与通信有关的Windows API函数共有26个,但主要有关的有:
CreateFile() 用 “comn”(n为串口号)作为文件名就可以打开串口。
ReadFile() 读串口。
WriteFile() 写串口。
CloseHandle() 关闭串口句柄。
初始化时应注意CreateFile()函数中串口共享方式应设为0,串口为不可共享设备,其它与一般文件读写类似。以下给出API实
现的源代码。
1.1 发送的例程
//声明全局变量 HANDLE m_hIDComDev; OVERLAPPED m_OverlappedRead, m_Over lappedWrite; //初始化串口 void CSerialAPIView::OnInitialUpdate() { CView::OnInitialUpdate(); Char szComParams[50]; DCB dcb; 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(“Can not open serial port!”); goto endd; } memset(&m_OverlappedRead, 0, sizeof (OVERLAPPED)); memset(&m_OverlappedWrite, 0, sizeof (OVERLAPPED)); COMMTIMEOUTS CommTimeOuts; 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; unsigned char ucSet; ucSet = (unsigned char) ((FC_RTSCTS&FC_DTRDSR) != 0); ucSet = (unsigned char) ((FC_RTSCTS&FC_RTSCTS) ! = 0); ucSet = (unsigned char) ((FC_RTSCTS&FC_XONXOFF) ! = 0); if (!SetCommState(m_hIDComDev, &dcb)‖ !SetupComm(m_hIDComDev,10000,10000)‖ m_OverlappedRead. hEvent ==NULL‖ m_OverlappedWrite. hEvent ==NULL) { DWORD dwError = GetLastError(); if (m_OverlappedRead. hEvent != NULL) CloseHandle(m_OverlappedRead. hEvent); if (m_OverlappedWrite. hEvent != NULL) CloseHandle(m_OverlappedWrite. hEvent); CloseHandle(m_hIDComDev); } endd: ; } //发送数据 void CSerialAPIView::OnSend() { char szMessage[20] = “thank you very much”; DWORD dwBytesWritten; for (int i=0; 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++; } }
DCB ComDcb; //设备控制块 HANDLE hCom; //global handle hCom = CreateFile ("COM1",GENERIC_READ| GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); if (hCom==INVALID_HANDLE_&118alue) { AfxMessageBox("无法打开串行口"); } else { COMMTIMEOUTS CommTimeOuts ; 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 ) ; } //设置新的通信参数 接收可用定时器或线程等 DWORD dRead,dReadNum; unsigned char buff [200]; dRead=ReadFile(hCom, buff, 100, &dReadNum, NULL); //接收100个字符, //dReadNum为实际接收字节数
实例:
部分上位机程序
(1)发送命令字程序,代码如下
void CCommDlg::OnSend()
{
CSerial Serial;
//构造串口类,初始化串行口
if (Serial.Open(2,9600)) //if-1
//打开串行口2,波特率为9600bps
{
static char szMessage[]="0";
//命令码(可定义各种命令码)
int nBytesSent;
int count=0;
resend:
nBytesSent=Serial.SendData(szMessage,strlen(szMessage));
//发送命令码
char rdMessage [20];
if (Serial.ReadDataWaiting()) //if-2
{
Serial.ReadData(rdMessage,88);
//rdMessage 定义接收字节存储区,为全局变量//
if ((rdMessage[0]!=0x7f)&&(count<3))
{
count++;
goto resend
}
if(count>=3)
MessageBox(“发送命令字失败”);
}
else //if-2
MessageBox("接收数据错误");
}
else //if-1
MessageBox("串行口打开失败");
}
下位机通信程序:
#include
#include
#include
#define count 9
#define com_code 0x00
#define com_code1 0xff
unsigned char buffer[count];
int po,year,month,date,hour;
int minute,second,recordID ;
int sum;
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; //校验和
…
}
/*发送中断服务程序*/
void send(void) interrupt 4 using 1
{
int i;
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;
}