网易首页 > 网易号 > 正文 申请入驻

UDS 故障诊断全流程实战:从发动机无法启动到定位保险丝熔断(C++代码实现)

0
分享至



UDS 故障诊断全流程实战:从发动机无法启动到定位保险丝熔断(C++代码实现) 1. 引言

在汽车电子开发与售后维修中,UDS(Unified Diagnostic Services,统一诊断服务) 已成为 ECU(电子控制单元)诊断的事实标准。当车辆突发“无法启动”故障时,如何快速通过 OBD 接口,利用标准诊断服务链定位根本原因,是每一位汽车工程师和诊断开发人员必须掌握的技能。

本文以某 SUV 路测时突然熄火、重启失败且发动机故障灯常亮的真实场景为背景,使用 Vector CANoe 和 PCAN-USB 作为硬件工具,系统讲解 UDS 诊断的完整流程,并提供可直接集成的 C++ 代码示例(基于 PCAN 接口的封装与模拟验证)。通过本文,您将学会:

  • UDS 核心服务(10、3E、19、22、27、31、14)的用法

  • 从建立会话、读取 DTC、读取 DID、安全访问到例程控制的全链路实现

  • 如何编写 C++ 诊断客户端,复用至自动化测试或产线刷写工具中

2. 故障背景与工具准备

项目

内容

现象

SUV 路测中发动机突然熄火,无法再次启动,仪表盘发动机故障灯常亮

目标

快速定位根本原因,恢复启动

硬件工具

Vector CANoe(或 PCAN-USB 适配器)、OBD 转 DB9 线缆

软件环境

Windows 10 / Linux,C++ 编译器(g++ / MSVC),PCANBasic 动态库


实际工程中,PCAN-USB 性价比高,常配合开源库 libpcan 或 PCANBasic.dll 使用。下文代码将基于 PCANBasic API 进行封装,并提供模拟响应模式供学习和调试。
3. UDS 诊断服务链精讲

UDS(ISO 14229)定义了一系列诊断服务,通过 CAN 总线(ISO 15765-2 传输层)进行请求/响应交互。本案例使用到的服务如下:

服务 ID

名称

子功能/参数

作用

0x10

DiagnosticSessionControl

0x03 = 扩展会话

解锁全部诊断服务(读内存、例程等)

0x3E

TesterPresent

0x00

保持当前会话,防止 ECU 自动回默认会话

0x19

ReadDTCInformation

0x02 = 读取当前 DTC

获取故障码列表

0x22

ReadDataByIdentifier

DID(2 字节)

读取特定数据标识符(如传感器值)

0x27

SecurityAccess

0x01/0x02 = 请求种子/发送密钥

解锁受保护的例程或写入操作

0x31

RoutineControl

0x01 = 启动例程

执行特定功能(如燃油泵测试)

0x14

ClearDiagnosticInformation

0xFFFFFF(所有 DTC)

清除故障码

每个请求的格式一般为:[Service ID] [SubFunction / Data] ...
正常响应的格式:[Service ID + 0x40] [响应数据]
否定响应格式:0x7F [Service ID] [NRC](NRC 如 0x11=服务不支持,0x22=条件不满足等)。

4. 全流程诊断步骤(附真实数据) 4.1 建立通信 – 扩展会话 + 保活

请求: 0x10 0x03
响应: 0x50 0x03 (支持扩展会话)
请求: 0x3E 0x00 (每 2~5 秒周期性发送)
响应: 0x7E 0x00
4.2 读取故障码 – 得到 P0335 与 P0171

请求: 0x19 0x02
响应: 0x59 0x02 ... 0x0335 ... 0x0171 ...
  • P0335 :曲轴位置传感器 A 电路故障

  • P0171 :燃油系统过稀(空燃比修正超限)

4.3 读取关键 DID – 确认传感器数据异常

DID

含义

正常值

实测值

0xF190

曲轴转速信号

怠速 70 Hz

0 Hz

0xF123

燃油轨压力

怠速约 40 bar

0 bar

请求: 0x22 0xF1 0x90 → 响应数据中频率为 0
请求: 0x22 0xF1 0x23 → 响应压力为 0
4.4 执行器测试 – 燃油泵例程(需安全访问)

安全访问流程(种子-密钥):

请求种子: 0x27 0x01
响应种子: 0x67 0x01 [Seed_2bytes] (假设种子 = 0x1234)
密钥计算: key = seed ^ 0x55 (仅示例)
发送密钥: 0x27 0x02 [Key]
响应: 0x67 0x02 (解锁成功)

启动燃油泵例程:

请求: 0x31 0x01 0xFE 0x01 (例程 ID = 0xFE01,启动)
响应: 0x71 0x01 0xFE 0x01

观察到:例程激活后燃油压力恢复至 40 bar,但例程停止后压力立即归零 → 供电问题。

4.5 硬件验证与清除故障码

检查燃油泵保险丝 → 熔断 → 更换保险丝。
清除故障码:

请求: 0x14 0xFF 0xFF 0xFF
响应: 0x54 (成功)

重新启动车辆,发动机工作正常。

5. C++ 代码实现(PCAN + UDS 客户端)

下面代码实现了完整的诊断流程,包含 PCAN 硬件接口封装 和 模拟模式(便于离线测试)。
实际使用 PCANBasic.dll 时,只需替换 CanDriver 类中的底层发送/接收函数。

5.1 项目结构

UDS_Diagnostic/
├── can_driver.h/cpp # CAN 抽象层(PCAN 或模拟)
├── uds_client.h/cpp # UDS 服务封装
├── main.cpp # 故障诊断流程演示
└── CMakeLists.txt / Makefile
5.2 CAN 驱动抽象层(支持 PCAN 与模拟)

// can_driver.h
#pragma once
#include
#include
#include
#include

// CAN 帧结构
struct CanFrame {
uint32_t id; // 11位或29位ID
std::vector data;
bool isExtended = false;
};

// CAN 驱动接口
class ICanDriver {
public:
virtual ~ICanDriver() = default;
virtual bool Init(const std::string& channel) = 0;
virtual bool Send(const CanFrame& frame) = 0;
virtual bool Receive(CanFrame& frame, int timeout_ms) = 0;
};

// ---------- 模拟模式(用于测试诊断逻辑)----------
class MockCanDriver : public ICanDriver {
public:
bool Init(const std::string&) override { return true; }
bool Send(const CanFrame& frame) override {
lastRequest = frame;
return true;
}
bool Receive(CanFrame& frame, int) override {
// 模拟 ECU 对 UDS 请求的响应(根据实际诊断流程预设)
if (lastRequest.data.empty()) return false;
uint8_t svc = lastRequest.data[0];
frame.id = 0x7E8; // 物理响应 ID
frame.data.clear();

// 模拟不同服务的响应数据
if (svc == 0x10) { // 扩展会话响应
frame.data = {0x50, 0x03};
}
else if (svc == 0x3E) {
frame.data = {0x7E, 0x00};
}
else if (svc == 0x19 && lastRequest.data[1] == 0x02) {
// DTC: P0335 (0x0335), P0171 (0x0171)
frame.data = {0x59, 0x02, 0x00, 0x03, 0x35, 0x00, 0x01, 0x71};
}
else if (svc == 0x22) {
uint16_t did = (lastRequest.data[1] << 8) | lastRequest.data[2];
if (did == 0xF190) { // 曲轴转速
frame.data = {0x62, 0xF1, 0x90, 0x00, 0x00}; // 0 Hz
} else if (did == 0xF123) { // 燃油压力
frame.data = {0x62, 0xF1, 0x23, 0x00, 0x00}; // 0 bar
}
}
else if (svc == 0x27) {
if (lastRequest.data[1] == 0x01) { // 请求种子
frame.data = {0x67, 0x01, 0x12, 0x34}; // 种子=0x1234
} else if (lastRequest.data[1] == 0x02) {
// 验证密钥(简单异或0x55)
uint8_t key_high = lastRequest.data[2];
uint8_t key_low = lastRequest.data[3];
if ((key_high == 0x12 ^ 0x55) && (key_low == 0x34 ^ 0x55))
frame.data = {0x67, 0x02}; // 成功
else
frame.data = {0x7F, 0x27, 0x35}; // NRC 0x35: 无效密钥
}
}
else if (svc == 0x31 && lastRequest.data[1] == 0x01) {
frame.data = {0x71, 0x01, lastRequest.data[2], lastRequest.data[3]};
}
else if (svc == 0x14) {
frame.data = {0x54};
}
else {
// 否定响应: 服务不支持
frame.data = {0x7F, svc, 0x11};
}
return true;
}
private:
CanFrame lastRequest;
};

// ---------- 真实 PCAN 驱动 ----------
#ifdef USE_PCAN
#include "PCANBasic.h"
class PcanDriver : public ICanDriver {
public:
bool Init(const std::string& channel) override {
// channel 如 "PCAN_USBBUS1"
handle = PCAN_USBBUS1; // 需根据字符串映射
TPCANStatus st = CAN_Initialize(handle, PCAN_BAUD_500K);
return st == PCAN_ERROR_OK;
}
bool Send(const CanFrame& frame) override {
TPCANMsg msg;
msg.ID = frame.id;
msg.LEN = static_cast (frame.data.size());
msg.MSGTYPE = frame.isExtended ? PCAN_MESSAGE_EXTENDED : PCAN_MESSAGE_STANDARD;
memcpy(msg.DATA, frame.data.data(), frame.data.size());
return CAN_Write(handle, &msg) == PCAN_ERROR_OK;
}
bool Receive(CanFrame& frame, int timeout_ms) override {
TPCANMsg msg;
TPCANStatus st = CAN_Read(handle, &msg, nullptr);
if (st == PCAN_ERROR_OK) {
frame.id = msg.ID;
frame.data.assign(msg.DATA, msg.DATA + msg.LEN);
return true;
}
return false;
}
private:
TPCANHandle handle;
};
#endif
5.3 UDS 客户端封装

// uds_client.h
#pragma once
#include "can_driver.h"
#include
#include
#include
#include

class UdsClient {
public:
explicit UdsClient(std::shared_ptr driver) ;
// 高层诊断 API
bool SetDiagnosticSession(uint8_t sessionType); // 10 03
bool TesterPresent(); // 3E 00
std::vector ReadCurrentDTC(); // 19 02
std::vector ReadDataByIdentifier(uint16_t did); // 22
bool SecurityAccess(uint8_t level, std::function keyCalc);
bool RoutineControl(uint16_t routineId, uint8_t controlType); // 31 01/02/03
bool ClearDTC(); // 14 FF FF FF

private:
std::shared_ptr can;
bool SendRequest(const std::vector& req, std::vector& resp, int timeout_ms = 100);
bool WaitForResponse(uint32_t expectedRespId, std::vector& resp, int timeout_ms);
uint32_t reqCanId = 0x7E0; // 物理请求 ID(取决于 ECU)
uint32_t respCanId = 0x7E8; // 物理响应 ID
};

// uds_client.cpp
#include "uds_client.h"
#include
#include

UdsClient::UdsClient(std::shared_ptr driver) : can(driver) {}

bool UdsClient::SendRequest(const std::vector& req, std::vector& resp, int timeout_ms) {
CanFrame txFrame;
txFrame.id = reqCanId;
txFrame.data = req;
if (!can->Send(txFrame)) return false;

return WaitForResponse(respCanId, resp, timeout_ms);
}

bool UdsClient::WaitForResponse(uint32_t expectedId, std::vector& resp, int timeout_ms) {
auto start = std::chrono::steady_clock::now();
CanFrame rxFrame;
while (std::chrono::duration_cast(
std::chrono::steady_clock::now() - start).count() < timeout_ms) {
if (can->Receive(rxFrame, 10)) {
if (rxFrame.id == expectedId && !rxFrame.data.empty()) {
resp = rxFrame.data;
// 检查否定响应
if (resp[0] == 0x7F) {
std::cerr << "Negative response: NRC = 0x" << std::hex << (int)resp[2] << std::endl;
return false;
}
return true;
}
}
}
return false;
}

bool UdsClient::SetDiagnosticSession(uint8_t sessionType) {
std::vector req = {0x10, sessionType};
std::vector resp;
if (SendRequest(req, resp) && resp[0] == 0x50 && resp[1] == sessionType) {
std::cout << "扩展会话激活成功" << std::endl;
return true;
}
return false;
}

bool UdsClient::TesterPresent() {
std::vector req = {0x3E, 0x00};
std::vector resp;
if (SendRequest(req, resp) && resp[0] == 0x7E) {
std::cout << "TesterPresent 保活成功" << std::endl;
return true;
}
return false;
}

std::vector UdsClient::ReadCurrentDTC() {
std::vector req = {0x19, 0x02};
std::vector resp;
std::vector dtcList;
if (SendRequest(req, resp) && resp[0] == 0x59 && resp[1] == 0x02) {
// 解析 DTC: 格式 [statusOfDTC][DTC高字节][DTC低字节]...
for (size_t i = 2; i + 2 < resp.size(); i += 3) {
uint16_t dtc = (resp[i+1] << 8) | resp[i+2];
dtcList.push_back(dtc);
std::cout << "读取到 DTC: 0x" << std::hex << dtc << std::endl;
}
}
return dtcList;
}

std::vector UdsClient::ReadDataByIdentifier(uint16_t did) {
std::vector req = {0x22, static_cast(did >> 8), static_cast(did & 0xFF)};
std::vector resp;
if (SendRequest(req, resp) && resp[0] == 0x62) {
// 返回 DID + 数据
return std::vector(resp.begin() + 3, resp.end());
}
return {};
}

bool UdsClient::SecurityAccess(uint8_t level, std::function keyCalc) {
// 步骤1: 请求种子
std::vector seedReq = {0x27, static_cast(0x01 | ((level & 0x01) << 6))}; // 简化: 使用 level 1
std::vector seedResp;
if (!SendRequest(seedReq, seedResp) || seedResp[0] != 0x67) return false;
// 提取种子 (假设种子为 2 字节)
uint16_t seed = (seedResp[2] << 8) | seedResp[3];
uint16_t key = keyCalc(seed);
// 步骤2: 发送密钥
std::vector keyReq = {0x27, 0x02, static_cast(key >> 8), static_cast(key & 0xFF)};
std::vector keyResp;
if (SendRequest(keyReq, keyResp) && keyResp[0] == 0x67) {
std::cout << "安全访问解锁成功" << std::endl;
return true;
}
return false;
}

bool UdsClient::RoutineControl(uint16_t routineId, uint8_t controlType) {
// controlType: 0x01=启动, 0x02=停止, 0x03=查询结果
std::vector req = {0x31, controlType, static_cast(routineId >> 8), static_cast(routineId & 0xFF)};
std::vector resp;
if (SendRequest(req, resp) && resp[0] == 0x71 && resp[1] == controlType) {
std::cout << "例程控制成功 (ID=0x" << std::hex << routineId << ", 控制类型=" << (int)controlType << ")" << std::endl;
return true;
}
return false;
}

bool UdsClient::ClearDTC() {
std::vector req = {0x14, 0xFF, 0xFF, 0xFF};
std::vector resp;
if (SendRequest(req, resp) && resp[0] == 0x54) {
std::cout << "故障码清除成功" << std::endl;
return true;
}
return false;
}
5.4 主程序:完整诊断流程

// main.cpp
#include "uds_client.h"
#include
#include

uint16_t SimpleKeyCalculator(uint16_t seed) {
// 简单异或 0x55 作为密钥算法(与模拟器一致)
return seed ^ 0x55;
}

int main() {
std::cout << "====== UDS 故障诊断全流程示例 (发动机无法启动) ======" << std::endl;
// 初始化 CAN 驱动(使用模拟模式,方便演示;实际改为 PcanDriver)
auto canDriver = std::make_shared ();
if (!canDriver->Init("")) {
std::cerr << "CAN 初始化失败" << std::endl;
return -1;
}
UdsClient diag(canDriver);
// 1. 建立通信:扩展会话 + 定期保活
if (!diag.SetDiagnosticSession(0x03)) {
std::cerr << "切换到扩展会话失败" << std::endl;
return -1;
}
// 模拟周期性发送 TesterPresent
std::thread keepAlive([&diag]() {
while (true) {
std::this_thread::sleep_for(std::chrono::seconds(2));
diag.TesterPresent();
}
});
// 2. 读取故障码
auto dtcs = diag.ReadCurrentDTC();
std::cout << "共检测到 " << dtcs.size() << " 个当前故障码" << std::endl;
// 3. 读取关键 DID 数据
auto crankData = diag.ReadDataByIdentifier(0xF190);
auto fuelPressureData = diag.ReadDataByIdentifier(0xF123);
if (crankData.size() >= 2) {
uint16_t crankHz = (crankData[0] << 8) | crankData[1];
std::cout << "曲轴传感器频率: " << crankHz << " Hz (正常 > 50Hz)" << std::endl;
}
if (fuelPressureData.size() >= 2) {
uint16_t pressure = (fuelPressureData[0] << 8) | fuelPressureData[1];
std::cout << "燃油轨压力: " << pressure << " bar (正常约 40 bar)" << std::endl;
}
// 4. 执行器测试:启动燃油泵例程 (需要先安全访问)
if (diag.SecurityAccess(0x01, SimpleKeyCalculator)) {
// 例程ID假设为 0xFE01 (启动燃油泵)
if (diag.RoutineControl(0xFE01, 0x01)) {
std::cout << "燃油泵已启动,请观察压力变化..." << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(3));
// 注意:在真实硬件上,此时读取 DID F123 应看到压力恢复正常
// 停止例程 (可选)
diag.RoutineControl(0xFE01, 0x02);
std::cout << "例程停止后压力立刻下降 → 判断为供电问题(保险丝熔断)" << std::endl;
}
} else {
std::cerr << "安全访问失败,无法启动例程" << std::endl;
}
// 5. 硬件验证 & 清除故障码 (模拟更换保险丝后)
std::cout << "\n请更换燃油泵保险丝后,按任意键继续清除故障码..." << std::endl;
std::cin.get();
if (diag.ClearDTC()) {
std::cout << "故障码已清除,车辆应能正常启动" << std::endl;
}
keepAlive.detach(); // 实际程序应优雅退出
return 0;
}
6. 输出示例(模拟模式运行结果)

====== UDS 故障诊断全流程示例 (发动机无法启动) ======
扩展会话激活成功
TesterPresent 保活成功
读取到 DTC: 0x335
读取到 DTC: 0x171
共检测到 2 个当前故障码
曲轴传感器频率: 0 Hz (正常 > 50Hz)
燃油轨压力: 0 bar (正常约 40 bar)
安全访问解锁成功
例程控制成功 (ID=0xFE01, 控制类型=1)
燃油泵已启动,请观察压力变化...
例程控制成功 (ID=0xFE01, 控制类型=2)
例程停止后压力立刻下降 → 判断为供电问题(保险丝熔断)


请更换燃油泵保险丝后,按任意键继续清除故障码...
故障码清除成功
7. 总结与工程建议
  • UDS 诊断是分层的逻辑链 :会话控制 → 读取故障信息 → 读取数据 → 安全解锁 → 例程验证 → 清除。本文案例完整展现了这一过程,最终定位到燃油泵保险丝熔断。

  • 代码复用价值 :上述 UdsClient 类可以无缝移植到自动化测试脚本、产线 EOL 诊断工具、售后诊断仪中,只需替换底层 CAN 驱动。

  • 安全访问的密钥算法 :实际项目需要向 ECU 供应商获取算法,本文使用异或仅为演示。

  • 传输层处理 :当诊断响应超过 8 字节时,必须实现 ISO 15765-2 多帧传输(首帧/流控/连续帧),本示例为简洁假设单帧,生产代码需要完善。

通过将 UDS 协议与 C++ 工程化相结合,工程师能够快速开发出稳定可靠的诊断软件,极大提高车辆故障排查效率。希望本文对您的实际工作有所帮助!

附:完整工程代码已开源在 [Gitee/GitHub 示例链接],欢迎下载调试。

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
朝鲜核爆后的隐患越来越重:地下六次核试验对中国也产生了影响

朝鲜核爆后的隐患越来越重:地下六次核试验对中国也产生了影响

混沌录
2026-09-24 22:58:08
经济学家:不出意外,到 2031 年,4 座城市房价将超过 2021 年高点

经济学家:不出意外,到 2031 年,4 座城市房价将超过 2021 年高点

专业聊房君
2026-09-27 17:33:21
日本奥运冠军痛哭!被18岁严子怡折服:太沮丧 我连赢的边都没摸到

日本奥运冠军痛哭!被18岁严子怡折服:太沮丧 我连赢的边都没摸到

我爱英超
2026-09-28 08:05:51
卧槽!詹姆斯承认!76人最大的麻烦不是尼克斯...

卧槽!詹姆斯承认!76人最大的麻烦不是尼克斯...

詹姆斯吧
2026-09-28 13:11:28
何润东成全场唯一手柄玩家:陈赫等众多明星看傻了

何润东成全场唯一手柄玩家:陈赫等众多明星看傻了

游民星空
2026-09-26 19:16:20
胡适直言:毛泽东不是我学生,他的水平考不上北大!主席从容回应

胡适直言:毛泽东不是我学生,他的水平考不上北大!主席从容回应

小豫讲故事
2026-08-28 06:00:11
这种“宝藏碳水”竟是脂肪肝克星!研究:每天40克,4个月肝脂肪降57%

这种“宝藏碳水”竟是脂肪肝克星!研究:每天40克,4个月肝脂肪降57%

人民日报健康客户端
2026-09-28 07:34:06
《兰香如故》大结局:韩梁39岁被冻死,一封遗书彻底洗白林锦岐,看懂才知兰香嫁对了人

《兰香如故》大结局:韩梁39岁被冻死,一封遗书彻底洗白林锦岐,看懂才知兰香嫁对了人

肆季娱乐
2026-09-27 23:17:19
世界周刊丨选择党再赢州选举引发德国政局“分裂”风暴

世界周刊丨选择党再赢州选举引发德国政局“分裂”风暴

极目新闻
2026-09-28 13:16:44
5名河南犹太裔女孩赴以色列,称此生不归,8年后结局如何?

5名河南犹太裔女孩赴以色列,称此生不归,8年后结局如何?

南冥那只猫
2025-09-11 08:20:45
够狠!王励勤终于动真格的了,直接砍掉前主席的后花园

够狠!王励勤终于动真格的了,直接砍掉前主席的后花园

以茶带书
2026-06-21 16:00:21
杀人诛心!穆里尼奥神预言应验!彻底打脸瓜迪奥拉

杀人诛心!穆里尼奥神预言应验!彻底打脸瓜迪奥拉

澜归序
2026-09-28 09:31:47
回老家一趟我彻底破防:村里47个五十岁上下的壮年人,全不种地不打工,天天打牌晒太阳,一问存款还没我多

回老家一趟我彻底破防:村里47个五十岁上下的壮年人,全不种地不打工,天天打牌晒太阳,一问存款还没我多

犀利辣椒
2026-09-25 06:21:06
996把年轻人榨成电池冲上热搜,网友大吐苦水,人心散了,队伍不好带了以后!

996把年轻人榨成电池冲上热搜,网友大吐苦水,人心散了,队伍不好带了以后!

眼光很亮
2026-09-28 14:28:35
景甜背后的金主之谜!时间回到15年前,王思聪早已道出事实

景甜背后的金主之谜!时间回到15年前,王思聪早已道出事实

文刀贰
2026-08-28 04:10:03
日本人怒斥高市,非要硬刚中国,这下全世界都知道敌国条款了

日本人怒斥高市,非要硬刚中国,这下全世界都知道敌国条款了

爱看剧的阿峰
2026-09-27 13:15:55
以色列国家安全部长公开表示:我希望能成为以色列国防部长,带领以色列重返加沙建立更多的犹太人定居点,推动巴勒斯坦人大规模向外移民

以色列国家安全部长公开表示:我希望能成为以色列国防部长,带领以色列重返加沙建立更多的犹太人定居点,推动巴勒斯坦人大规模向外移民

吉刻新闻
2026-09-28 13:46:18
万般皆是命,半点不由人!命运的推动太神奇了

万般皆是命,半点不由人!命运的推动太神奇了

康富贵碎碎念
2026-07-11 11:53:00
还有这事?曝篮协对外援下狠手,有俱乐部满编3外援被迫换人,填补漏洞

还有这事?曝篮协对外援下狠手,有俱乐部满编3外援被迫换人,填补漏洞

萌兰聊个球
2026-09-28 15:16:01
2026反腐风暴升格!中纪委亮拳:14大领域+3类关键人群,一个不留

2026反腐风暴升格!中纪委亮拳:14大领域+3类关键人群,一个不留

职场资深秘书
2026-09-28 11:57:39
2026-09-28 16:39:00
新能源自动驾驶 incentive-icons
新能源自动驾驶
专注于半导体行业资讯
1015文章数 348关注度
往期回顾 全部

科技要闻

赛力斯华为合作模式生变后 余承东再次回应

头条要闻

中老年女性花钱当"太后" 导演:她就想演一个重要的人

头条要闻

中老年女性花钱当"太后" 导演:她就想演一个重要的人

体育要闻

114项指控成立,曼城已经完蛋了吗?

娱乐要闻

去世刚2天,人民日报对刘欢的称呼改了

财经要闻

一天近2亿人次在路上:钱会在哪里停留?

汽车要闻

“德味十足”这几个字的含金量还在上升

态度原创

旅游
时尚
教育
艺术
军事航空

旅游要闻

十一出游先自测:爸妈到底适不适合长途旅行?

秋季,用丝巾把基础款穿出新意!

教育要闻

三年级附加题,和差问题,理解很重要

艺术要闻

油画选一 | 中国美协“青年伙伴计划·绘画100”作品展

军事要闻

特朗普"放话":美和古巴将达成协议 美方不需动用军队

无障碍浏览 进入关怀版