关于十六进制发送和显示(VS上位机和下位机)
2017-06-30 21:31
190 查看
1.先上一个ASCII表
ASCII(American Standard Code for Information Interchange,美国信息交换标准代码)是基于拉丁字母的一套电脑编码系统,主要用于显示现代英语和其他西欧语言。它是现今最通用的单字节编码系统,并等同于国际标准ISO/IEC 646。
请注意,ASCII是American Standard Code for Information Interchange缩写,而不是ASCⅡ(罗马数字2),有很多人在这个地方产生误解。
在计算机中,所有的数据在存储和运算时都要使用二进制数表示(因为计算机用高电平和低电平分别表示1和0),例如,像a、b、c、d这样的52个字母(包括大写)、以及0、1等数字还有一些常用的符号(例如*、#、@等)在计算机中存储时也要使用二进制数来表示,而具体用哪些二进制数字表示哪个符号,当然每个人都可以约定自己的一套(这就叫编码),而大家如果要想互相通信而不造成混乱,那么大家就必须使用相同的编码规则,于是美国有关的标准化组织就出台了ASCII编码,统一规定了上述常用符号用哪些二进制数来表示。
美国标准信息交换代码是由美国国家标准学会(American National Standard Institute , ANSI )制定的,标准的单字节字符编码方案,用于基于文本的数据。起始于50年代后期,在1967年定案。它最初是美国国家标准,供不同计算机在相互通信时用作共同遵守的西文字符编码标准,它已被国际标准化组织(International Organization for Standardization, ISO)定为国际标准,称为ISO 646标准。适用于所有拉丁文字字母。
为了好记,总结一句话:ASCII就是相当于十进制数(二进制转换)。
2.明确一点:发送和接收数据的过程全部都是以ASCII来进行的。
3.在通信时,一般的串口通信都是以ByteArray来进行发送,那么它其实就是ASCII,那么就不需要担心数据会变化。
4.如果在网络通信中,例如一个套接字程序中,事先定义好的变量类型是char,即字符型,当发送时是以字符串来发送的话,那么发送的过程会自动以这些字符对应的ASCII进行发送。下面解决此问题。
5.十六进制发送:
void CChatClientDlg::CmdSend() //命令发送函数(16进制) { // TODO: 在此添加控件通知处理程序代码 CString temp_str; char temp_hex[1024] = { '\0' }; int strlen; int i, j; //////////////cstring 转换成 hex数组 temp_str = m_CmdWords; temp_str = temp_str.Trim();//去掉chr首尾的空格 strlen = temp_str.GetLength(); char* temp_char = (char*)(LPCTSTR)temp_str; for (j = 0, i = 0; i < strlen; i++) //字符串清除空格 { if (temp_char[i] != ' ') { temp_char[j] = temp_char[i]; j++; } } temp_char[j] = '\0';//字符串结束 for (i = 0; temp_char[i] != '\0'; i++)//判断是否为16进制字符 { if (!(((temp_char[i] >= '0') && (temp_char[i] <= '9')) || ((temp_char[i] >= 'A') && (temp_char[i] <= 'F')) || ((temp_char[i] >= 'a') && (temp_char[i] <= 'f')))) { MessageBox(_T("有非十六进制字符,请重新输入")); return; } } for (j = 0, i = 0; temp_char[i] != '\0'; i += 2)//转换为16进制 即"ef"转换为0xef { if (temp_char[i + 1] == '\0') { MessageBox(_T("输入数据个数不正确,请重新输入")); return; } temp_hex[j] = (char)(ascii2hex(temp_char[i]) * 16 + ascii2hex(temp_char[i + 1])); j++; } CString strMsg(temp_hex); strMsg = strMsg.Trim();//去掉首尾的空格 i = send(m_client, strMsg.GetBuffer(0), strMsg.GetLength(), 0); m_ListWords.AddString("发送: " + strMsg); m_ListWords.SetTopIndex(m_ListWords.GetCount() - 1); } int CChatClientDlg::ascii2hex(char ch) //ascii码转16进制 { int hex = 0; if ((ch >= '0') && (ch <= '9')) { hex = ch - '0'; } else if ((ch >= 'A') && (ch <= 'F')) { hex = ch - 'A' + 10; } else if ((ch >= 'a') && (ch <= 'f')) { hex = ch - 'a' + 10; } else { hex = -1; } return hex; }
6.十六进制显示
void CChatClientDlg::ReceiveData() //接收数据处理函数 { UpdateData(); char buffer[1024]; CString temp_str,temp_str1; CButton* p_check; p_check = (CButton*)GetDlgItem(IDC_CHECK_HEXRECEIVE); if (p_check->GetCheck() == FALSE) {//ASCII显示接受数据 int num = recv(m_client, buffer, 1024, 0); buffer[num] = '\0'; //将接收到的数据添加到列表框中 CString sTemp; sTemp.Format("收到: %s", buffer); //接收完数据后继续侦测 WSAAsyncSelect(m_client, m_hWnd, 10000, FD_READ | FD_CLOSE); m_ListWords.AddString(sTemp); m_ListWords.SetTopIndex(m_ListWords.GetCount() - 1); } else {//十六进制显示接受数据 int num = recv(m_client, buffer, 1024, 0); buffer[num] = '\0'; for (int k = 0; k < num; k++) //将数组转换为 CString 型变量 { //下一条语句,显示2个字符一个空格 temp_str.Format(_T("%-3.2x"), buffer[k]); temp_str1 += temp_str; } m_ListWords.AddString("shou: " + temp_str1); m_ListWords.SetTopIndex(m_ListWords.GetCount() - 1); } }
7.浅谈十六进制显示
一般的数据发送和接收以ByteArray来进行,而套接字中是以char型来发送和接收数据时,那么就会出现一个bug,假设PLC发送的是十六进制的AA(大于127),发出来后对应的ASCII:170,而他没有对应的字符,所以套接字中对其无法进行正常的显示了(乱码),所以最好在通信时都以ByteArray来发送接收。假如假设PLC发送的是十六进制的55,发出来后对应的ASCII:85,而他有对应的字符U,所以不勾选十六进制显示时显示U,勾选之后执行temp_str.Format(_T(“%-3.2x”), buffer[k]);temp_str1 += temp_str;把U转成十六进制55显示。
8.着重讲一下十六进制发送
比如我在一个上位机界面的编辑框中输入一个16进制数48,那么其实它是一个字符串,点击十六进制发送,此时最重要的是这一句:temp_hex[j] = (char)(ascii2hex(temp_char[i]) * 16 + ascii2hex(temp_char[i + 1]));
这里temp_hex[j]是一个char型数组,(char)右边的数据是一个整形的数据,即72,那么(char)之后得到的是什么呢?
新建一个Win32控制台程序,里面输入以下的代码:
#include "stdafx.h" #include <iostream> using namespace std; int _tmain(int argc, _TCHAR* argv[]) { char ch; int k = 48; ch = (char)k;//注意这里 cout << "x=" << ch << endl; getchar(); return 0; }
程序运行结果如下:x=0
可以看出这是ASCII表里面中0x48对应的字符。
此时就彻底醒悟了,temp_hex[j]进行发送是发送0,然后发送的过程中就是发送0对应的ASCII:72,然后在接收端程序中,例如PLC程序中,就将这个72以十六进制的方式进行显示及存储就得到的48了,完美理清!
相关文章推荐
- 关于英文ROM短信发送后对方显示为横线解决方法
- 关于微信发送中文 总是显示\u***”
- 关于VS中添加头文件时显示无法找到文件的问题
- VS2015启动运行后一直发送VsHub请求(Fiddler显示)的解决方案
- 关于opencv中imshow()函数在VS中调用不显示图像的问题
- 关于python中send发送十六进制的方法
- 关于VS2017,VS2015 中利用 EF使用Mysql 不显示数据源问题解决方案
- 关于新手c#的上位机记录 第一部分(包含完整普通串口助手及单条波形实时显示)
- Zedboard & Zynq 图像采集(五) 板端Linux下视频TCP发送 & Linux上位机QT视频显示
- VS调试的时候数字显示的是十六进制的解决办法!
- [MFC]关于VS2002中文版开发显示对话框的常规DLL出现RC2135错误的解决办法
- 关于上位机和下位机的一些解释
- vs 2005 express 版本 关于debug 调试时显示 无法找到msvcr80d.dll的错误 解决方法
- 关于如何使用VS高亮显示无扩展名源码文件的一个小技巧
- vs调试时,变量值以十六进制显示
- 关于如何使用VS高亮显示无扩展名源码文件的一个小技巧
- Windows下VS发送UDP包100个,并接受显示出来
- 关于VS2013 mfc使用Edit control控件显示输出内容问题
- 关于如何使用VS高亮显示无扩展名源码文件的一个小技巧
- 关于发送邮件日志显示450