c++串口上位机调试助手的总结和部分代码

在初始化函数中添加:

// TODO: Add extra initialization here

m_bAutoSend=FALSE; //m_bAutoSend为全局变量

m_nCycleTime=1000;

m_GPSCOM.SetCommPort(1); //选择COM1

m_GPSCOM.SetInputMode(1); //输入方式为二进制方式

m_GPSCOM.SetInBufferSize(1024); //设置输入缓冲区大小

m_GPSCOM.SetOutBufferSize(512); //设置输出缓冲区大小

// m_GPSCOM.SetSettings("9600,n,8,1"); //波特率115200,无校验,8个数据位,1个停止位

if(m_GPSCOM.GetPortOpen()) //如果串口是打开的

m_GPSCOM.SetPortOpen(FALSE);//则关闭串口

//参数1表示每当串口接收缓冲区中有多于

//或等于1个字符时将引发一个接收数据的OnComm事件

m_GPSCOM.SetRThreshold(1);

m_GPSCOM.SetInputLen(0); //设置当前接收区数据长度为0

//m_GPSCOM.GetInput(); //先预读缓冲区以清除残留数据

显示接收到的内容

m_RXDATA建立的变量是CEidtl类型,不是CString

static long RXcount=0;

void CGPS_COM1Dlg::OnGPSCOM() //编辑框接收函数——用于显示串口接收到的数据

{

// TODO: Add your control notification handler code here

VARIANT variant_inp;

COleSafeArray safearray_inp;

LONG len,k;

BYTE rxdata[2048]; //设置BYTE数组 An 8-bit integerthat is not signed.

CString strtemp;

CString strRXData;

strRXData.Empty();

if(m_GPSCOM.GetCommEvent()==2) //事件值为2表示接收缓冲区内有字符

{

variant_inp=m_GPSCOM.GetInput(); //读缓冲区

safearray_inp=variant_inp; //VARIANT型变量转换为ColeSafeArray型变量

len=safearray_inp.GetOneDimSize(); //得到有效数据长度

for(k=0;k<len;k++)

safearray_inp.GetElement(&k,rxdata+k);//转换为BYTE型数组

for(k=0;k<len;k++) //将数组转换为Cstring型变量

{

BYTE bt=*(char*)(rxdata+k); //字符型

if(m_hexdisplay.GetCheck())

{

strtemp.Format("%02x ",bt); //将十六进制送入临时变量strtemp存放

}

else

{

strtemp.Format("%c",bt); //将字符送入临时变量strtemp存放

}

strRXData=strRXData+strtemp; //加入接收编辑框对应字符串

}

m_RXDATA.ReplaceSel(strRXData);

RXcount=RXcount+len;

CString rxdatacount;

rxdatacount.Format("%ld",RXcount);

// rxdatacount="接收:"+rxdatacount;

m_RXdatacount.SetWindowText(rxdatacount); //显示接收计数

}

}

//不用UpdateData(),这样写的好处就是当一直在接收时,也能自由发送而不受UpdateData()函数影响。

串口打开或关闭

void CGPS_COM1Dlg::OnButton1() //串口打开或关闭

{

// TODO: Add your control notification handler code here

if(m_ctrlAutoSend.GetCheck())

{

AfxMessageBox("请先关闭自动发送,才可以关闭串口");

}

else

{

if(!m_GPSCOM.GetPortOpen())

{

m_GPSCOM.SetPortOpen(TRUE);//打开串口

SetDlgItemText(IDC_BUTTON1,"关闭串口");

}

else

{

m_GPSCOM.SetPortOpen(FALSE);//关闭串口

SetDlgItemText(IDC_BUTTON1,"打开串口");

}

}

}

m_TXDATA建立的变量是CEidtl类型,不是CString

long TX_count=0;

void CGPS_COM1Dlg::OnButton2Tx() //数据发送函数

{

// TODO: Add your control notification handler code here

if(!m_GPSCOM.GetPortOpen())

{

AfxMessageBox("请先打开串口");

}

else

{

UpdateData(TRUE); //读取编辑框内容

if(m_strHexSend.GetCheck())

{

CByteArray hexdata;

int len=String2Hex(m_TXDATA,hexdata); //此处返回的len可以用于计算发送了多少个十六进制数

m_GPSCOM.SetOutput(COleVariant(hexdata)); //发送十六进制数据

TX_count+=(long) ((m_TXDATA.GetLength()+1)/3); //十六进制计数要注意算法

}

else

{

m_GPSCOM.SetOutput(COleVariant(m_TXDATA));//发送ASCII字符数据

TX_count+=m_TXDATA.GetLength();

}

CString strTemp;

strTemp.Format("%d",TX_count);

m_TXcount.SetWindowText(strTemp);

}

}

void CGPS_COM1Dlg::OnButton3Clear() //清除接收编辑框

{

// TODO: Add your control notification handler code here

m_RXDATA.SetWindowText("");//清除接收对话框中的数据

}

void CGPS_COM1Dlg::OnCHECK1hexdisplay()

{

// TODO: Add your control notification handler code here

}

void CGPS_COM1Dlg::OnCOMchose()

{

// TODO: Add your control notification handler code here

char str[10];

int iPos=m_COMChose.GetCurSel();

int iNum=m_COMChose.GetLBText( iPos, (LPTSTR) str) ;

int i=atoi(str+3);

if(m_GPSCOM.GetPortOpen())

{

AfxMessageBox("请先关闭串口,再选择COM口");

}

if(!m_GPSCOM.GetPortOpen())

{

m_GPSCOM.SetCommPort(i); //选择COM口

}

}

void CGPS_COM1Dlg::OnHexSend()

{

// TODO: Add your control notification handler code here

}

void CGPS_COM1Dlg::OnTimer(UINT nIDEvent)

{

// TODO: Add your message handler code here and/or call default

switch(nIDEvent)

{

case 1: OnButton2Tx();

break;

/* case 2:

m_strCurPath.SetWindowText(m_strCurPath); //重新显示路径

KillTimer(2);//关闭定时器

*/

default: ;

break;

}

CDialog::OnTimer(nIDEvent);

}

void CGPS_COM1Dlg::OnCheck2_AutoSend()

{

// TODO: Add your control notification handler code here

m_bAutoSend=!m_bAutoSend; //标志是否打开自动发送

if(m_bAutoSend)

{

if(!m_GPSCOM.GetPortOpen())

{

m_bAutoSend=!m_bAutoSend;

m_ctrlAutoSend.SetCheck(0);

AfxMessageBox("串口没有打开,请打开串口");

return;

}

else

SetTimer(1,m_nCycleTime,NULL); //设置定时器1 m_nCycleTime

}

else

{

KillTimer(1); //“杀”掉定时器1

}

}

void CGPS_COM1Dlg::OnChangeEdit_CycleTime()

{

// TODO: If this is a RICHEDIT control, the control will not

// send this notification unless you override the CDialog::OnInitDialog()

// function and call CRichEditCtrl().SetEventMask()

// with the ENM_CHANGE flag ORed into the mask.

// TODO: Add your control notification handler code here

CEdit* pEdit=(CEdit*)GetDlgItem(IDC_EDIT1);

CString strText;

pEdit->GetWindowText(strText);

m_nCycleTime=atoi(strText);

}

void CGPS_COM1Dlg::OnClearCount()

{

// TODO: Add your control notification handler code here

RXcount=0;

TX_count=0;

m_RXdatacount.SetWindowText("");//清除接收对话框中的数据

m_TXcount.SetWindowText("");//清除接收对话框中的数据

}

void CGPS_COM1Dlg::OnButtonSavedata()

{

// TODO: Add your control notification handler code here

UpdateData(TRUE);

CFile m_rFile;

LPCSTR lpszPath="c:\\comdata"; //存盘路径为c:\\comdata

SetCurrentDirectory(lpszPath);

CString m_Filename,m_name1;

m_name1=m_strFilename; //填写的名字

m_Filename=m_name1+".txt"; //以TXT格式存储

if(0==m_strFilename.GetLength())

{

AfxMessageBox("请先输入保存的文件名");

}

else

{

if(!m_rFile.Open(m_Filename,CFile::modeCreate | CFile::modeWrite))

{

AfxMessageBox("创建记录文件失败!");

return;

}

char TxtTemp[60000]; //字符串的长度

int Maxsize=60000; //

int i=m_RXDATA.GetWindowText(TxtTemp,Maxsize);//将接受编辑框的数据取出放到数组TxtTemp中

//在文件开始处写上保存日期

CTime t=CTime::GetCurrentTime();

CString str=t.Format("%Y年%m月%d日%H时%M分%S秒\r\n");

m_rFile.Write((LPCTSTR)str,str.GetLength());

//保存数据

m_rFile.Write((LPCTSTR)TxtTemp,m_RXDATA.GetWindowTextLength());

m_rFile.Flush();

m_rFile.Close(); //关闭文件

AfxMessageBox("保存成功");

UpdateData(FALSE);

}

}

在头文件中要声明这两个函数

//由于这个转换函数的格式限制,在发送框中的十六制字符应该每两个字符之间插入一个空隔

//如:A1 23 45 0B 00 29

//CByteArray是一个动态字节数组,可参看MSDN帮助

int CGPS_COM1Dlg::String2Hex(CString str, CByteArray &senddata)

{

int hexdata,lowhexdata;

int hexdatalen=0;

int len=str.GetLength();

senddata.SetSize(len/2);

for(int i=0;i<len;)

{

char lstr,hstr=str[i];

if(hstr==' ')

{

i++;

continue;

}

i++;

if(i>=len)

break;

lstr=str[i];

hexdata=ConvertHexChar(hstr);

lowhexdata=ConvertHexChar(lstr);

if((hexdata==16)||(lowhexdata==16))

break;

else

hexdata=hexdata*16+lowhexdata;

i++;

senddata[hexdatalen]=(char)hexdata;

hexdatalen++;

}

senddata.SetSize(hexdatalen);

return hexdatalen;

}

//这是一个将字符转换为相应的十六进制值的函数

//好多C语言书上都可以找到

//功能:若是在0-F之间的字符,则转换为相应的十六进制字符,否则返回-1

char CGPS_COM1Dlg::ConvertHexChar(char ch)

{

if((ch>='0')&&(ch<='9'))

return ch-0x30;

else if((ch>='A')&&(ch<='F'))

return ch-'A'+10;

else if((ch>='a')&&(ch<='f'))

return ch-'a'+10;

else return (-1);

}