IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C语言实现J1939长帧组包接口以及模拟DM1数据并生成CANalyst数据文件 -> 正文阅读

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

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 ->该字节的最高位为0
				printf("1");
			else
				printf("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;                  // 控制字节,固定32
    bam[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;                  // 保留,固定ff
    bam[5] = pgn & 0xff;
    bam[6] = (pgn >> 8) & 0xff;
    bam[7] = 00;                    // 三个字节PGN

    printf("\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 1
    INT8U 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));

    // DTC2
    INT8U 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)+DTCn
    INT8U 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++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-05-14 09:47:23  更:2022-05-14 09:47:45 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/10 15:23:15-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码