افتح SAE J1939
SAE J1939 هو بروتوكول لتشكيل رسالة CAN-BUS بطريقة محددة تناسب المركبات الصناعية مثل الجرارات والآلات والشاحنات والمزيد.
SAE J1939 هو بروتوكول سهل للغاية للاستخدام ، ولكن هناك نقص في المعلومات حول SAE J1939 ، نظرًا لتكلفة وثيقة البروتوكول ، المتاحة كيفية تشكيل رسالة حافظة وفقًا لمعيار بروتوكول SAE J1939. لذلك أنا أكتب بروتوكول SAE J1939 متاح مجانًا للاستخدام على أي أنظمة مضمنة مثل STM32 أو Arduino أو AVR أو PIC وما إلى ذلك.
لتعلم بناء هذا المشروع ، تحتاج أولاً إلى فهم SAE J1939. لقد كتبت هذا المشروع بلغة C لأن C هو معيار الصناعة. لهجة C Language التي اخترتها هي ANSI C (C89) ولا أستخدم تخصيص الذاكرة الديناميكية في هذه المكتبة. لذلك سوف يعمل مع MISRA C Standard.
مع هذه المكتبة ، يمكنك التواصل مع الصمامات والمحركات والمشغلات والآلات والأجهزة وجميع الأشياء الأخرى المناسبة لتطبيقات الهاتف المحمول الثقيلة. لقد قمت ببناء بنية أساسية للمشروع وآمل أن يرسل المستخدمون الآخرون طلب سحب من رمز C للحصول على وظائف إضافية إلى معيار SAE J1939 لأن SAE J1939 هو معيار ضخم.
هل تبحث عن مكتبة C canopen للأنظمة المدمجة؟ https://github.com/danielmartensson/Aasy-Canopen
هل تبحث عن إطار C ++ واجهة المستخدم الرسومية التي تستخدم SAE J1939 المفتوحة على USB؟ https://github.com/danielmartensson/GoObysoft
هل تبحث عن مشروع C STM32 مع Open SAE J1939؟ https://github.com/danielmartensson/stm32-plc
ابدء
أول شيء تحتاج إلى معرفته هو قراءة مستند PDF الخاص بي من Open SAE J1939 داخل مجلد Documentation . تعلم بنية المشروع ، وإلا فلن تتمكن من فهم SAE J1939. بعد أن تحصل على فهم أساسي للمشروع ، يمكنك البناء عليه. تبقيه بسيطًا واتبع معيار SAE J1939!
بعد أن تفهم بنية المشروع ، ثم حدد اختيار المعالج في ملف Hardware -> Hardware.h . هنا يمكنك تحديد على سبيل المثال STM32 ، Arduino ، PIC ، AVR إلخ. أو إذا كنت ترغب في تشغيله على الكمبيوتر أولاً ، ثم حدد PROCESSOR_CHOICE 0 وقم بتشغيل بعض الأمثلة. هذا هو وضع تصحيح الأخطاء للملاحظات الداخلية.
كيفية استخدام المشروع
- الخطوة 1: قم بتنزيل هذا المستودع
- الخطوة 2: انتقل إلى
Hardware -> Hardware.h وحدد المعالج الخاص بك ، إذا لم يكن متاحًا ، يرجى كتابة رمز له وإرسال طلب سحب لي - الخطوة 3: انسخ عبر مجلد
Src إلى مجلد المشروع داخل IDE. إعادة تسمية Src على سبيل المثال Open SAE J1939 . هذا اسم جيد. - الخطوة 4: استخدم
Examples -> Open SAE J1939 -> Main.txt مثل رمز البداية الأولي لمشروع SAE J1939.
/*
* Main.c
*
* Created on: 16 juli 2021
* Author: Daniel Mårtensson
*/
#include <stdio.h>
/* 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 ( "%st" , is_TX ? "TX" : "RX" );
/* Print ID as hex */
printf ( "%08Xt" , ID );
/* Print the data */
uint8_t i ;
for ( i = 0U ; i < DLC ; i ++ ) {
printf ( "%Xt" , data [ i ]);
}
/* Print the non-data */
for ( i = DLC ; i < 8U ; i ++ ) {
printf ( "%Xt" , 0U );
}
/* New line */
printf ( "n" );
}
/* Apply your delay here */
void Callback_Function_Delay ( uint8_t delay ){
/* Place your hardware delay here e.g HAL_Delay(delay); for STM32 */
}
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 processor choice at hardware.h
*/
CAN_Set_Callback_Functions ( Callback_Function_Send , Callback_Function_Read , Callback_Function_Traffic , Callback_Function_Delay );
/* 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 ;
} راجع الأمثلة في Examples -> SAE J1939 كيفية تغيير العنوان أو الاسم أو التعرفات على وحدة التحكم الإلكترونية الخاصة بك.
هيكل المشروع
مثال على العمل كيف يتم تنفيذ هيكل SAE J1939 المفتوح
مخطط التدفق هذا في الكود كيف تعمل مكتبة SAE J1939 المفتوحة. يوضح هذا المثال كيفية إرسال طلب والحصول على إجابة.
- الخطوة 1: سوف ترسل
ECU X PGN إلى ECU Y . تفسير PGN كرمز وظيفة. | enum_j1939_status_codes sae_j1939_send_request_ecu_identification ( j1939 * j1939 ، uint8_t da ) { |
| return sae_j1939_send_request ( j1939 ، DA ، pgn_ecu_identification ) ؛ |
| } |
- الخطوة 2: سوف تقرأ
ECU Y رسالة PGN من ECU X | bool is_new_message = can_read_message ( & id ، data ) ؛ |
| if ( is_new_message ) { |
| / * حفظ أحدث */ |
| J1939 -> id = id ؛ |
| memcpy ( J1939 -> البيانات ، البيانات ، 8 ) ؛ |
| J1939 -> id_and_data_is_updated = true ؛ |
| |
| uint8_t id0 = id >> 24 ؛ |
| uint8_t id1 = id >> 16 ؛ |
| uint8_t da = id >> 8 ؛ /* عنوان الوجهة الذي هو هذه وحدة التحكم الإلكترونية. إذا كان da = 0xff = بث إلى جميع وحدة التحكم الإلكترونية. في بعض الأحيان يمكن أن يكون DA رقم معرف أيضًا */ |
| uint8_t sa = id ؛ / * عنوان مصدر وحدة التحكم الإلكترونية التي تلقينا رسالة من */ |
| |
| / * قراءة طلب من ecu الأخرى */ |
| if ( id0 == 0x18 && id1 == 0xea && ( da == J1939 -> information_this_ecu . this_ecu_address || da == 0xff )) { |
| SAE_J1939_READ_REQUEST ( J1939 ، SA ، DATA ) ؛ |
- الخطوة 3: سيتم تفسير رمز وظيفة
PGN بواسطة ECU Y . | void sae_j1939_read_request ( j1939 * j1939 ، uint8_t sa ، uint8_t data []) { |
| uint32_t pgn = ( البيانات [ 2 ] << 16 ) | ( البيانات [ 1 ] << 8 ) | البيانات [ 0 ] ؛ |
| if ( pgn == pgn_acknowledgement ) { |
| sae_j1939_send_acknowledgement ( j1939 ، sa ، control_byte_acknowledgement_pgn_supported ، group_function_value_normal ، pgn ) ؛ |
| } آخر إذا ( pgn == pgn_address_claimed ) { |
| sae_j1939_response_request_address_claimed ( j1939 ) ؛ |
| } آخر إذا ( pgn == pgn_commanded_address ) { |
| sae_j1939_send_acknowledgement ( j1939 ، sa ، control_byte_acknowledgement_pgn_supported ، group_function_value_normal ، pgn ) ؛ |
| } آخر إذا ( pgn == pgn_address_delete ) { |
| sae_j1939_send_acknowledgement ( j1939 ، sa ، control_byte_acknowledgement_pgn_supported ، group_function_value_normal ، pgn ) ؛ / * لا SAE J1939 Standard */ |
| } آخر إذا ( pgn == pgn_dm1 ) { |
| sae_j1939_response_request_dm1 ( j1939 ، sa ) ؛ |
| } آخر إذا ( pgn == pgn_dm2 ) { |
| sae_j1939_response_request_dm2 ( j1939 ، sa ) ؛ |
| sae_j1939_send_acknowledgement ( j1939 ، sa ، control_byte_acknowledgement_pgn_supported ، group_function_value_normal ، pgn ) ؛ |
| } آخر إذا ( pgn == pgn_dm3 ) { |
| sae_j1939_response_request_dm3 ( j1939 ، sa ) ؛ |
| } آخر إذا ( pgn == pgn_request ) { |
| sae_j1939_send_acknowledgement ( j1939 ، sa ، control_byte_acknowledgement_pgn_supported ، group_function_value_normal ، pgn ) ؛ |
| } آخر إذا ( pgn == pgn_tp_cm ) { |
| sae_j1939_send_acknowledgement ( j1939 ، sa ، control_byte_acknowledgement_pgn_supported ، group_function_value_normal ، pgn ) ؛ |
| } آخر إذا ( pgn == pgn_tp_dt ) { |
| sae_j1939_send_acknowledgement ( j1939 ، sa ، control_byte_acknowledgement_pgn_supported ، group_function_value_normal ، pgn ) ؛ |
| } آخر إذا ( pgn > = pgn_auxiliary_valve_estimated_flow_0 && pgn <= pgn_auxiliary_valve_estimated_flow_15 ) { |
| iso_11783_response_request_auxiliary_valve_estimated_flow ( j1939 ، pgn & 0xf ) ؛ / * pgn & 0xf = valve_number */ |
| } آخر إذا ( pgn == pgn_general_purpose_valve_estimated_flow ) { |
| iso_11783_response_request_general_purpose_valve_estimated_flow ( j1939 ، sa ) ؛ |
| } آخر إذا ( pgn > = pgn_auxiliary_valve_measured_position_0 && pgn <= pgn_auxiliary_valve_measured_position_15 ) { |
| iso_11783_response_request_auxiliary_valve_measured_position ( j1939 ، pgn & 0xf ) ؛ / * pgn & 0xf = valve_number */ |
| } آخر إذا ( pgn == pgn_software_identification ) { |
| sae_j1939_response_request_software_identification ( j1939 ، sa ) ؛ |
| } آخر إذا ( pgn == pgn_ecu_identification ) { |
| sae_j1939_response_request_ecu_identification ( j1939 ، sa ) ؛ |
- الخطوة 4: يتم الآن تفسير رمز دالة
PGN على أنه ECU Identification بواسطة ECU Y ثم تقوم ECU Y ببث ECU Identification إلى جميع ECUs .- الخطوة 4.1.1: بالنسبة لرسالة حزمة واحدة ، ستقوم
ECU Y ببث ECU Identification . | enum_j1939_status_codes sae_j1939_response_request_ecu_identification ( j1939 * j1939 ، uint8_t da ) { |
| / * ابحث عن طول حقول الصفيف */ |
| uint8_t length_of_each_field = j1939 -> information_this_ecu . هذا . ecu_identification . length_of_each_field ؛ |
| if ( length_of_each_field < 2 ) { |
| / * إذا كان لكل حقل الطول 1 ، فيمكننا إرسال تعريف وحدة التحكم الإلكترونية لأنها كانت رسالة عادية */ |
| uint32_t id = ( 0x18fdc5 << 8 ) | J1939 -> information_this_ecu . this_ecu_address ؛ |
| بيانات UINT8_T [ 8 ] ؛ |
| البيانات [ 0 ] = J1939 -> information_this_ecu . هذا . ecu_identification . ecu_part_number [ 0 ] ؛ |
| البيانات [ 1 ] = J1939 -> information_this_ecu . هذا . ecu_identification . ecu_serial_number [ 0 ] ؛ |
| البيانات [ 2 ] = J1939 -> information_this_ecu . هذا . ecu_identification . ecu_location [ 0 ] ؛ |
| البيانات [ 3 ] = J1939 -> information_this_ecu . هذا . ecu_identification . ecu_type [ 0 ] ؛ |
| البيانات [ 4 ] = 0xFF ؛ /* محجوز */ |
| البيانات [ 5 ] = 0xFF ؛ /* محجوز */ |
| البيانات [ 6 ] = 0xFF ؛ /* محجوز */ |
| البيانات [ 7 ] = 0xFF ؛ /* محجوز */ |
| return can_send_message ( id ، data ) ؛ |
| } آخر { |
- الخطوة 4.1.2: اقرأ الاستجابة من
ECU X من ECU Y لأنه يتم بث ECU Identification . | } آخر إذا ( id0 == 0x18 && id1 == 0xfd && da == 0xc5 ) { |
| SAE_J1939_READ_RESPONSE_REQUEST_ECU_IDIDING ( J1939 ، SA ، DATA ) ؛ |
- الخطوة 4.2.1: بالنسبة لرسالة الحزمة المتعددة ، يمكن أن يكون بايت التحكم BAM أو RTS. يتم استخدام BAM فقط إذا أرسلت إلى جميع العنوان
ECUs EG 0xFF = 255 . ولكن إذا كان بايت التحكم هو RTS ، فإن عنوان EG ليس 0xFF ، فسيقوم ECU Y بإرسال RTS والاستماع إلى استجابة CTS بواسطة ECU X RTS هو سؤال "اسمحوا لي أن أعرف متى يمكنني نقل الرسالة؟" و CTS هو الرد Now you can transmit the message to me . | J1939 -> this_ecu_tp_cm . Total_message_size = 0 ؛ |
| uint8_t i ؛ |
| لـ ( i = 0 ؛ i < length_of_each_field ؛ i ++ ) { |
| J1939 -> this_ecu_tp_dt . البيانات [ i ] = j1939 -> information_this_ecu . هذا . ecu_identification . ecu_part_number [ i ] ؛ |
| J1939 -> this_ecu_tp_dt . البيانات [ length_of_each_field + i ] = j1939 -> information_this_ecu . هذا . ecu_identification . ecu_serial_number [ i ] ؛ |
| J1939 -> this_ecu_tp_dt . البيانات [ length_of_each_field * 2 + i ] = j1939 -> information_this_ecu . هذا . ecu_identification . ecu_location [ i ] ؛ |
| J1939 -> this_ecu_tp_dt . البيانات [ length_of_each_field * 3 + i ] = j1939 -> information_this_ecu . هذا . ecu_identification . ecu_type [ i ] ؛ |
| J1939 -> this_ecu_tp_cm . Total_message_size += 4 ؛ |
| } |
| |
| / * أرسل TP CM */ |
| J1939 -> this_ecu_tp_cm . number_of_packages = j1939 -> this_ecu_tp_cm . Total_message_size ٪ 8 > 0 ؟ J1939 -> this_ecu_tp_cm . Total_message_size / 8 + 1 : J1939 -> this_ecu_tp_cm . Total_message_size / 8 ؛ / * التقريب */ |
| J1939 -> this_ecu_tp_cm . pgn_of_the_packeted_message = pgn_ecu_identification ؛ |
| J1939 -> this_ecu_tp_cm . control_byte = da == 0xff ؟ Control_byte_tp_cm_bam : control_byte_tp_cm_rts ؛ / * إذا تم بثه ، فاستخدم BAM Control Byte */ |
| enum_j1939_status_codes الحالة = sae_j1939_send_transport_protocol_connection_management ( j1939 ، da ) ؛ |
- الخطوة 4.2.2: إذا كانت
ECU Y ترسل RTS ، فسيقرأ ECU X RTs والاستجابة مع CTS مرة أخرى إلى ECU Y | if ( j1939 -> from_other_ecu_tp_cm . control_byte == control_byte_tp_cm_rts ) { |
| J1939 -> this_ecu_tp_cm = j1939 -> from_other_ecu_tp_cm ؛ / * نسخ - نحتاج إلى الحصول على نفس البيانات */ |
| J1939 -> this_ecu_tp_cm . control_byte = control_byte_tp_cm_cts ؛ / * نحتاج فقط إلى تغيير بايت التحكم من RTs إلى CTS */ |
| sae_j1939_send_transport_protocol_connection_management ( j1939 ، sa ) ؛ |
| } |
- الخطوة 4.2.3: بمجرد أن تتلقى
ECU Y CTS ، فإنها ستنقل البيانات ، في هذه الحالة ECU Identification ، مرة أخرى إلى ECU X . | if ( j1939 -> from_other_ecu_tp_cm . control_byte == control_byte_tp_cm_cts ) { |
| sae_j1939_send_transport_protocol_data_transfer ( j1939 ، sa ) ؛ |
| } |
- الخطوة 4.2.3: بمجرد إرسال
ECU Y الحزمة بعد الحزمة ... | enum_j1939_status_codes sae_j1939_send_transport_protocol_data_transfer ( j1939 * j1939 ، uint8_t da ) { |
| uint32_t id = ( 0x1CEB << 16 ) | ( دا << 8 ) | J1939 -> information_this_ecu . this_ecu_address ؛ |
| uint8_t i ، j ، package [ 8 ] ؛ |
| uint16_t bytes_sent = 0 ؛ |
| enum_j1939_status_codes status = status_send_ok ؛ |
| لـ ( i = 1 ؛ i <= j1939 -> this_ecu_tp_cm . number_of_packages ؛ i ++ ) { |
| حزمة [ 0 ] = i ؛ / * عدد الحزمة */ |
| لـ ( j = 0 ؛ j < 7 ؛ j ++ ) { |
| if ( bytes_sent < j1939 -> this_ecu_tp_cm . total_message_size ) { |
| الحزمة [ J + 1 ] = J1939 -> this_ecu_tp_dt . البيانات [ bytes_sent ++ ] ؛ / * البيانات التي جمعناها */ |
| } آخر { |
| حزمة [ j + 1 ] = 0xff ؛ /* محجوز */ |
| } |
| } |
| الحالة = can_send_message ( معرف ، حزمة ) ؛ |
| can_delay ( 100 ) ؛ / * المهم يمكن أن يؤخر وفقًا للمعيار */ |
| if ( الحالة ! = status_send_ok ) { |
| حالة العودة ؛ |
| } |
| } |
| حالة العودة ؛ |
| } |
- الخطوة 4.2.4: تقوم
ECU X بتلقي كل حزمة وبناء الرسالة من خلال معرفة رمز وظيفة PNG . | void sae_j1939_read_transport_protocol_data_transfer ( j1939 * j1939 ، uint8_t sa ، uint8_t data []) { |
| / * احفظ بيانات التسلسل */ |
| J1939 -> from_other_ecu_tp_dt . sequence_number = data [ 0 ] ؛ |
| J1939 -> from_other_ecu_tp_dt . from_ecu_address = sa ؛ |
| uint8_t i ، j ، index = data [ 0 ] - 1 ؛ |
| لـ ( i = 1 ؛ i < 8 ؛ i ++ ) { |
| J1939 -> from_other_ecu_tp_dt . البيانات [ الفهرس * 7 + i - 1 ] = البيانات [ i ] ؛ / * لكل حزمة ، نرسل 7 بايت من البيانات حيث تكون بيانات البايت الأولى [0] رقم التسلسل */ |
| } |
| / * تحقق مما إذا كنا قد أكملنا رسالتنا - إرجاع = غير مكتمل */ |
| if ( j1939 - > from_other_ecu_tp_cm . number_of_packages ! = j1939 - > from_other_tp_tp_dt . sequence_number || |
| يعود ؛ |
| } |
| |
| / * رسالتنا كاملة - قم بإنشائها واتصل بها complete_data [Total_message_size] */ |
| uint32_t pgn = j1939 -> from_other_ecu_tp_cm . pgn_of_the_packeted_message ؛ |
| uint16_t total_message_size = j1939 -> from_other_ecu_tp_cm . total_message_size ؛ |
| uint8_t complete_data [ max_tp_dt ] ؛ |
| uint16_t inserted_bytes = 0 ؛ |
| لـ ( i = 0 ؛ i < j1939 -> from_other_ecu_tp_dt . sequence_number ؛ i ++ ) { |
| لـ ( j = 0 ؛ j < 7 ؛ j ++ ) { |
| if ( inserted_bytes < total_message_size ) { |
| complete_data [ inserted_bytes ++ ] = j1939 -> from_other_ecu_tp_dt . البيانات [ i * 7 + j ] ؛ |
| } |
| } |
| } |
| |
| / * أرسل نهاية الرسالة ACK مرة أخرى */ |
| if ( j1939 -> from_other_ecu_tp_cm . control_byte == control_byte_tp_cm_rts ) { |
| sae_j1939_send_acknowledgement ( j1939 ، sa ، control_byte_tp_cm_endofmsgack ، group_function_value_normal ، pgn ) ؛ |
| } |
ثم أخيرًا تنفيذ الرسالة. | حالة pgn_ecu_identific |
| SAE_J1939_READ_RESPONSE_REQUEST_ECU_IDIDING ( J1939 ، SA ، COMMUNT_DATA ) ؛ |
| استراحة ؛ |
SAE J1939 وظيفة
- SAE J1939: 21 طبقة النقل
- شكر وتقدير
- طلب
- إدارة اتصال بروتوكول النقل مع BAM و CTS و RTS و EOM
- نقل بيانات بروتوكول النقل
- SAE J1939: 71 طبقة التطبيق
- طلب تحديد مكون
- طلب تحديد هوية ECU
- طلب هوية البرنامج
- طلب الملكية أ
- طلب الملكية ب
- SAE J1939: 73 طبقة التشخيص
- DM1
- DM2
- DM3
- DM14
- DM15
- DM16
- SAE J1939: 81 طبقة إدارة الشبكة
- العنوان المطالب به
- عنوان أمر
- العنوان لم يطالب به
- حذف العنوان
وظائف إضافية
- ISO 11783 جرارات وآلات للزراعة والغابات
- ISO 11783-7 تنفيذ طبقة تطبيق الرسائل
- أمر صمام مساعد
- الصمام المساعد المقدر التدفق
- موقف صمام مساعد مقاس
- أمر صمام الغرض العام
- صمام الغرض العام المقدر التدفق
الأسئلة والأجوبة
- س: هل يمكن استخدام هذه المكتبة مع
C++ ؟- ج: نعم يمكن استخدامه مع
C++
- س: أريد أن أبني على هذه المكتبة ، ماذا علي أن أفعل؟
- ج: أولاً ، تحتاج إلى معرفة عمليات
ANSI C (C89) وعمليات bitwise. ثم تحتاج إلى فهم هيكل SAE J1939:21 Transport Layer . لا تنس تحديث PDF من خلال وظيفتك الجديدة.
- س: هل يمكنني استخدام هذا على Arduino الخاص بي؟
- ج: نعم ، رمز
C هذا هو رمز C نقي بنسبة 100 ٪ ويستخدم فقط C Library القياسي وأيضًا لا يأخذ الرمز في مراعاة الأجهزة التي تستخدمها.
- س: هل أحتاج إلى تثبيت المكتبة لاستخدام المكتبة؟
- ج: لا ، فقط نسخ ملفات
.c و .h إلى مشروعك وتجميعها. لقد استخدمت هذا مع إطار QT.
- س: هذا المشروع قديم جدًا الآن وليس الكثير من التحديثات ، هل ما زال يستحق استخدامه؟
- ج: نعم ، يتم تحديث هذه المكتبة فقط عندما تتضمن أنا أو غيرها المزيد من الوظائف من SAE J1939. السبب في أنني كتبت هذا في
ANSI C (C89) هو أنه معيار في الصناعة وستتمكن دائمًا من تجميع هذه المكتبة واستخدامها على جميع الأنظمة.
- س: ما هي خطتك مع المكتبة؟
- ج: لجعل SAE J1939 متاحًا للجميع
- س: ليس لدي علب ، لكن هل يمكنني استخدام هذه المكتبة على أي حال مع UART و USB و WiFi وما إلى ذلك؟
- ج: نعم. هذه ليست سوى طريقة لتشكيل رسالة بطريقة محددة.
- س: هل يمكنني إرسال بيانات مع هذه المكتبة ، حتى لو لم يكن لديّ علب؟
- ج: نعم. هناك شيء يسمى طلب الإرسال DM14 ، استجابة حالة DM15 والنقل الثنائي DM16. استخدم ذلك إذا كنت ترغب في نقل البيانات بطريقة صناعية.
- س: هل يمكنني إرسال رسائل حزمة متعددة من ECU متعددة إلى وحدة التحكم الإلكترونية واحدة في نفس الوقت؟
- ج: لا. إذا بدأت في إرسال تعدد الأدوات من ECU متعددة إلى وحدة نقدية وحدة التحكم الإلكترونية أخرى ، فإن وحدة التحكم الإلكترونية لا يمكنها فهم الرسالة. نقل الرسائل المتعددة فقط واحدة في ذلك الوقت إذا كان عنوان الوجهة هو نفسه.
- س: لا أريد استخدام
ANSI C (C89) مع Open SAE J1939. هل يمكنني استخدام أحدث معيار C مع Open SAE J1939؟- نعم ، يمكنك استخدام أحدث معيار C مع هذه المكتبة.
- س: هل من الممكن تجميع هذه المكتبة على جهاز Windows MS-DOS أو Windows 95؟
- مترجم متوافق مع C89 و IDE ولا ينبغي أن يكون أي مشكلة
- س: هل يمكنني ضبط الذاكرة التي يشغلها البرنامج؟
- ج: نعم ، يمكنك ضبط المعرفة
MAX_PROPRIETARY_A و MAX_PROPRIETARY_B و MAX_PROPRIETARY_B_PGNS في Structs.h الملفات. يتم توفير القيمة الافتراضية "عاقلة" ، ولكن يمكنك ضبطها على الحد الأدنى إذا لم يكن هناك حاجة إلى دعم PGNS الخاص إذا لم يكن هناك حاجة إلى استخدام المزيد من PGN.
القضايا والأجوبة
- أنا: لا يمكنني تجميع هذه المكتبة. أنا أستخدم
Keil Microvision .- A: لا يمكن لـ
Keil Microvision التعامل مع الأرقام الثنائية مثل 0b010101 . جرب STM32CubeIDE بدلاً من ذلك لأن Open SAE J1939 مصنوع في STM32CubeIDE
- أنا: هل يمكنك تزويدنا ببعض أمثلة الأجهزة على سبيل المثال
STM32 ؟- ج: نعم! هناك مثال STM32 كيفية الحصول على اتصال مع CAN-BUS بما في ذلك مستمع المقاطعة للرسائل. انتقل إلى
Examples -> Hardware عند البحث عن CAN_STM32.txt . كما يوجد مثال USB أيضًا لـ QT C++ .