用AI和古法编程写一个解析DBC文件的软件
-
网络节点:描述当前网络有哪些ECU,以BU_开头 如:BU_: Airbag BMS -
报文定义:CAN帧的ID和长度,以BO_开头,如:BO_ 512 VehicleSpeed: 8 ECU_Engine -
信号定义:定义了该信号(车速,模式等)在CAN帧中位置和位宽长度单位.以SG_开头,如SG_ VehicleSpeed: 0|16@0+ (0.01,0) [0|250] “km/h” ECU_BMS,ECU_ESP -
值表:非连续信号的单位吧(挡位,模式等),以VAL_开头,如VAL_ 512 LightStatus 0 “Off” 1 “On” 2 “Error”; -
注释与属性:报文的发送周期等.
-
使用网页前端开发,这样可以免安装 -
有一个加载按钮从本地加载dbc文件 -
解析dbc文件格式 -
显示当前网络的拓扑结构 -
能够导出CSV文件 -
能导出信号节点的每一帧C语言结构体,ECU开发一般是C语言


function parseDbcContent(content) {dbcData = { nodes: [], messages: [], version: "", bitTiming: null };const lines = content.split('\n');let currentMessage = null;for (let i = 0; i < lines.length; i++) {const line = lines[i].trim();if (!line || line.startsWith('//') || line.startsWith('/*')) continue;if (line.startsWith('VERSION')) {const match = line.match(/VERSION\s+"([^"]*)"/);if (match) dbcData.version = match[1];} else if (line.startsWith('BU_:')) {const nodes = line.substring(4).trim().split(/\s+/);dbcData.nodes = nodes.filter(n => n && n !== 'Vector__XXX');} else if (line.startsWith('BO_')) {if (currentMessage) dbcData.messages.push(currentMessage);const match = line.match(/BO_\s+(\d+)\s+(\w+)\s*:\s*(\d+)\s+(\w+)/);if (match) {currentMessage = {id: parseInt(match[1]),name: match[2],length: parseInt(match[3]),transmitter: match[4],signals: []};} else {currentMessage = null;}} else if (line.startsWith('SG_') && currentMessage) {const match = line.match(/SG_\s+([\w_]+)\s*:\s*(\d+)\|(\d+)@(\d+)([+-])\s*\(([^,]+),([^)]+)\)\s*\[([^|]+)\|([^\]]+)\]\s*"([^"]*)"\s*(.*)/);if (match) {currentMessage.signals.push({name: match[1],startBit: parseInt(match[2]),length: parseInt(match[3]),endianness: parseInt(match[4]),signed: match[5] === '-',factor: parseFloat(match[6]),offset: parseFloat(match[7]),min: parseFloat(match[8]),max: parseFloat(match[9]),unit: match[10],receivers: match[11].trim().split(/\s*,\s*/).filter(r => r && r !== 'Vector__XXX')});}}}if (currentMessage) dbcData.messages.push(currentMessage);dbcData.messages.sort((a, b) => a.id - b.id);if (dbcData.nodes.length === 0) {const nodeSet = new Set();dbcData.messages.forEach(msg => {if (msg.transmitter) nodeSet.add(msg.transmitter);msg.signals.forEach(sig => sig.receivers.forEach(rec => nodeSet.add(rec)));});dbcData.nodes = Array.from(nodeSet);}}




/* ================================================================* 发送节点: BMS_MQB (3 个报文)* ================================================================ *//*** @brief CAN报文: BMS_Hybrid_01* @note 帧ID: 0x65C (1628 DEC)* 发送节点: BMS_MQB* 数据长度: 8 字节* 接收节点: Gateway_MQB*/typedef union{uint8_t raw[8];struct{uint16_t reserved0: 13;uint8_t BMS_HYB_ASV_hinten_Status: 1; /**< 起始位:13, 长度:1 */uint8_t BMS_HYB_ASV_vorne_Status: 1; /**< 起始位:14, 长度:1 */uint8_t BMS_HYB_KD_Fehler: 1; /**< 起始位:15, 长度:1 */uint8_t BMS_HYB_BattFanSpd: 1; /**< 起始位:16, 长度:4 */uint8_t reserved1: 3;uint8_t BMS_HYB_VentilationReq: 1; /**< 起始位:20, 长度:1 */uint8_t BMS_HYB_Kuehlung_Anf: 2; /**< 起始位:22, 长度:2 */uint8_t reserved2: 1;uint8_t BMS_HYB_Temp_vor_Verd: 1; /**< 起始位:24, 长度:8 */uint8_t reserved3: 4;uint8_t BMS_HYB_BattFanSpd: 3; /**< 起始位:16, 长度:4 */uint8_t BMS_HYB_Temp_nach_Verd: 1; /**< 起始位:32, 长度:8 */uint8_t BMS_HYB_Temp_vor_Verd: 7; /**< 起始位:24, 长度:8 */uint8_t BMS_Temperatur: 1; /**< 起始位:40, 长度:8 */uint8_t BMS_HYB_Temp_nach_Verd: 7; /**< 起始位:32, 长度:8 */uint8_t BMS_Temperatur_Ansaugluft: 1; /**< 起始位:48, 长度:8 */uint8_t BMS_Temperatur: 7; /**< 起始位:40, 长度:8 */uint8_t BMS_IstSpannung_HV: 1; /**< 起始位:56, 长度:8 */uint8_t BMS_Temperatur_Ansaugluft: 7; /**< 起始位:48, 长度:8 */} fields;} CAN_BMS_Hybrid_01_t;
夜雨聆风