Chinaunix首页 | 论坛 | 博客
  • 博客访问: 515659
  • 博文数量: 77
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 689
  • 用 户 组: 普通用户
  • 注册时间: 2013-08-12 08:40
文章分类

全部博文(77)

文章存档

2018年(1)

2016年(3)

2015年(24)

2014年(49)

我的朋友

分类: C/C++

2014-10-16 19:05:58

  1. 类库文件:cncomm.h 加入VC++工程
  2. StdAfx.h中加入 #include "CnComm.h"
  3. 界面头文件加入COM口定义  CnComm m_Com;
  4. 界面头文件加入消息响应函数 afx_msg LRESULT OnReceive(WPARAM, LPARAM);
  5. 初始化打开串口 m_Com.Open(5);                         
  6. 设置波特率等参数(可选)  
    m_Com.SetState(DWORD dwBaudRate, BYTE btParity = NOPARITY, BYTE btByteSize = 8, BYTE btStopBits = ONESTOPBIT);
    dwBaudRate:波特率,9600,19200,38400等; 
    btParity:奇偶校验,{ NOPARITY 无校验, ODDPARITY 偶校验, EVENPARITY 奇校验, MARKPARITY 1校验, SPACEPARITY 0校验} 
    btByteSize:数据位数,{4, 5, 6, 7, 8} 
    btStopBits:停止位数,{ ONESTOPBIT 1位 , ONE5STOPBITS 1.5位 , TWOSTOPBITS 2位}
  7. 串口绑定界面 m_Com.SetWnd(this->GetSafeHwnd());
  8. 加入接收函数消息映射    ON_MESSAGE(ON_COM_RECEIVE, OnReceive)
  9. 实现接收数据函数OnReceive

1、导入cnComm类所包含的唯一一个文件:cnComm.h
2、在主对话框中增加一个cnComm类型的成员变量
 
  1. public:  
  2.     cnComm m_Com;   //默认启动监视线程, 异步 

3、编写“打开”按钮响应事件 

  1. void CCnComm_DemoDlg::OnBtnOpen()   
  2. {  
  3.     UpdateData(TRUE);   //保存发送编辑框里的内容  
  4.  
  5.     //先关闭已经被打开的串口  
  6.     if(m_Com.IsOpen())  
  7.     {  
  8.         m_Com.Close();  
  9.     }  
  10.  
  11.     //打开串口  
  12.     m_Com.Open(m_ctrlComList.GetCurSel()+1,"9600,8,n,1");  
  13.  
  14.     //设定需要监视串口数据接收的窗口  
  15.     m_Com.SetWnd(this->GetSafeHwnd());  
  16.  
  17.     //判断是否打开成功  
  18.     if(m_Com.IsOpen())  
  19.     {  
  20.         m_strStatus.Format("COM%d 已经被打开",m_ctrlComList.GetCurSel()+1);  
  21.         UpdateData(FALSE);  
  22.     }  
  23.     else 
  24.     {  
  25.         m_strStatus.Format("COM%d 打开失败",m_ctrlComList.GetCurSel()+1);  
  26.         UpdateData(FALSE);  
  27.     }  
  28. }  

 

4、编写“关闭”按钮响应事件

  1. void CCnComm_DemoDlg::OnBtnClose()   
  2. {  
  3.     UpdateData(TRUE);   //保存发送编辑框里的内容  
  4.  
  5.     if(m_Com.IsOpen())  
  6.     {  
  7.         m_Com.Close();  
  8.     }  
  9.  
  10.     if(!m_Com.IsOpen())  
  11.     {  
  12.         m_strStatus = "没有串口被打开";  
  13.         UpdateData(FALSE);  
  14.     }  
  15. }  

 5、完成发送功能:

  1. void CCnComm_DemoDlg::OnBtnSend()   
  2. {  
  3.     char cTx[256];  
  4.  
  5.     UpdateData(TRUE);   //取得发送编辑框中的内容  
  6.       
  7.     //没有任何内容则立即返回  
  8.     if(m_strTx.GetLength() == 0)  
  9.         return;  
  10.  
  11.     //没有打开串口也立即返回  
  12.     if(!m_Com.IsOpen())  
  13.     {  
  14.         AfxMessageBox("请先打开串口");  
  15.         return;  
  16.     } 

  17. int Hex2Ascii(const char* hex, char* ascii)
    {
        int len = strlen(hex), tlen, i, cnt;

        for (i = 0, cnt = 0, tlen = 0; i
        {
            char c = toupper(hex[i]);

            if ((c>='0'&& c<='9') || (c>='A'&& c<='F'))
            {
                BYTE t = (c >= 'A') ? c - 'A' + 10 : c - '0';


                if (cnt)
                    ascii[tlen++] += t, cnt = 0;
                else
                    ascii[tlen] = t << 4, cnt = 1;
            }
        }      
            ascii[tlen] = '\0';

            return tlen;
    }

  18.     _tcscpy(cTx,m_strTx.GetBuffer(m_strTx.GetLength()));  
  19.  
  20.     m_Com.Write(cTx);  

      用Write()函数发送数据时,如果字符串中有00,则被丢弃,建议使用WritePort()函数。例如:m_Com.WritePort(buf,len);

8、完成读串口功能。cnComm类可以自己启动一个监视线程来监视串口是否收到数据,当收到数据时会向由cnComm::SetWnd(hWnd)函数设定的窗口发送ON_COM_RECEIVE消息。下面我们在主窗口中完成ON_COM_RECEIVE消息响应函数,这里就不啰嗦怎么加了,不知道的话可以google“VC 怎么添加自定义消息”。下面是消息响应函数内容: 

  1. //字符串转16进制
  2. int Ascii2Hex(const char* ascii, char* hex,int len)
    {
        int i;
        char chHex[] = "0123456789ABCDEF";

        for (i = 0; i     {
            hex[i*3] = chHex[((BYTE)ascii[i]) >> 4];
            hex[i*3 +1] = chHex[((BYTE)ascii[i]) & 0xf];
            hex[i*3 +2] = ' ';
        }

        hex[len * 3] = '\0';

        return len * 3;
    }

  3. //判断字符串是否为16进制
    int CCommToolDlg::isHex(const char* pBuf, int bufSize)  
    {  
        int i = 0;  
      
        if ((NULL == pBuf) || (0 == bufSize))  
        {  
            return -1;  
        }  
      
        for (i = 0; i < bufSize; ++i)  
        {  
            if (('0' > pBuf[i] || '9' < pBuf[i])  
                && ('A' > pBuf[i] || 'F' < pBuf[i])  
                && ('a' > pBuf[i] || 'f' < pBuf[i]))  
            {  
                return -1;  
            }  
        }  
      
        return 1;  
    }

  4. void CCommToolDlg::ProcessData(char *str,int len)
    {
        //CString s;
        //s.Format("length :%s\r\n",len);
        //if(isHex(str,len))
  1.     //DDX_Check(pDX, IDC_CHECK_HEX, m_bHex);
  2.     //m_bHex = FALSE;
  3.     if(m_bHex)
        {
            char hex_buf[1024*3];
            Ascii2Hex(str,hex_buf,len);
            comm_data += hex_buf;
        }

        UpdateData(FALSE);

        AfxMessageBox(_T("File write."));

  4.     file.Write(str,len);
    }


  5. void CCnComm_DemoDlg::OnComReceive()  
  6. {  
  7.     char cRx[1024];  
  8.     CString strTemp;  
  9.  
  10.     int len = m_Com.Read(cRx,1024);   //读取一个字符(意第二个参数含义)
  11.     str[len] = _T('\0');  
  12.     ProcessData(cRx,len);

  13.     strTemp.Format("%s",cRx);  
  14.     m_strRx = m_strRx + strTemp;  
  15.  
  16.     UpdateData(FALSE);  //显示接收内容  

9、测试接收功能,这里我利用了只用一个串口测试通信程序的方法,我把我电脑上的唯一一个串口的第2和第3脚短接(相当于短接了发送和接收脚),打开程序,在发送框中填入要发送的字符串,点发送,接收框里马上会收到刚发送的内容。

阅读(4743) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~