前几天找这个源码,没有找到,今天找到了,有打开串口参数设置对话框,梳理一下关键实现代码:
主界面如下:
打开软件,设置初始的变量,串口参数:
// CCommWizardDlg dialogCCommWizardDlg::CCommWizardDlg(CWnd* pParent /*=NULL*/) : CDialog(CCommWizardDlg::IDD, pParent){ bSend = FALSE;//自动发送标志 bReceive = FALSE;//自动接收标志 m_nPort = 1;//端口号 m_strSettings = _T("9600,n,8,1");//串口参数 m_strSendString = _T("");//发送的字符串 m_nTime = 1000;//时间间隔1s m_nInputMode = 1;//输入模式设置为1 //{ {AFX_DATA_INIT(CCommWizardDlg) m_strReceive = _T("");//文本框内容清除 //}}AFX_DATA_INIT // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);}
初始化函数中:初始化输入模式选择,
// TODO: Add extra initialization here m_ctrlDataType.AddString(_T("按ASCII码")); m_ctrlDataType.AddString(_T("按2进制"));// m_ctrlDataType.AddString(_T("按16进制")); m_ctrlDataType.SetCurSel(m_nInputMode);//初始化时是1,即按2进制
改变组合框的输入模式代码:
void CCommWizardDlg::OnSelchangeType() { // TODO: Add your control notification handler code here m_nInputMode = m_ctrlDataType.GetCurSel();}
清除接收文本框内容:
void CCommWizardDlg::OnClear() { // TODO: Add your control notification handler code here m_strReceive = _T("");//清除接收文本框内容}
主对话框中定义声明的:
// CCommWizardDlg dialogclass CCommWizardDlg : public CDialog{// Constructionpublic: char CCommWizardDlg::ConvertHexChar(char ch); int String2Hex(CString str, CByteArray &senddata);//字符串到十六进制转换 void OpenPort();//打开串口 CCommWizardDlg(CWnd* pParent = NULL); // standard constructor BOOL bSend;//发送 BOOL bReceive;//接收 int m_nInputMode;//输入模式 int m_nPort;//端口号 CString m_strSettings;//参数 CString m_strSendString;//发送的字符串 int m_nTime;//间隔时间// Dialog Data //{ {AFX_DATA(CCommWizardDlg) enum { IDD = IDD_COMMWIZARD_DIALOG }; CButton m_ctrlReceive;//接收按钮控件 CButton m_ctrlSend;//发送按钮控件 CComboBox m_ctrlDataType;//控制数据类型 输入模式 组合框控件变量 CString m_strReceive;//接收到的字符串 CMSComm m_Com;//串口控件 //}}AFX_DATA
点击设置参数后,代码如下:
void CCommWizardDlg::OnSettings() { // TODO: Add your control notification handler code here CSettingDlg setDlg;//声明类对象 setDlg.nPort = m_nPort;//上次设置的端口号值 setDlg.nTime = m_nTime;//上次设置的间隔时间值 setDlg.strSettings = m_strSettings;//上次设置的串口参数值 setDlg.strSendString = m_strSendString;//上次设置的发送字符串值 if(setDlg.DoModal() == IDOK)//弹出对话框,点确定按钮后返回值设置。 { m_nPort = setDlg.nPort;//从setDlg(参数设置类)中获取端口号 m_nTime = setDlg.nTime;//间隔时间值 m_strSettings = setDlg.strSettings;//串口参数值 m_strSendString = setDlg.strSendString;//发送字符串值 } OpenPort();//打开串口}
设置参数如下,设置串口相关参数。
点确定之后,选择的串口就被打开了,代码如下:
void CCommWizardDlg::OnSettings() { // TODO: Add your control notification handler code here CSettingDlg setDlg;//声明类对象 setDlg.nPort = m_nPort;//上次设置的端口号值 setDlg.nTime = m_nTime;//上次设置的间隔时间值 setDlg.strSettings = m_strSettings;//上次设置的串口参数值 setDlg.strSendString = m_strSendString;//上次设置的发送字符串值 if(setDlg.DoModal() == IDOK)//弹出对话框,点确定按钮后返回值设置。 { m_nPort = setDlg.nPort;//从setDlg(参数设置类)中获取端口号 m_nTime = setDlg.nTime;//间隔时间值 m_strSettings = setDlg.strSettings;//串口参数值 m_strSendString = setDlg.strSendString;//发送字符串值 } OpenPort();//打开串口}
打开串口函数:
//打开串口void CCommWizardDlg::OpenPort(){ if(m_Com.GetPortOpen()) m_Com.SetPortOpen(FALSE);//关闭串口 m_Com.SetCommPort(m_nPort); //选择串口号 if( !m_Com.GetPortOpen()) m_Com.SetPortOpen(TRUE);//打开串口 else AfxMessageBox("cannot open serial port"); m_Com.SetSettings(m_strSettings); //波特率9600,无校验,8个数据位,1个停止位 m_Com.SetRThreshold(1); //参数1表示每当串口接收缓冲区中有多于或等于1个字符时将引发一个接收数据的OnComm事件 m_Com.SetInputMode(1); m_Com.SetInputLen(0); //设置当前接收区数据长度为0 m_Com.GetInput();//先预读缓冲区以清除残留数据 }
程序中的变量的声明定义:
// CSettingDlg dialogclass CSettingDlg : public CDialog{// Constructionpublic: CSettingDlg(CWnd* pParent = NULL); // standard constructor int nPort, nTime; CString strSettings, strSendString;// Dialog Data //{ {AFX_DATA(CSettingDlg) enum { IDD = IDD_DIALOG1 }; int m_nPort; CString m_strSettings; CString m_strSendString; int m_nTime; //}}AFX_DATA
点确定后将数据保存在当前参数设置窗口类中。
自动发送:
自动发送代码:
void CCommWizardDlg::OnSend() { // TODO: Add your control notification handler code here bSend = !bSend;//取反。 if(bSend)//发送。 { m_ctrlSend.SetWindowText(_T("停止发送")); SetTimer(1,m_nTime,NULL);//发送时间为1000毫秒,启动发送。 } else//停止发送。 { m_ctrlSend.SetWindowText(_T("自动发送")); KillTimer(1); //取消发送定时。 } }
自动发送时启动定时器:
void CCommWizardDlg::OnTimer(UINT nIDEvent) { // TODO: Add your message handler code here and/or call default OnManualsend();//手动发送函数 CDialog::OnTimer(nIDEvent);}
调用手动发送函数:
void CCommWizardDlg::OnManualsend() { // TODO: Add your control notification handler code here CString strSend;//发送字符串 if(m_nInputMode > 1)//输入模式大于1(字节数组,十六进制) { CByteArray hexdata;//字节数据, int len=String2Hex(m_strSendString ,hexdata);//字符串转十六进制字节数组 m_Com.SetOutput(COleVariant(hexdata));//发送字节数组 } else m_Com.SetOutput(COleVariant(m_strSendString));//发送数据,发送字符串}
//字符串转十六进制字节数组int CCommWizardDlg::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) 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;}
接收回显方式的选择:
改变组合框输入模式选择:
void CCommWizardDlg::OnSelchangeType() { // TODO: Add your control notification handler code here m_nInputMode = m_ctrlDataType.GetCurSel();}
接收数据:
//自动接收按钮void CCommWizardDlg::OnReceive() { // TODO: Add your control notification handler code here m_Com.GetInput();//先预读缓冲区以清除残留数据 bReceive = !bReceive;//自动接收标志取反,,,定时器里有检测该变量 if(bReceive)//自动接收 m_ctrlReceive.SetWindowText(_T("停止接收"));//按钮控件文本设置 else//不自动接收 m_ctrlReceive.SetWindowText(_T("开始接收"));}
//这是一个将字符转换为相应的十六进制值的函数//功能:若是在0-F之间的字符,则转换为相应的十六进制字符,否则返回-1char CCommWizardDlg::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);}
串口控件:
BEGIN_EVENTSINK_MAP(CCommWizardDlg, CDialog) //{ {AFX_EVENTSINK_MAP(CCommWizardDlg) ON_EVENT(CCommWizardDlg, IDC_COMMCTRL, 1 /* OnComm */, OnOnCommCommctrl, VTS_NONE) //}}AFX_EVENTSINK_MAPEND_EVENTSINK_MAP()
接收函数:
void CCommWizardDlg::OnOnCommCommctrl() { // 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; if(bReceive) { if(m_Com.GetCommEvent()==2) //事件值为2表示接收缓冲区内有字符 { variant_inp = m_Com.GetInput(); //读缓冲区 safearray_inp = variant_inp; //VARIANT型变量转换为ColeSafeArray型变量 len=safearray_inp.GetOneDimSize(); //得到有效数据长度 for(k=0;k
在主对话框中加入串口控件后,引入 头文件#include "mscomm.h"
串口h文件中有这几行代码:
// CMSComm wrapper classclass CMSComm : public CWnd{protected: DECLARE_DYNCREATE(CMSComm)public: CLSID const& GetClsid() { static CLSID const clsid = { 0x648a5600, 0x2c6e, 0x101b, { 0x82, 0xb6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x14 } }; return clsid; }