一款基于CAN总线的模拟ECU工具

在周立功的底层CAN库上封装了CanBusDevice 支持多个版本的动态库加载,可以用于实现单路CAN通信和多路CAN通信,共享库实现,内部有2个线程(发送和接收),采用线程锁:

#ifndef CANBUSDEVICE_H
#define CANBUSDEVICE_H

#include <QObject>
#include <QMap>

QT_BEGIN_NAMESPACE

#ifndef QT_STATIC
    #if defined(BUILD_CANBUSDEVICE_LIB)
    #define CANBUSDEVICE_EXPORT Q_DECL_EXPORT
    #else
    #define CANBUSDEVICE_EXPORT Q_DECL_IMPORT
    #endif
#else
    #define CANBUSDEVICE_EXPORT
#endif

class CanBusData;
class CanBusDevicePrivate;

class CANBUSDEVICE_EXPORT CanBusDeviceInfo {

public:
    explicit CanBusDeviceInfo(const QString &description, int devType)
    { m_description = description; m_devType = devType; }
    QString description() { return m_description; }
    int devType() { return m_devType; }

    static QList<CanBusDeviceInfo> availablePorts();

private:
    int m_devType;
    QString m_description;
};

class CANBUSDEVICE_EXPORT CanBusDevice : public QObject
{
    Q_OBJECT

public:

    enum Channel {
        Channel_0 = 0,
        Channel_1,
        Channel_2,
        Channel_3,
        UnknownChannel = -1
    };
    Q_ENUM(Channel)

    enum FilterType {
        DualFiltering = 0,
        SingleFiltering,
        UnknownFilterType = -1
    };
    Q_ENUM(FilterType)

    enum WorkMode {
        Normal = 0,
        ListenOnly,
        UnknownWorkMode = -1
    };
    Q_ENUM(WorkMode)

    enum BaudRate {
        Baud1000K = 1000,
        Baud800K = 800,
        Baud500K = 500,
        Baud250K = 250,
        Baud125K = 125,
        Baud100K = 100,
        Baud50K = 50,
        Baud20K = 20,
        Baud10K = 10,
        Baud5K = 5,
        UnknownBaud = -1
    };
    Q_ENUM(BaudRate)

    enum SendType {
        NormalTransmission = 0,
        SingleTransmission,
        SelfReceiving,
        SingleSelfReceiving,
        UnknownSendType = -1
    };
    Q_ENUM(SendType)

    enum FrameType {
        StandardFrame = 0,
        ExtendedFrame,
        UnknownExternFlag = -1
    };
    Q_ENUM(FrameType)

    enum FrameFormat {
        DataFrame = 0,
        RemoteFrame,
        UnknownFrameFormat = -1
    };
    Q_ENUM(FrameFormat)

    enum FilterIdMode {
        Disabled = 0,
        NonReceivingIds,
        OnlyReceivingIds,
        UnknownFilterIdMode = -1
    };
    Q_ENUM(FilterIdMode)

    explicit CanBusDevice(const QString &fileName, QObject *parent = nullptr);
    ~CanBusDevice();

    bool dynamicLoad(bool isLoad, const QString &fileName = QString());

    bool setAccessCode(int channel, quint32 accessCode);
    quint32 accessCode(int channel) const;
    
    bool setAccessMask(int channel, quint32 accessMask);
    quint32 accessMask(int channel) const;
    
    bool setFilterType(int channel, FilterType filterType);
    FilterType filterType(int channel) const;
    
    bool setWorkMode(int channel, WorkMode workMode);
    WorkMode workMode(int channel) const;
    
    bool setBaudRate(int channel, qint32 baudRate);
    qint32 baudRate(int channel) const;

    QString timer0(qint32 baudRate);
    QString timer1(qint32 baudRate);

    void setFilterIdMode(FilterIdMode mode);
    FilterIdMode filterIdMode(void);
    void addFilterCanid(quint32 canid);
    void addFilterCanids(QList<quint32> canids);
    void clearFilterCanids(void);
    QList<quint32> filterCanids(void);
    
    bool open(int devType, int devIndex);
    void close(void);
    bool isOpen() const;
    qint64 write(int channel, quint32 canid, const QByteArray &data, 
        FrameType frameType = ExtendedFrame, FrameFormat frameFormat = DataFrame,
        SendType sendType = NormalTransmission);

    QString errorString(void);

Q_SIGNALS:
    void detailedData(int channel, QList<CanBusData> &canDatas);
    void sectionData(int channel, quint32 canid, const QByteArray &data);
    void error(int channel, quint32 errCode, const QByteArray &passive, quint8 arLost);

private slots:
    void doRawCanData(int channel, QList<CanBusData> &canDatas);

private:
    CanBusDevicePrivate *const d_ptr;
    FilterIdMode m_filterIdMode;
    QList<quint32> m_filterCanids;
    QMap<int, qint32> m_baudRates;

private:
    Q_DECLARE_PRIVATE(CanBusDevice)
    Q_DISABLE_COPY(CanBusDevice)
};

class CANBUSDEVICE_EXPORT CanBusData
{
public:
    quint32                     canid;
    quint32                     timeStamp;
    quint8                      timeFlag;
    CanBusDevice::SendType      sendType;
    CanBusDevice::FrameType     frameType;
    CanBusDevice::FrameFormat   frameFormat;
    QByteArray                  data;
};

QT_END_NAMESPACE

#endif // CANBUSDEVICE_H

下载地址:https://download.csdn.net/download/xiyuan255/25512747

 

集成CANoe官方将BLF加密CAN转ASC格式的CAN数据的功能,自解析DBC文件转CSV文件(数据模拟)功能;

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 学习CAN总线是一项相对庞大而复杂的任务,需要一定的时间和精力来理解和掌握。以下是一些建议,帮助你从零开始学习。 首先,了解CAN总线的基本概念。CAN总线是一种用于在微控制器和其他电子设备之间传输数据的通信协议。它具有高可靠性、高实时性和高带宽的特点,在汽车、工业自动化和航空航天等领域得到广泛应用。 其次,学习CAN总线的基本原理。CAN总线采用了差分信号传输和冲突检测与解决的机制,使得多个节点可以同时发送和接收数据。了解CAN总线的物理层和数据链路层的工作原理,包括位定时、帧格式、帧标识符和错误处理等方面的知识。 第三,学习CAN总线的应用。了解CAN总线在不同领域的应用案例,例如汽车中的车载网络、工业自动化中的设备控制和航空航天中的数据传输。深入了解这些应用案例将有助于你更好地理解和应用CAN总线技术。 第四,进行实际的实验和项目。通过实际的实验和项目,你可以亲自动手搭建CAN总线通信系统,了解其配置和调试过程。同时,你还可以通过参与开源项目或者模拟实践项目来提高自己的实践能力和解决问题的能力。 最后,不断学习和实践。CAN总线是一个广阔而复杂的领域,需要持续的学习和实践才能够真正掌握。通过不断地学习新知识、参与实践、解决问题,你将逐渐成为一个专业的CAN总线工程师。 总之,学习CAN总线需要耐心和时间,但只要你有足够的决心和努力,相信你一定可以从零学懂CAN总线。希望以上的建议能对你有所帮助。 ### 回答2: 学习CAN总线可以从以下几个方面入手。 首先,了解CAN总线的基本原理。CAN总线是一种通信协议,用于控制器区域网络。它主要用于汽车和工业领域的实时通信。可以了解CAN总线的工作原理、数据传输方式以及帧格式等基础知识。 其次,了解CAN总线的应用领域和优势。CAN总线广泛应用于汽车的电子控制系统中,如发动机控制、制动控制和座椅控制等。了解CAN总线在工业自动化中的应用场景,如机器人和控制系统中的使用。同时,了解CAN总线相比传统通信协议的优势,如实时性强、可靠性高等特点。 进一步,学习CAN总线的通信方式和协议。CAN总线采用的是两线制通信,即CAN_H和CAN_L。了解CAN总线的物理层和数据链路层协议,如位定时器和帧发送器等。还可以学习CAN总线的通信速率和通信范围等相关知识。 最后,进行实践操作。通过购买一套CAN总线开发工具,如CAN总线调试器和开发板,进行实际的项目开发。可以尝试使用CAN总线进行简单的通信测试或控制实验,如发送和接收CAN总线数据等。 总之,学习CAN总线需要从理论知识、应用场景、通信方式和实践操作四个方面进行综合学习。通过系统性地学习和实践,可以逐步掌握CAN总线的相关知识和技能,实现从零学习CAN总线的目标。 ### 回答3: 从零学懂CAN总线有几个主要的步骤和概念需要理解。 首先,需要了解CAN总线是什么。CAN(Controller Area Network)总线是一种广泛应用于汽车和工业领域的串行通信协议,用于在不同的电子控制单元(ECU)之间进行通信。它通过两根传输线(CAN_H和CAN_L)进行数据交换。 其次,要学习CAN总线的基本原理。CAN总线采用差分信号传输,即CAN_H线上的电压与CAN_L线上的电压互为反相。这种传输方式可以减少电磁干扰,并提高抗干扰能力。CAN总线采用非常规线路拓扑结构,即多个ECU通过一个主控制器连接在一个总线上。 然后,需要学习CAN总线的帧格式和通信方式。CAN总线使用帧的形式进行数据传输,包括标准帧和扩展帧。标准帧使用11位标识符,扩展帧使用29位标识符。CAN总线采用CSMA/CD(载波监听多路访问/冲突检测)的通信方式,即多个ECU同时发送数据时,会检测到冲突并采取相应的策略。 另外,要学习CAN总线的数据传输和错误检测。CAN总线支持数据的广播和单播传输,可以实现实时和可靠的数据传输。同时,CAN总线还提供了多种错误检测机制,包括奇偶校验、位错误检测、CRC(循环冗余校验)等,以保证数据的可靠性。 最后,要学习如何使用CAN总线进行开发和调试。可以使用CAN总线适配器或开发板连接到计算机,并使用相应的软件进行数据通信和调试。需要熟悉CAN总线的相关API和命令,并了解如何在不同的开发环境中进行CAN总线的配置和使用。 通过以上的学习和实践,从零学懂CAN总线需要理解CAN总线的基本原理、帧格式和通信方式、数据传输和错误检测以及如何进行开发和调试。同时,实际的应用和项目经验也是提高对CAN总线理解和应用能力的重要途径。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值