C语言实现J1939长帧组包接口以及模拟DM1数据并生成CANalyst数据文件

利用Dev-Cpp v5.11,通过C语言实现,经过Code::Blocks编译后,会生成exe文件,可以直接用exe文件执行,完成后会在程序目录生成CANalyst工具适用的文件,具体代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>/****************************************************************DEFINE THE DATATYPE
****************************************************************/
typedef unsigned char  BOOLEAN;
typedef unsigned char  INT8U;                   /* Unsigned  8 bit quantity                           */
typedef signed   char  INT8S;                   /* Signed    8 bit quantity                           */
typedef unsigned short INT16U;                  /* Signed   16 bit quantity                           */
typedef signed   short INT16S;                  /* Unsigned 32 bit quantity                           */
typedef unsigned int   INT32U;                  /* Unsigned 32 bit quantity                           */
typedef unsigned long  long INT64U;             /* Unsigned 64 bit quantity                           */
typedef signed   int   INT32S;                  /* Signed   32 bit quantity                           */
typedef float          FP32;                    /* Single precision floating point                    */
typedef double         FP64;                    /* Double precision floating point                    */
typedef  unsigned long ip_addr;#ifndef  false
#define  false                  0
#endif#ifndef  true
#define  true                   1
#endif#ifndef  TRUE
#define  TRUE                   1
#endif#ifndef   FALSE
#define   FALSE                 0
#endif#define MEMCPY_EX(DET_PTR, DET_LEN, SRC_PTR, SRC_LEN)   \
do {                                                    \assert((DET_LEN) >= (SRC_LEN));     \memcpy(DET_PTR, SRC_PTR, SRC_LEN);                  \
} while(0)INT8U HexToChar(INT8U sbyte)
{sbyte &= 0x0F;if (sbyte < 0x0A) return (sbyte + '0');else return (sbyte - 0x0A + 'A');
}BOOLEAN printf_hex(INT8U *ptr, INT16U len)
{INT16U i = 0;INT8U  ch;INT8U s_debugmem[4096] = {0};if (ptr == 0 || len == 0) {return false;}memset(s_debugmem, 0, sizeof(s_debugmem));for (i = 0; len > 0; len--) {ch = *ptr++;if ((i + 3) > sizeof(s_debugmem)) {break;}s_debugmem[i++] = HexToChar((INT8U)(ch >> 4));s_debugmem[i++] = HexToChar(ch);s_debugmem[i++] = ' ';}printf("%s\n", s_debugmem);return true;
}void printf_bin(int num)
{int i, j, k;unsigned char *p = (unsigned char*)&num + 3;    //p先指向num后面第3个字节的地址,即num的最高位字节地址for (i = 0; i < 4; i++) {                       //依次处理4个字节(32位)j = *(p - i);                               //取每个字节的首地址,从高位字节到低位字节,即p p-1 p-2 p-3地址处for (int k = 7; k >= 0; k--) {              //处理每个字节的8个位,注意字节内部的二进制数是按照人的习惯存储!if (j & (1 << k))                       //1左移k位,与单前的字节内容j进行或运算,如k=7时,00000000&10000000=0 ->该字节的最高位为0printf("1");elseprintf("0");}printf(" ");                                //每8位加个空格,方便查看}printf("(%d)", num);printf("\r\n");
}#define CANalystXMLFile "./dm1_data.xml"
static FILE *s_xml_fd;
static void save_to_CANalyst_xml_file(INT32U can_id, INT8U *can_data, INT32U len)
{if (can_data == NULL) {printf("can data is null\n");return;}if (s_xml_fd) {char xml_buf[2048] = {0}, temp[128] = {0};strcat(xml_buf,"    ");strcat(xml_buf,"<TaskObj Frames=\"1\" Interval=\"20\" Times=\"1\" IdIncrease=\"0\" DataIncrease=\"0\" ");sprintf(temp, "ID=\"%d\" ", can_id);strcat(xml_buf,temp);strcat(xml_buf,"SendType=\"0\" RemoteFlag=\"0\" ExternFlag=\"1\" DataLen=\"8\" ");sprintf(temp, "Data=\"%02x %02x %02x %02x %02x %02x %02x %02x\"/>\n",can_data[0], can_data[1], can_data[2], can_data[3], can_data[4], can_data[5], can_data[6], can_data[7]);strcat(xml_buf,temp);strcat(xml_buf,"\0");fwrite(xml_buf, strlen(xml_buf), 1, s_xml_fd);}
}void gen_dm1_can_data(INT16U pgn, INT8U *data, INT16U len)
{// 广播帧INT32U bam_id = 0x18ECFF00;INT8U  bam[8] = {0};bam[0] = 0x20;                  // 控制字节,固定32bam[1] = len & 0xff;            // 消息字节数,低位在前bam[2] = (len >> 8) & 0xff;     // 消息字节数,高位在后if ((len % 7) == 0) {bam[3] = len / 7;} else {bam[3] = (len / 7) + 1;     // 数据包数}bam[4] = 0xff;                  // 保留,固定ffbam[5] = pgn & 0xff;bam[6] = (pgn >> 8) & 0xff;bam[7] = 00;                    // 三个字节PGNprintf("\n");printf("packet num:%d, len:%d, pgn:%d(%04x)\n\n", bam[3], len, pgn, pgn);printf("TP.CM_BAM  can id:%08x(%u), data:", bam_id, bam_id);printf_hex(bam, sizeof(bam));printf("\n");save_to_CANalyst_xml_file(bam_id, bam, sizeof(bam));// 数据发送帧INT32U dt_id = 0x18EBFF00;INT16U i = 0, packet_num = bam[3];INT8U dt_ptr[packet_num * 8] = {0};for (i = 0; i < packet_num; i++) {dt_ptr[i*8] = i + 1;if (i == packet_num - 1) {INT8U left_len = len-(7*i);memset(&dt_ptr[(i*8)+1], 0xff, 7);memcpy(&dt_ptr[(i*8)+1], &data[i * 7], left_len);} else {memcpy(&dt_ptr[(i*8)+1], &data[i * 7], 7);}}for (i = 0; i < packet_num; i++) {printf("TP.DT_DATA can id:%08x(%d), data:", dt_id, dt_id);printf_hex(&dt_ptr[8*i], 8);save_to_CANalyst_xml_file(dt_id, &dt_ptr[8*i], sizeof(dt_ptr));}printf("\n");// printf_hex(dt_ptr, packet_num * 8);
}void gen_dm1_data(INT8U lamp, INT8U flash, INT32U spn, INT8U fmi, INT8U count, INT8U *des_ptr, INT8U des_len)
{INT8U dtc[4] = {0};if ((des_ptr == NULL) || (des_len < 6)) {printf("des ptr error, len:%d\n", des_len);return;}printf("lamp:%02x, flash:%02x, spn:%d, fmi:%d, count:%d\n", lamp, flash, spn, fmi, count);dtc[0] = spn;dtc[1] = spn >> 8;dtc[2] = fmi & 0x1F;dtc[2] |= ((spn >> 16) & 0x07) << 5;dtc[3] = count;des_ptr[0] = lamp;des_ptr[1] = flash;memcpy(&des_ptr[2], dtc, sizeof(dtc));
}int main(int argc, char const *argv[])
{//    INT8U buf[6] = {0};
//    gen_dm1_data(0x11, 0x22, 983, 1, 2, buf, sizeof(buf));
//    printf_hex(buf, 6);
//    return 0;remove(CANalystXMLFile);s_xml_fd = fopen(CANalystXMLFile, "a+");if (s_xml_fd == NULL) printf("file open error\n");char xml_buf[1024] = {0};// 写xml头sprintf(xml_buf, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE xml>\n<xml version=\"1.0\">\n");fwrite(xml_buf, strlen(xml_buf), 1, s_xml_fd);// DM1长帧数据INT32U pgn, lamp, flash, spn, fmi, count;pgn = 0xfeca;
//    printf("input pgn(十进制):");
//    scanf("%d", &pgn);printf("input lamp(一个字节十六进制):");scanf("%x", &lamp);printf("input flash(一个字节十六进制):");scanf("%x", &flash);// DTC 1INT8U data1[6] = {0};printf("\n\ninput first DTC data\n");printf("input spn(十进制):");scanf("%d", &spn);printf("input fmi(十进制):");scanf("%d", &fmi);printf("input count(十进制):");scanf("%d", &count);gen_dm1_data(lamp, flash, spn, fmi, count, data1, sizeof(data1));// DTC2INT8U data2[6] = {0};printf("\n\ninput second DTC data\n");printf("input spn(十进制):");scanf("%d", &spn);printf("input fmi(十进制):");scanf("%d", &fmi);printf("input count(十进制):");scanf("%d", &count);gen_dm1_data(lamp, flash, spn, fmi, count, data2, sizeof(data2));// 组成长帧数据体,lamp(1)+flash(1)+DTC1(4)+DTC2(4)+DTCnINT8U data[10] = {0};memcpy(data, data1, sizeof(data1));memcpy(&data[6], &data2[2], sizeof(data2)-2);gen_dm1_can_data((INT16U)pgn, data, sizeof(data));// 写xml尾memset(xml_buf, 0, sizeof(xml_buf));sprintf(xml_buf, "</xml>\n");fwrite(xml_buf, strlen(xml_buf), 1, s_xml_fd);if (s_xml_fd)    fclose(s_xml_fd);printf("save CANalyst XML File to %s\n\n", CANalystXMLFile);// system("pause>nul");    // 避免可执行程序双击执行后窗口关闭,不提示按任意键继续system("pause"); // 避免可执行程序双击执行后窗口关闭return 0;
}

C语言实现J1939长帧组包接口以及模拟DM1数据并生成CANalyst数据文件相关推荐

  1. C语言版iso8583报文拆包组包代码

    源码文件在银联和农信的系统中使用,稳定可靠,两个文件加一起约8千行代码,主要有"组报文"和"解报文"两个函数,系统调用这两个函数完成8583报文的打包和拆包. ...

  2. python按比例生成数据组_基于python中的一个值生成“正态分布”数据

    通过施加总和temp=100你介绍的依赖至少两个数据点之间,因此无法建立一套独立的采样随机数据点. 一个简单的例子: 想象一下投币.系统中的随机性正好是一个二进制结果,或1位. 想象一下两个硬币翻转. ...

  3. Qt 实现数据协议控制--组帧、组包、解析帧、解析包

    数据传输中的组帧和组包 一.数据帧,数据包的概念 数据帧 组包 二. 程序实现: 2.1.frame(帧)类的实现: 2.2.Pack(包)类的实现: 三.测试 一.数据帧,数据包的概念 数据帧 数据 ...

  4. R语言将dataframe长表转化为宽表实战:使用reshape函数、使用tidyr包的spread函数、使用data.table

    R语言将dataframe长表转化为宽表实战:使用reshape函数.使用tidyr包的spread函数.使用data.table 目录

  5. java socket发送定长报文_定长消息报文的组包与解包简单封装(Java实现)

    报文 组包 解包 在实际项目中经常会碰到不同系统之间的数据交换,有些是用webservice.有些则是使用发socket消息的方式,将需要发送的消息组装成特定格式的字符串或Xml格式的文件,再通过so ...

  6. C语言字符串的组包解包

    组包解包 sprintf组包 sscanf解包 sscanf的高级用法1:使用%*s %*d 跳过提取的内容(不要提取的内容) sscanf的高级用法2:使用%[n]s %[n]d 提取指定宽度n的字 ...

  7. C语言---sprintf组包、sscanf解包

    目录 一.sprintf组包(了解) (一)案例1:将2022 9 24这三个数据组成一个"2022年9月24日" (二)案例2:将一个人的姓名.年龄.性别.家庭地址组成要求的格式 ...

  8. c语言程序竞赛,2015年江西理工大学C语言程序设计竞赛(初级组)

    JankTao相亲记 解法:排序 #include #include #include #include #include #include #include #include using names ...

  9. R语言可视化学习笔记之ggridges包绘制山峦图

    作者:严涛 浙江大学作物遗传育种在读研究生(生物信息学方向)伪码农,R语言爱好者,爱开源. 严涛老师的绘图教程还有: gganimate |诺奖文章里面的动图绘制教程来了!! ggplot2学习笔记之 ...

  10. 新功能发布—TSMaster如何实现J1939多帧报文收发

    前言 众所周知,J1939协议是由美国汽车工程师协会(SAE)定义的一组标准.J1939标准用于卡车.公共汽车和移动液压等重型车辆.如今大多数车辆都通过CAN进行ECU通信.但是CAN总线仅仅是提供了 ...

最新文章

  1. 谷歌地图API位置请求_Google Maps API
  2. JVM内存区域划分总结
  3. Mac下安装多版本python
  4. jquery JSON的解析方式
  5. linux rcu机制,Linux RCU机制详解 (透彻)
  6. javascript 作用_JavaScript承诺如何从内到外真正发挥作用
  7. php生成appid,PHP生成腾讯云COS签名
  8. ajax 数据data,ajax取出data数据库
  9. mysql 5.1.6 安装包_Centos6 离线安装 MySQL5.5.55-1(附带安装包及 Perl 依赖包)
  10. miui锁屏通知显示android,MIUI10系统又更新了!新增勿扰锁屏通知功能,修复系统Bug...
  11. ubuntu中使用.rpm
  12. 拓端tecdat|R语言神经网络模型预测车辆数量时间序列
  13. otsu阈值分割算法原理_Otsu算法
  14. matlab fvtool 滤波器频响
  15. 怎么修改ftp服务器被动端口,ftp服务器改为被动模式
  16. iReport使用入门
  17. LeetCode 661. Image Smoother
  18. 给文档添加签名,介绍用iPhone的实例,安卓手机类似
  19. 以下python语言关键字在异常处理_python后端开发工程师考证试题
  20. dat图片 电脑端微信_微信电脑图片dat转为jpg

热门文章

  1. cad插件苹果系统_CAD看图软件mac版|CAD迷你看图 for Mac下载 v4.0.0 官方版_最火软件站...
  2. SHA1算法 c语言(参考其他修改)
  3. python 离线安装numpy_Python本地安装numpy包
  4. GitHub上10个有趣的开源小游戏(附加在线演示)
  5. eclipse安装包
  6. 模糊pid控制算法matlab程序解读,基于Matlab的模糊PID控制研究
  7. Matlab 常用命令 大全
  8. 【原创】我的辞职申请(2005-10-27)
  9. 52个外文文献论文网站,写论文的你必囤!
  10. java俄罗斯方块简单代码_Java简易俄罗斯方块