博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
vc 串口精灵软件分析
阅读量:6938 次
发布时间:2019-06-27

本文共 7740 字,大约阅读时间需要 25 分钟。

前几天找这个源码,没有找到,今天找到了,有打开串口参数设置对话框,梳理一下关键实现代码:

 

主界面如下:

      

打开软件,设置初始的变量,串口参数:

// 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;    }

 

转载于:https://www.cnblogs.com/rechen/p/5085253.html

你可能感兴趣的文章