# SAE J1939协议栈 **Repository Path**: Beautiful_Man/sae-j1939-protocol-stack ## Basic Information - **Project Name**: SAE J1939协议栈 - **Description**: 开源的SAE J1939协议栈 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 4 - **Forks**: 6 - **Created**: 2024-01-12 - **Last Updated**: 2025-08-31 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # SAE J1939协议栈 SAE J1939 是一种协议,用于以特定方式塑造 CAN 总线消息,适用于拖拉机、机械、卡车等工业车辆。 SAE J1939 是一个非常易于使用的协议,但由于协议文档的成本,缺乏关于 SAE J1939 的信息,无法根据 SAE J1939 协议标准塑造 CAN 总线报文。因此,我正在编写一个 SAE J1939 协议,可在任何嵌入式系统(如 STM32、Arduino、AVR、PIC 等)或 PC 上免费使用。 要学习在此项目的基础上进行构建,您首先需要了解 SAE J1939。我用语言写了这个项目,因为 C 是行业标准。我选择的语言方言是,我在这个库中不使用动态内存分配。因此,它将与标准一起使用。`` 使用此库,您可以与阀门、发动机、执行器、机械、硬件和所有其他适用于重工业移动应用的东西进行通信。我已经建立了项目的基本结构,我希望其他用户能够向 SAE J1939 标准发送其代码的拉取请求以获得额外的功能,因为 SAE J1939 是一个巨大的标准。 # 如何使用项目 - 第 1 步:下载此存储库 - 第 2 步:转到并选择您的处理器,如果它不可用,请为其编写代码并向我发送拉取请求`Hardware -> Hardware.h` - 第 3 步:将文件夹复制到 IDE 中的项目文件夹。例如,重命名为 。这是个好名字。`Src``Src``Open SAE J1939` - 第 4 步:使用该示例作为 SAE J1939 项目的初始起始代码。`Examples -> Open SAE J1939 -> Main.txt` ```c /* * Main.c * * Created on: 16 juli 2021 * Author: Daniel Mårtensson */ #include /* Include Open SAE J1939 */ #include "Open_SAE_J1939/Open_SAE_J1939.h" /* Include ISO 11783 */ #include "ISO_11783/ISO_11783-7_Application_Layer/Application_Layer.h" void Callback_Function_Send(uint32_t ID, uint8_t DLC, uint8_t data[]) { /* Apply your transmit layer here, e.g: * uint32_t TxMailbox; * static CAN_HandleTypeDef can_handler; * This function transmit ID, DLC and data[] as the CAN-message. * HardWareLayerCAN_TX(&can_handler, ID, DLC, data, &TxMailbox); * * You can use TCP/IP, USB, CAN etc. as hardware layers for SAE J1939 */ } void Callback_Function_Read(uint32_t* ID, uint8_t data[], bool* is_new_data) { /* Apply your receive layer here, e.g: * CAN_RxHeaderTypeDef rxHeader = {0}; * static CAN_HandleTypeDef can_handler; * This function read CAN RX and give the data to ID and data[] as the CAN-message. * if (HardWareLayerCAN_RX(can_handler, &rxHeader, ID, data) == STATUS_OK){ * *is_new_data = true; * } * * You can use TCP/IP, USB, CAN etc. as hardware layers for SAE J1939 */ } /* This function reads the CAN traffic */ void Callback_Function_Traffic(uint32_t ID, uint8_t DLC, uint8_t data[], bool is_TX) { /* Print if it is TX or RX */ printf("%s\t", is_TX ? "TX" : "RX"); /* Print ID as hex */ printf("%08X\t", ID); /* Print the data */ uint8_t i; for (i = 0U; i < DLC; i++) { printf("%X\t", data[i]); } /* Print the non-data */ for (i = DLC; i < 8U; i++) { printf("%X\t", 0U); } /* New line */ printf("\n"); } int main() { /* Create our J1939 structure */ J1939 j1939 = { 0 }; /* * Callbacks can be used if you want to pass a specific CAN-function into the hardware layer. * All you need to do is to enable INTERNAL_CALLLBACK inside hardware.h * If you don't want to have the traffic callback, just set the argument as NULL. * If you don't want any callback at all, you can write your own hardware layer by selecting a specific procesor choice at hardware.h */ CAN_Set_Callback_Functions(Callback_Function_Send, Callback_Function_Read, Callback_Function_Traffic); /* Load your ECU information */ Open_SAE_J1939_Startup_ECU(&j1939); /* SAE J1939 process */ bool run = true; while (run) { /* Read incoming messages */ Open_SAE_J1939_Listen_For_Messages(&j1939); /* Your application code here */ } /* Save your ECU information */ Open_SAE_J1939_Closedown_ECU(&j1939); return 0; } ``` 请参阅如何更改ECU的地址、名称或标识中的示例。`Examples -> SAE J1939` # 项目结构 ![a](https://raw.githubusercontent.com/DanielMartensson/Open-SAE-J1939/main/Src/Documentation/Pictures/Project%20structure.png) # 功能 - SAE J1939:21 Transport Layer - Acknowledgement - Request - Transport Protocol Connection Management - Transport Protocol Data Transfer - SAE J1939:71 Application Layer - Request Component Identification - Request ECU Identification - Request Software Identification - Request Proprietary A - SAE J1939:73 Diagnostics Layer - DM1 - DM2 - DM3 - DM14 - DM15 - DM16 - SAE J1939:81 Network Management Layer - Address Claimed - Commanded Address - Address Not Claimed - Delete Address # 额外功能 - ISO 11783 Tractors And Machinery For Agriculture And Forestry - ISO 11783-7 Implement Messages Application Layer - Auxiliary Valve Command - Auxiliary Valve Estimated Flow - Auxiliary Valve Measured Position - General Purpose Valve Command - General Purpose Valve Estimated Flow # 问题与解答 - Q: Can this library be used with `C++`? - A: Yes it can be used with `C++` - Q: I want to build on this library, what should I do? - A: First you need to know `ANSI C (C89)` and bitwise operations. Then you need to understand the `SAE J1939:21 Transport Layer` structure. Don't forget to update the PDF with your new functionality. - Q: Can I use this on my Arduino? - A: Yes, this `C` code is 100% pure `C` code and only using `C` standard library and also the code does not take account of what hardware you are using. - Q: Do I need to install the library for to use the library? - A: No, just copy over the `.c` and `.h` files to your project and compile. I have used this with QT framework. - Q: This project is quite old now and not so much updates, is it still worth to use it? - A: Yes, this library only updates when I or other includes more functionality from SAE J1939. The reason why I wrote this in `ANSI C (C89)` is because it's an industry standard and will you will always be able to compile this library and use it on all systems. - Q: What is your plan with the library? - A: To make SAE J1939 available for everybody - Q: I don't have CAN-bus, but can I use this library anyway with UART, USB, WiFi etc? - A: Yes. This is only a way to shape a message in a specific way. - Q: Can I send data with this library, even if I don't have CAN-bus? - A: Yes. There are something called DM14 transmit request, DM15 status response and DM16 binary transfer. Use that if you want to transfer data in an industrial way. - Q: Can I send multi package messages from from multiple ECU:s to one ECU at the same time? - A: No. If you starting to send multipackages from multiple ECU:s to another ECU, then that ECU cannot understand the message. Transmit only multipackage messages one at the time if the destination address is the same. - Q: I don't want to use 'ANSI C (C89)' with Open SAE J1939. Can I use the latest C standard with Open SAE J1939? - Yes, you can use the latest C standard with this library. - Q: Is it possible to compile this library onto a Windows MS-DOS or Windows 95 machine? - A C89 compatible compiler and an IDE and it should not be any problem # 问题解决 - I: I cannot compile this library. I'm using `Keil Microvision`. - A: `Keil Microvision` cannot handle binary numbers such as `0b010101`. Try `STM32CubeIDE` instead because `Open SAE J1939` is made in `STM32CubeIDE` - I: Can you provide us with some hardware examples for example `STM32`? - A: Yes! There is a STM32 example how to get connection with CAN-bus including an interrupt listener for messages. Go to `Examples -> Hardware` folder at look for `CAN_STM32.txt`. Also there is a `USB` example as well for `QT C++`. # 来源 [GitHub - DanielMartensson/Open-SAE-J1939: SAE J1939 protocol free to use for embedded systems or PC with CAN-bus](https://github.com/DanielMartensson/Open-SAE-J1939?tab=readme-ov-file)