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

news/2025/1/15 18:00:47/

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;
}

http://www.ppmy.cn/news/397674.html

相关文章

达梦数据库集群部署(已实现)

准备两台ip 主库ip 192.168.1.127 从库ip 192.168.1.122 1、关闭数据库后&#xff0c;使用dmrman工具(主库ip 192.168.1.127) backup database /opt/dmdbms/data/DM1/dm.ini backupset /opt/dmdbms/data/dmbak;主库(ip 192.168.1.127)成功运行后的截图 2、先在备份库(192.1…

DM-RS 概述

DMRS&#xff08;demodulation reference signal&#xff09;解调参考信号&#xff0c;用于接收端&#xff08;基站侧或者UE侧&#xff09;进行信道估计&#xff0c;来用于物理信道的解调 在LTE与解调相关的参考信号&#xff1a; 上行方向&#xff1a; 1.对pusch/pucch,基站…

linux dm-0 dm-1 设备映射 简介

在linux系统中你使用一些命令时&#xff08;例如nmon、iostat 如下截图所示&#xff09;&#xff0c;有可能会看到一些名字为dm-xx的设备&#xff0c;那么这些设备到底是什么设备呢&#xff0c;跟磁盘有什么关系呢&#xff1f;以前不了解的时候&#xff0c;我也很纳闷. 其实dm是…

DMA简介

为什么要有 DMA 技术? dma主要是用于读写数据用的 在没有 DMA 技术前&#xff0c;I/O 的过程是这样的&#xff1a; CPU 发出对应的指令给磁盘控制器&#xff0c;然后返回&#xff1b;磁盘控制器收到指令后&#xff0c;于是就开始准备数据&#xff0c;会把数据放入到磁盘控制…

【磁盘】Linux dm-0 dm-1 dm-2 设备映射

在Linux系统中你使用一些命令时&#xff08;如nmon、iostat &#xff09;&#xff0c;有可能会看到一些名字为dm-xx的设备&#xff0c;那么这些设备到底是什么设备呢&#xff0c;跟磁盘有什么关系呢&#xff1f; 其实dm是Device Mapper的缩写&#xff0c;Device Mapper 是 Lin…

DM问题总结(1)

一、DM大小写敏感问题 如下两套DM数据库&#xff0c;分别为大小写敏感与非敏感。 当CASE_SENSITIVE为1大小写敏感时&#xff0c;会将A,a区分开来&#xff0c;仅查询a&#xff0c;当CASE_SENSITIVE为0大小写不敏感时&#xff0c;A,a会被DM认为是相同的字符。 同时&#xff0c…

Cos 文件上传下载

目录 方法一&#xff1a; maven依赖&#xff1a; UploadServlet upload.jsp 方法二&#xff1a; maven依赖 UploadServlet upload.jsp success.jsp error.jsp 运行结果&#xff1a; 百度文件上传插件&#xff1a; Web Uploader 本文通过JSPServlet的架构&#xff0c…

DM建模实例2

DM建模 DM实例2 DM建模 1 草图绘制2 特征操作3 布尔操作4 总结 1 草图绘制 1.启动 WB&#xff0c;在项目窗口中拖入 Geometry 工作卡片&#xff0c;鼠标右键单击 Edit in DM &#xff0c;进入 DM 工作界面&#xff0c;在 Units 下设置单位为mm。 2.选择xy平面为草图绘制基准面…