上一节中已经完成了一次设置多个对话框中串口控件的串口flag,那么现在要实现的功能是打开串口后进行收发数据了,而且有多个编辑框,编辑框中数据是整形,中间涉及到进制转换。
void CDLG_CI::OnBnClickedStart() { // TODO: 在此添加控件通知处理程序代码 CByteArray senddata; int data1 = 0xAA, data2 = 0x55, data3 = 0x08, data4 = 0x00, data5 = 0x00, data6 = 0x00, data7 = 0x00, data8 = 0x00, data9 = 0x00, data10 = 0x00, data11 = 0x00, data12 = 0x00, data13 = 0x00, data14 = 0x00, data15 = 0x00, data16 = 0x00, data17 = 0x00, data18 = 0x00, data19 = 0x00, data20 = 0x00, data21 = 0x00, data22 = 0x00, data23 = 0x00, data24 = 0x00, data25 = 0x00, data26 = 0x00, data27 = 0x00, data28 = 0x00, data29 = 0x00, data30 = 0x00, data31 = 0x00, data32 = 0x00, data33 = 0x00, data34 = 0x00, data35 = 0x00, data36 = data1 + data2 + data3 + data4 + data5 + data6 + data7 + data8 + data9 + data10 + data11 + data12 + data13 + data14 + data15 + data16 + data17 + data18 + data19 + data20 + data21 + data22 + data23 + data24 + data25 + data26 + data27 + data28 + data29 + data30 + data31 + data32 + data33 + data34 + data35, data37 = (data36 & 0xff00) >> 8, data38 = (data36 & 0xff); //将其转化为数值类型 senddata.Add(data1); senddata.Add(data2); senddata.Add(data3); senddata.Add(data4); senddata.Add(data5); senddata.Add(data6); senddata.Add(data7); senddata.Add(data8); senddata.Add(data9); senddata.Add(data10); senddata.Add(data11); senddata.Add(data12); senddata.Add(data13); senddata.Add(data14); senddata.Add(data15); senddata.Add(data16); senddata.Add(data17); senddata.Add(data18); senddata.Add(data19); senddata.Add(data20); senddata.Add(data21); senddata.Add(data22); senddata.Add(data23); senddata.Add(data24); senddata.Add(data25); senddata.Add(data26); senddata.Add(data27); senddata.Add(data28); senddata.Add(data29); senddata.Add(data30); senddata.Add(data31); senddata.Add(data32); senddata.Add(data33); senddata.Add(data34); senddata.Add(data35); senddata.Add(data37); senddata.Add(data38); m_mscomm_ci.put_Output(COleVariant(senddata));//发送数据 }
这里要注意的地方是编辑框中的内容是可以直接获取的,不用添加变量也行,非常方便。
这里加了一个buffer和strtemp可以实现buffer区域的缓存足够,不然会有buffer too small 的bug。同时用到了两个函数,把收到的数据转成16进制数存储。
//将字符转换十六进制 char CDLG::HexChar(char c) { if ((c >= '0') && (c <= '9')) return c - 0x30; else if ((c >= 'A') && (c <= 'F')) return c - 'A' + 10; else if ((c >= 'a') && (c <= 'f')) return c - 'a' + 10; else return -1; } //将字符串转换成十六进制 int CDLG::Str2Hex(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 = HexChar(hstr); //高位转换 lowhexdata = HexChar(lstr); //低位转换 if((hexdata==16)||(lowhexdata==16)) break; else hexdata = hexdata * 16 + lowhexdata; i++; senddata[hexdatalen] = (char)hexdata; hexdatalen++; } return hexdatalen; }函数定义部分: 放在头文件的public部分:
char CDLG::HexChar(char c); int CDLG::Str2Hex(CString str, CByteArray& senddata);这里要把一串数据中的其中两个拼接起来,本来是想着把得到的16进制数组中的元素再转化为字符串的,后来发现这样做倒不如直接在开始就提取出来,因为想要的数据位置知道。 如下:
void CCARDNUM::OnCommMscommCardnum() { // TODO: 在此处添加消息处理程序代码 VARIANT variant_inp; COleSafeArray safearray_inp; long len, k; byte rxdata[1024]; //设置 BYTE 数组 CString strtemp, buffer,strcard; static unsigned int Receive_flag = 0; if (m_mscomm_cardnum.get_CommEvent() == 2) //值为 2 表示接收缓冲区内有字符 { variant_inp = m_mscomm_cardnum.get_Input(); //读缓冲区消息 safearray_inp = variant_inp; ///变量转换 len = safearray_inp.GetOneDimSize(); //得到有效的数据长度 //将数组转换为 CString 型变量 for (k = 0; k < len; k++) { safearray_inp.GetElement(&k, rxdata + k); strtemp.Format("X", *(rxdata + k)); buffer += strtemp; } strcard.Format("%sX", strcard, *(rxdata + 3)); strcard.Format("%sX", strcard, *(rxdata + 4)); } buffer.TrimLeft(); buffer.TrimRight(); CByteArray receivedata; int receivedatalen; receivedatalen = Str2Hex(buffer, receivedata); int data36 = receivedata[0] + receivedata[1] + receivedata[2] + receivedata[3] + receivedata[4] + receivedata[5] + receivedata[6] + receivedata[7] + receivedata[8] + receivedata[9] + receivedata[10] + receivedata[11] + receivedata[12] + receivedata[13] + receivedata[14] + receivedata[15] + receivedata[16] + receivedata[17] + receivedata[18] + receivedata[19] + receivedata[20] + receivedata[21] + receivedata[22] + receivedata[23] + receivedata[24] + receivedata[25] + receivedata[26] + receivedata[27] + receivedata[28] + receivedata[29] + receivedata[30] + receivedata[31] + receivedata[32] + receivedata[33] + receivedata[34], data37 = (data36 & 0xff00) >> 8, data38 = (data36 & 0xff); if ((receivedata[35] == data37) && (receivedata[36] == data38)) { if ((receivedata[2] == 0x01)) { MyPublicData.Public_card = strcard; m_cardnum = strcard; SetDlgItemText(IDC_CARDSHOW, m_cardnum); AfxMessageBox(_T("已识别卡号!")); m_StateLed1.SetIcon(m_hIconLedGreen); } } else { m_mscomm_cardnum.put_PortOpen(FALSE); AfxMessageBox(_T("串口数据有误,请重新加载参数!")); m_StateLed1.SetIcon(m_hIconLedRed); } }