user-0 提问: 关于Modbus ASCII通讯要发送的字符串中LRC校验字节的处理

回复:
user: user-0
content: 没找到答案，先结贴吧，这个问题看来没人感兴趣。自己去研究了，谢谢赵老师。

user: user-1
content: 楼主应该先忘掉字符串，脑中只认识字节和长度（字节数）。

user: user-1
content: Modbus ASCII  sendbuf[1024]=":0103040a47\xed\r\n"  我猜。

user: user-0
content: 嗯，谢谢赵老师。 我现在想重新问我的问题，就是，Modbus ASCII 和Modbus RTU要发送的字符串是什么样子的。 比如： LRC算出来的是16进制的字节值，若发送的数据是字符串形式，不需任何转换，直接放在字符串最后位置就行了。若发送的数据是数组形式，则需要转换为ASCII值，即由1字节的16进制转换为2字节的ASCII值，4D应该转换为34 44。 是这样的吗？ 又比如： Modbus ASCII  sendbuf[1024]=":0103040a470D0A"  ，这个字符串数组对吗，能直接这样发吗？  有哪位高手能给个详细的程序及说明。

user: user-1
content: 开始、运行、cmd、确定：下面<>括住表示相应按键 chcp 437<Enter> :0103040a<按住Alt键不放，依次按数字小键盘上的<2><3><7>，松开Alt键>

user: user-0
content: 有没有高手帮忙指点下啊？

user: user-0
content: 看不懂啊，赵老师。

user: user-0
content: 嗯，最关键的地方在于： lrc 是BYTE类型，而BYTE类型实际上就是unsigned char类型， 而temp[0]是char类型，做下面这个赋值有没有问题： temp[0]=(char)lrc ;

user: user-1
content: 你的冒号：似应改为半角冒号: 想将237显示为正常的字符，在cmd窗口中输入命令chcp 437

user: user-1
content: void HexDump(char *buf,int len,int addr) {     int i,j,k;     char binstr[80];      for (i=0;i<len;i++) {         if (0==(i%16)) {             sprintf(binstr,"%08x -",i+addr);             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         } else if (15==(i%16)) {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);             sprintf(binstr,"%s  ",binstr);             for (j=i-15;j<=i;j++) {                 sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');             }             printf("%s\n",binstr);         } else {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         }     }     if (0!=(i%16)) {         k=16-(i%16);         for (j=0;j<k;j++) {             sprintf(binstr,"%s   ",binstr);         }         sprintf(binstr,"%s  ",binstr);         k=16-k;         for (j=i-k;j<i;j++) {             sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');         }         printf("%s\n",binstr);     } }

user: user-0
content: 调试结果如下图：

user: user-0
content: 求高手帮忙！

user: user-1
content: 引用 12 楼 xiaobicai 的回复:赵老师，你这个程序没注释，看不懂，对我的问题有什么联系吗？ 你可以把其中的HexDump函数搬到你代码中，随时查看某个字符串在内存中的字节值。  电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……

user: user-0
content: 赵老师，你这个程序没注释，看不懂，对我的问题有什么联系吗？

user: user-1
content: 引用 9 楼 xiaobicai 的回复:赵老师，你发的那个HexDump函数是干什么用的，是将一个字符串转换成16进制的吗，其中第三个参数addr是做什么的？ addr是你想显示的基地址。 例如：#include <stdio.h> #include <string.h> FILE *f; char buffer[4096]; int r,a; void HexDump(char *buf,int len,int addr) {     int i,j,k;     char binstr[80];      for (i=0;i<len;i++) {         if (0==(i%16)) {             sprintf(binstr,"%08x -",i+addr);             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         } else if (15==(i%16)) {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);             sprintf(binstr,"%s  ",binstr);             for (j=i-15;j<=i;j++) {                 sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');             }             printf("%s\n",binstr);         } else {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         }     }     if (0!=(i%16)) {         k=16-(i%16);         for (j=0;j<k;j++) {             sprintf(binstr,"%s   ",binstr);         }         sprintf(binstr,"%s  ",binstr);         k=16-k;         for (j=i-k;j<i;j++) {             sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');         }         printf("%s\n",binstr);     } } int main(int argc,char **argv) {     if (argc<2) {         fprintf(stderr,"Usage: %s filename.ext\n",argv[0]);         return 2;     }     f=fopen(argv[1],"rb");     if (NULL==f) {         fprintf(stderr,"Can not open file [%s]!\n",argv[1]);         return 1;     }     a=0;     while (1) {         r=fread(buffer,1,4096,f);         HexDump(buffer,r,a);         a+=r;         if (r<4096) break;     }     fclose(f);     return 0; }

user: user-0
content: 有没有对Modbus通讯程序比较熟悉的高手啊。 我这样转换对吗？ 我在百度知道里面找到下面这段说明，有更详细的程序及说明吗？  LRC算出来的是16进制的字节值，若发送的数据是字符串形式，不需任何转换，直接放在字符串最后位置就行了。若发送的数据是数组形式，则需要转换为ASCII值，即由1字节的16进制转换为2字节的ASCII值，4D应该转换为34 44。

user: user-0
content: 赵老师，你发的那个HexDump函数是干什么用的，是将一个字符串转换成16进制的吗，其中第三个参数addr是做什么的？