-
类库文件:cncomm.h 加入VC++工程
-
StdAfx.h中加入 #include "CnComm.h"
-
界面头文件加入COM口定义 CnComm m_Com;
-
界面头文件加入消息响应函数 afx_msg LRESULT OnReceive(WPARAM, LPARAM);
-
初始化打开串口 m_Com.Open(5);
-
设置波特率等参数(可选)
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位}
-
串口绑定界面 m_Com.SetWnd(this->GetSafeHwnd());
-
加入接收函数消息映射 ON_MESSAGE(ON_COM_RECEIVE, OnReceive)
-
实现接收数据函数OnReceive
1、导入cnComm类所包含的唯一一个文件:cnComm.h
2、在主对话框中增加一个cnComm类型的成员变量
3、编写“打开”按钮响应事件
-
void CCnComm_DemoDlg::OnBtnOpen()
-
{
-
UpdateData(TRUE);
-
-
-
if(m_Com.IsOpen())
-
{
-
m_Com.Close();
-
}
-
-
-
m_Com.Open(m_ctrlComList.GetCurSel()+1,"9600,8,n,1");
-
-
-
m_Com.SetWnd(this->GetSafeHwnd());
-
-
-
if(m_Com.IsOpen())
-
{
-
m_strStatus.Format("COM%d 已经被打开",m_ctrlComList.GetCurSel()+1);
-
UpdateData(FALSE);
-
}
-
else
-
{
-
m_strStatus.Format("COM%d 打开失败",m_ctrlComList.GetCurSel()+1);
-
UpdateData(FALSE);
-
}
-
}
4、编写“关闭”按钮响应事件
-
void CCnComm_DemoDlg::OnBtnClose()
-
{
-
UpdateData(TRUE);
-
-
if(m_Com.IsOpen())
-
{
-
m_Com.Close();
-
}
-
-
if(!m_Com.IsOpen())
-
{
-
m_strStatus = "没有串口被打开";
-
UpdateData(FALSE);
-
}
-
}
5、完成发送功能:
-
void CCnComm_DemoDlg::OnBtnSend()
-
{
-
char cTx[256];
-
-
UpdateData(TRUE);
-
-
-
if(m_strTx.GetLength() == 0)
-
return;
-
-
-
if(!m_Com.IsOpen())
-
{
-
AfxMessageBox("请先打开串口");
-
return;
-
}
-
-
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;
}
-
_tcscpy(cTx,m_strTx.GetBuffer(m_strTx.GetLength()));
-
-
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 怎么添加自定义消息”。下面是消息响应函数内容:
-
//字符串转16进制
-
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;
}
-
-
//判断字符串是否为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;
}
-
-
void CCommToolDlg::ProcessData(char *str,int len)
{
//CString s;
//s.Format("length :%s\r\n",len);
//if(isHex(str,len))
-
//DDX_Check(pDX, IDC_CHECK_HEX, m_bHex);
-
//m_bHex = FALSE;
-
if(m_bHex)
{
char hex_buf[1024*3];
Ascii2Hex(str,hex_buf,len);
comm_data += hex_buf;
}
UpdateData(FALSE);
AfxMessageBox(_T("File write."));
-
file.Write(str,len);
}
-
-
void CCnComm_DemoDlg::OnComReceive()
-
{
-
char cRx[1024];
-
CString strTemp;
-
-
int len = m_Com.Read(cRx,1024);
-
-
ProcessData(cRx,len);
-
-
strTemp.Format("%s",cRx);
-
m_strRx = m_strRx + strTemp;
-
-
UpdateData(FALSE);
-
}
9、测试接收功能,这里我利用了只用一个串口测试通信程序的方法,我把我电脑上的唯一一个串口的第2和第3脚短接(相当于短接了发送和接收脚),打开程序,在发送框中填入要发送的字符串,点发送,接收框里马上会收到刚发送的内容。
阅读(4743) | 评论(0) | 转发(0) |