利用Dev-Cpp v5.11,通过C语言实现,经过Code::Blocks编译后,会生成exe文件,可以直接用exe文件执行,完成后会在程序目录生成CANalyst工具适用的文件,具体代码如下:
#include#include #include typedef unsigned char BOOLEAN; typedef unsigned char INT8U; typedef signed char INT8S; typedef unsigned short INT16U; typedef signed short INT16S; typedef unsigned int INT32U; typedef unsigned long long INT64U; typedef signed int INT32S; typedef float FP32; typedef double FP64; 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("%sn", 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("rn"); } #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 nulln"); return; } if (s_xml_fd) { char xml_buf[2048] = {0}, temp[128] = {0}; strcat(xml_buf," "); strcat(xml_buf," 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," "); 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)nn", 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:%dn", des_len); return; } printf("lamp:%02x, flash:%02x, spn:%d, fmi:%d, count:%dn", 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 errorn"); char xml_buf[1024] = {0}; // 写xml头 sprintf(xml_buf, "nn 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("nninput first DTC datan"); 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("nninput second DTC datan"); 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, " 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 %snn", CANalystXMLFile); // system("pause>nul"); // 避免可执行程序双击执行后窗口关闭,不提示按任意键继续 system("pause"); // 避免可执行程序双击执行后窗口关闭 return 0; }



