今天按照书上学习了一下API串口通信,并实际编程练习一番。
1.首先在vs6.0上建立一个新的MFC应用程序工程,选择单文档,基类采用CEditView(采用这个类的原因是在视图中具有文本编辑功能,同允许进行输入和编辑文本)。由此构建主界面。
2.新建一个dialog,用来设置com口、波特率、以及奇偶校验等。其中的选择是采用组合框。向组合框添加文本有三种方法:
一是:在组合框的Data项中,先输入文本,按ctrl+Enter,换行继续输入
二是:在class wizard中为组合框增加成员变量如m_Com,然后用m_Com.AddString("COM1");以此类推;
三是:采用获取组合框ID,然后调用AddString()函数,(CComboBox *)GetDlgItem(IDC_COMBO1)->AddString("COM1");
3.在头文件中申明必要的变量,我的设置时:
HANDLE hCom; //串口句柄
OVERLAPPED Wol; //写操作OVERLAPPED 结构变量
BYTE myWByte[300]; //存放将写数据
long dataWLen; //发送数据长度
CSetupDlg mySetupDlg; //声明设置对话框实例
LPCTSTR myCom; //串口名称
BYTE myParity; //校验类型
DWORD myfParity; //是否使用校验位
DWORD myBaudRate; //波特率
bool blnOpened; //串口已经打开标志
同时将设置对话框头文件和主框架窗口头文件放到视图头文件中:
#include "SetupDlg.h"
#include "MainFrm.h"
4.设置串口,通过对设置按钮增加相应即可,用来设置COM口、奇偶校验、波特率等
CString strStatus;
if (mySetupDlg.DoModal()==IDOK)
{
switch (mySetupDlg.m_Com)
{
case 0 :
{
strStatus="COM1";
myCom="COM1";
break;
}
case 1 :
{
strStatus="COM2";
myCom="COM2";
break;
}
case 2 :
{
strStatus="COM3";
myCom="COM3";
break;
}
case 3 :
{
strStatus="COM4";
myCom="COM4";
break;
}
// case 4 :
// {
// strStatus="COM1";
// myCom="COM1";
// break
// }
break;
}
strStatus+=",";
switch(mySetupDlg.m_BaudRate)
{
case 0 :
{
strStatus="19200";
myBaudRate=CBR_19200;
break;
}
case 1 :
{
strStatus="9600";
myBaudRate=CBR_9600;
break;
}
case 2 :
{
strStatus="4800";
myBaudRate=CBR_4800;
break;
}
break;
}
strStatus+=",";
switch(mySetupDlg.m_Parity)
{
case 0 :
{
myfParity=false;
myParity=NOPARITY;
strStatus+="N";
break;
}
case 1 :
{
myfParity=TRUE;
myParity=ODDPARITY;
strStatus+="O";
break;
}
case 2 :
{
myfParity=true;
myParity=EVENPARITY;
strStatus+="E";
break;
}
}
strStatus+=",8,1";
CMainFrame *m_pGetFrame=(CMainFrame *)AfxGetApp()->m_pMainWnd; //获取程序框架指针
strStatus="TTY 发送程序-"+strStatus; //设置程序框架标题文本
m_pGetFrame->SetWindowText(strStatus);
}
5.打开串口,用来设置当前串口参数,一般采用CreateFile()函数来打开串口,用GetCommState()函数获取当前串口配置,之后用
DCB结构来设置具体com口、波特率、奇偶校验等参数,设置完后用SetCommState()函数实现这些配置
CString strDis;
hCom=CreateFile(myCom,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if (hCom!=INVALID_HANDLE_VALUE)
{
SetupComm(hCom,1024,512);
DCB myDCB;
GetCommState(hCom,&myDCB);
myDCB.BaudRate=myBaudRate;
myDCB.fBinary=TRUE;
myDCB.fParity=myfParity;
myDCB.ByteSize=8;
myDCB.Parity=myParity;
myDCB.StopBits=ONESTOPBIT;
SetCommState(hCom,&myDCB);
AfxMessageBox("串口打开成功!");
blnOpened=TRUE;
}
else
{
AfxMessageBox("串口打开失败!");
blnOpened=FALSE;
}
}
6.关闭串口,调用CloseHandle()函数实现。
if ((blnOpened)&&(hCom!=NULL))
{
CloseHandle(hCom);
AfxMessageBox("串口已经关闭!");
blnOpened=false;
}
else
{
AfxMessageBox("串口未打开!");
}
7.发送字符,用OnChar()函数来实现。
myWByte[0]=nChar;
dataWLen=1;
Wol.Internal=0;
Wol.InternalHigh=0;
Wol.Offset=0;
Wol.OffsetHigh=0;
Wol.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
WriteFile(hCom,&myWByte,dataWLen,NULL,&Wol);
// Beep(1000,10);
CEditView::OnChar(nChar,nRepCnt,nFlags);
CEditView::OnChar(nChar, nRepCnt, nFlags);
8.更新菜单命令
void CTTYView::OnUpdateSetupcom(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
if (!blnOpened)
{
pCmdUI->Enable(true);
}
else
{
pCmdUI->Enable(false);
}
}
void CTTYView::OnUpdateOpencom(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
if (!blnOpened)
{
pCmdUI->Enable(true);
}
else
{
pCmdUI->Enable(false);
}
}
void CTTYView::OnUpdateClosecom(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
if (blnOpened)
{
pCmdUI->Enable(true);
}
else
{
pCmdUI->Enable(false);
}
}
void CTTYView::OnUpdateAppExit(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
if (blnOpened)
{
pCmdUI->Enable(true);
}
else
{
pCmdUI->Enable(false);
}
}