SAE J1939를 개방하십시오
SAE J1939는 트랙터, 기계, 트럭 등과 같은 산업용 차량에 적합한 특정 방식으로 캔 버스 메시지를 형성하기위한 프로토콜입니다.
SAE J1939는 사용할 수있는 매우 쉬운 프로토콜이지만 프로토콜 문서의 비용으로 인해 SAE J1939 프로토콜 표준에 따라 CAN 버스 메시지를 형성하는 방법으로 인해 SAE J1939에 대한 정보가 부족합니다. 따라서 STM32, Arduino, AVR, PIC 등 또는 PC와 같은 임베디드 시스템에서 무료로 사용할 수있는 SAE J1939 프로토콜을 작성하고 있습니다.
이 프로젝트를 구축하는 법을 배우려면 먼저 SAE J1939를 이해해야합니다. C는 업계 표준이기 때문에이 프로젝트를 C 언어로 작성했습니다. 내가 선택한 C 언어 방언은 ANSI C (C89) 이며이 라이브러리에서 동적 메모리 할당을 사용하지 않습니다. 따라서 MISRA C 표준과 함께 작동합니다.
이 라이브러리를 사용하면 밸브, 엔진, 액추에이터, 기계, 하드웨어 및 중공업 모바일 애플리케이션에 적합한 기타 모든 것과 통신 할 수 있습니다. 프로젝트의 기본 구조를 구축했으며 SAE J1939가 큰 표준이기 때문에 다른 사용자가 추가 기능에 대한 추가 기능에 대한 C 코드의 풀 요청을 보낼 수 있기를 바랍니다.
임베디드 시스템을위한 C Canopen 라이브러리를 찾고 계십니까? https://github.com/danielmartensson/easy-canopen
USB를 통해 Open SAE J1939를 사용하는 C ++ GUI 프레임 워크를 찾고 계십니까? https://github.com/danielmartensson/goobysoft
Open SAE J1939의 C STM32 프로젝트를 찾고 계십니까? https://github.com/danielmartensson/stm32-plc
시작하기
가장 먼저 알아야 할 것은 Documentation 폴더 내에서 Open SAE J1939의 내 자신의 PDF 문서를 읽는 것입니다. 프로젝트의 구조를 배우십시오. 그렇지 않으면 SAE J1939를 이해할 수 없습니다. 프로젝트에 대한 기본적인 이해를 얻은 후에는 프로젝트를 구축 할 수 있습니다. 간단하게 유지하고 SAE J1939 표준을 따르십시오!
프로젝트의 구조를 이해 한 후 Hardware -> Hardware.h 파일에서 프로세서 선택을 선택하십시오. 여기서는 STM32 , Arduino , PIC , AVR 등을 선택하거나 먼저 PC에서 실행하려면 PROCESSOR_CHOICE 0 선택하고 몇 가지 예제를 실행할 수 있습니다. 이것이 바로 내부 캔 피드백의 디버깅 모드입니다.
프로젝트 사용 방법
- 1 단계 :이 저장소를 다운로드하십시오
- 2 단계 :
Hardware -> Hardware.h 로 이동하여 프로세서를 선택하십시오. 사용할 수없는 경우 코드를 작성하고 풀 요청을 보내주십시오. - 3 단계 :
Src 폴더를 통해 IDE 내부의 프로젝트 폴더로 복사하십시오. 예를 들어 Open SAE J1939 예를 들어 Src 의 이름을 바꿉니다. 그것은 좋은 이름입니다. - 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 ECU의 주소, 이름 또는 식별 방법을 변경하는 방법을 참조하십시오.
프로젝트의 구조
Open SAE J1939의 구조가 어떻게 수행되는지 작업 예제
Code 의이 흐름도는 SAE J1939 라이브러리가 어떻게 작동하는지 코드입니다. 이 예제는 요청을 보내고 답변을 얻는 방법을 보여줍니다.
- 1 단계 :
ECU X PGN ECU Y 로 보낼 것입니다. PGN 함수 코드로 해석하십시오. | enum_j1939_status_codes sae_j1939_send_request_ecu_identification ( j1939 * j1939 , uint8_t da ) { |
| SAE_J1939_SEND_REQUEST (J1939 , DA , PGN_ECU_INDIFITION ); |
| } |
- 2 단계 :
ECU Y ECU X 의 PGN 메시지를 읽을 것입니다. | 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 ; /*이 ECU 인 목적지 주소. da = 0xff = 모든 ECU에 방송됩니다. 때로는 DA도 ID 번호가 될 수 있습니다 */ |
| uint8_t sa = id ; / * ECU의 소스 주소는 */로부터 메시지를 받았습니다. |
| |
| / * 다른 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 = ( data [ 2 ] << 16 ) | ( 데이터 [ 1 ] << 8 ) | 데이터 [ 0 ]; |
| if ( pgn == pgn_acknowledgement ) { |
| SAE_J1939_SEND_ACKNOWLEDGEMENT ( J1939 , SA , CONTROL_BYTE_ACKNOWELDGEMENT_PGN_SUPPORTED , Group_Function_Value_normal , PGN ); |
| } else if ( pgn == pgn_address_claimed ) { |
| SAE_J1939_RESPONSE_REQUEST_ADDRESS_CLAIMED ( J1939 ); |
| } else if ( pgn == pgn_commanded_address ) { |
| SAE_J1939_SEND_ACKNOWLEDGEMENT ( J1939 , SA , CONTROL_BYTE_ACKNOWELDGEMENT_PGN_SUPPORTED , Group_Function_Value_normal , PGN ); |
| } else if ( pgn == pgn_address_delete ) { |
| SAE_J1939_SEND_ACKNOWLEDGEMENT ( J1939 , SA , CONTROL_BYTE_ACKNOWELDGEMENT_PGN_SUPPORTED , Group_Function_Value_normal , PGN ); / * SAE J1939 표준 */ |
| } else if ( pgn == pgn_dm1 ) { |
| SAE_J1939_RESPONSE_REQUEST_DM1 ( J1939 , SA ); |
| } else if ( pgn == pgn_dm2 ) { |
| SAE_J1939_RESPONSE_REQUEST_DM2 ( J1939 , SA ); |
| SAE_J1939_SEND_ACKNOWLEDGEMENT ( J1939 , SA , CONTROL_BYTE_ACKNOWELDGEMENT_PGN_SUPPORTED , Group_Function_Value_normal , PGN ); |
| } else if ( pgn == pgn_dm3 ) { |
| SAE_J1939_RESPONSE_REQUEST_DM3 ( J1939 , SA ); |
| } else if ( pgn == pgn_request ) { |
| SAE_J1939_SEND_ACKNOWLEDGEMENT ( J1939 , SA , CONTROL_BYTE_ACKNOWELDGEMENT_PGN_SUPPORTED , Group_Function_Value_normal , PGN ); |
| } else if ( pgn == pgn_tp_cm ) { |
| SAE_J1939_SEND_ACKNOWLEDGEMENT ( J1939 , SA , CONTROL_BYTE_ACKNOWELDGEMENT_PGN_SUPPORTED , Group_Function_Value_normal , PGN ); |
| } else if ( pgn == pgn_tp_dt ) { |
| SAE_J1939_SEND_ACKNOWLEDGEMENT ( J1939 , SA , CONTROL_BYTE_ACKNOWELDGEMENT_PGN_SUPPORTED , Group_Function_Value_normal , PGN ); |
| } else if ( 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 */ |
| } else if ( pgn == pgn_general_purpose_valve_estimated_flow ) { |
| ISO_11783_RESPONSE_REQUEST_GENERAL_PURPOSE_VALVE_ESTIMATED_FLOW ( J1939 , SA ); |
| } else if ( pgn > = pgn_auxiliary_valve_measured_position_0 && pgn <= pgn_auxiliary_valve_measured_position_15 ) { |
| ISO_11783_RESPONSE_REQUEST_AUXILIARY_VALVE_MEASUED_POSITION ( J1939 , PGN & 0XF ); / * pgn & 0xf = valve_number */ |
| } else if ( pgn == pgn_software_identification ) { |
| SAE_J1939_RESPONSE_REQUEST_SOFTWARE_INGIFICATION ( J1939 , SA ); |
| } else if ( pgn == pgn_ecu_identification ) { |
| SAE_J1939_Response_Request_ecu_identification ( J1939 , SA ); |
- 4 단계 :
PGN 기능 코드는 이제 ECU Y 의 ECU Identification 으로 해석됩니다. 그런 다음 ECU Y ECU Identification 모든 ECUs 에 방송 할 것입니다.- 4.1.1 단계 : 1 패키지 메시지의 경우
ECU Y ECU Identification 방송 할 것입니다. | enum_J1939_STATUS_CODES SAE_J1939_RESPONSE_REQUEST_ECU_INGIFINSE ( J1939 * J1939 , UINT8_T DA ) { |
| / * 배열 필드의 길이 찾기 */ |
| uint8_t longth_of_each_field = j1939- > information_this_ecu . 이 _identifications . ecu_identification . longth_of_each_field ; |
| if ( longth_of_each_field < 2 ) { |
| / * 각 필드에 길이 1이 있으면 일반 메시지이므로 ECU 식별을 보낼 수 있습니다 */ |
| uint32_t id = ( 0x18fdc5 << 8 ) | J1939- > information_this_ecu . this_ecu_address ; |
| UINT8_T 데이터 [ 8 ]; |
| 데이터 [ 0 ] = J1939- > information_this_ecu . 이 _identifications . ecu_identification . ecu_part_number [ 0 ]; |
| 데이터 [ 1 ] = J1939- > information_this_ecu . 이 _identifications . ecu_identification . ecu_serial_number [ 0 ]; |
| 데이터 [ 2 ] = J1939- > information_this_ecu . 이 _identifications . ecu_identification . ecu_location [ 0 ]; |
| 데이터 [ 3 ] = J1939- > information_this_ecu . 이 _identifications . 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 Identification 방송되어 ECU Y 의 응답을 읽으십시오. | } else if ( id0 == 0x18 && id1 == 0xfd && da == 0xc5 ) { |
| SAE_J1939_READ_RESPONSE_REQUEST_ECU_INGIFINSE ( J1939 , SA , DATA ); |
- 4.2.1 단계 : 멀티 패키지 메시지의 경우 제어 바이트는 BAM 또는 RTS 일 수 있습니다. BAM은 모든
ECUs EG 주소 0xFF = 255 로 전송하는 경우에만 사용됩니다. 그러나 제어 바이트가 RTS 인 경우, 예를 들어 주소는 0xFF 아니며, ECU Y rts를 보내고 ECU X 의 CTS 응답을 듣게됩니다. RTS는 "메시지를 전송할 수있는시기를 알려주십시오."에 대한 질문입니다. 그리고 CTS는 Now you can transmit the message to me . | J1939- > this_ecu_tp_cm . Total_message_size = 0 ; |
| uint8_t i ; |
| for ( i = 0 ; i < longth_of_each_field ; i ++ ) { |
| J1939- > this_ecu_tp_dt . 데이터 [ i ] = j1939- > information_this_ecu . 이 _identifications . ecu_identification . ecu_part_number [ i ]; |
| J1939- > this_ecu_tp_dt . 데이터 [ longth_of_each_field + i ] = j1939- > information_this_ecu . 이 _identifications . ecu_identification . ecu_serial_number [ i ]; |
| J1939- > this_ecu_tp_dt . 데이터 [ longth_of_each_field * 2 + i ] = j1939- > information_this_ecu . 이 _identifications . ecu_identification . ecu_location [ i ]; |
| J1939- > this_ecu_tp_dt . 데이터 [ longth_of_each_field * 3 + i ] = j1939- > information_this_ecu . 이 _identifications . ecu_identification . ecu_type [ i ]; |
| J1939- > this_ecu_tp_cm . Total_message_size += 4 ; |
| } |
| |
| / * TP CM 보내기 */ |
| J1939- > this_ecu_tp_cm . 숫자 _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 제어 바이트를 사용하십시오 */ |
| enum_J1939_STATUS_CODES 상태 = SAE_JJ1939_SEND_TRANSPORT_PROTOCOL_CONNECTION_MANEMATIM ( J1939 , DA ); |
- 4.2.2 단계 :
ECU Y 가 RTS를 보내면 ECU X CTS로 RTS와 응답을 읽습니다 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 ; / * 우리는 제어 바이트를 RT에서 CTS로 변경하면됩니다 */ |
| SAE_J1939_SEND_TRANSPORT_PROTOCOL_CONNECTION_MANEMATIME ( 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 ) | ( da << 8 ) | J1939- > information_this_ecu . this_ecu_address ; |
| UINT8_T I , J , 패키지 [ 8 ]; |
| UINT16_T BYTES_SENT = 0 ; |
| enum_j1939_status_codes status = status_send_ok ; |
| for ( i = 1 ; i <= j1939- > this_ecu_tp_cm . number_of_packages ; i ++ ) { |
| 패키지 [ 0 ] = i ; / * 패키지 수 */ |
| for ( 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 ( id , package ); |
| can_delay ( 100 ); / * 표준에 따라 지연 될 수 있습니다 */ |
| if ( status ! = status_send_ok ) { |
| 반환 상태 ; |
| } |
| } |
| 반환 상태 ; |
| } |
- 단계 4.2.4 : 그런 다음
ECU X 각 패키지를 받고 PNG 기능 코드를 알고 메시지를 작성합니다. | void SAE_J1939_READ_RANSPORT_PROTOCOL_DATA_TRANSFER ( J1939 * J1939 , UINT8_T SA , UINT8_T DATA []) { |
| / * 시퀀스 데이터 저장 */ |
| j1939- > from_other_ecu_tp_dt . 시퀀스 _number = data [ 0 ]; |
| j1939- > from_other_ecu_tp_dt . from_ecu_address = sa ; |
| uint8_t i , j , index = data [ 0 ] -1 ; |
| for ( i = 1 ; i < 8 ; i ++ ) { |
| j1939- > from_other_ecu_tp_dt . 데이터 [ index * 7 + i -1 ] = 데이터 [ i ]; / * 모든 패키지에 대해 첫 바이트 데이터 [0]이 시퀀스 번호 */인 7 바이트의 데이터를 보냅니다. |
| } |
| / * 메시지를 완료했는지 확인하십시오 - return = 완료되지 않음 */ |
| if ( j1939- > from_other_ecu_tp_cm . number_of_packages ! = j1939- > from_other_ecu_tp_dt . sequence_number || j1939- > from_other_ecu_tp_cm . number_of_packages == 0 ) { |
| 반품 ; |
| } |
| |
| / * 우리의 메시지가 완료되었습니다 - 그것을 빌드하고 그것을 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 ; |
| for ( i = 0 ; i <j1939-> from_other_ecu_tp_dt . sequence_number ; i ++ ) { |
| for ( 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 Back */ |
| 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_identification : |
| SAE_J1939_READ_RESPONSE_REQUEST_ECU_INDIFICE ( J1939 , SA , Complete_Data ); |
| 부서지다 ; |
SAE J1939 기능
- SAE J1939 : 21 전송 층
- 승인
- 요구
- BAM, CTS, RTS 및 EOM과의 전송 프로토콜 연결 관리
- 전송 프로토콜 데이터 전송
- SAE J1939 : 71 애플리케이션 계층
- 구성 요소 식별 요청
- ECU 식별을 요청하십시오
- 소프트웨어 식별 요청
- 독점 요청 a
- 독점 요청 b
- SAE J1939 : 73 진단 계층
- DM1
- DM2
- DM3
- DM14
- DM15
- DM16
- SAE J1939 : 81 네트워크 관리 계층
- 청구 된 주소
- 명령 주소
- 청구되지 않은 주소
- 주소를 삭제하십시오
추가 기능
- ISO 11783 농업 및 임업을위한 트랙터 및 기계
- ISO 11783-7 구현 메시지 응용 프로그램 계층
- 보조 밸브 명령
- 보조 밸브 추정 흐름
- 보조 밸브 측정 위치
- 범용 밸브 명령
- 범용 밸브 추정 흐름
질문과 답변
- Q :이 라이브러리가
C++ 와 함께 사용할 수 있습니까?- A : 예
C++ 와 함께 사용할 수 있습니다
- Q :이 라이브러리를 구축하고 싶습니다. 어떻게해야합니까?
- A : 먼저
ANSI C (C89) 및 Bitwise 작업을 알아야합니다. 그런 다음 SAE J1939:21 Transport Layer 구조를 이해해야합니다. 새로운 기능으로 PDF를 업데이트하는 것을 잊지 마십시오.
- Q : Arduino에서 이것을 사용할 수 있습니까?
- A : 예,이
C 코드는 100% 순수한 C 코드이며 C 표준 라이브러리 만 사용하며 코드는 사용중인 하드웨어를 고려하지 않습니다.
- Q : 라이브러리를 사용하려면 라이브러리를 설치해야합니까?
- A : 아니요.
.c 및 .h 파일을 프로젝트에 복사하고 컴파일하면됩니다. 나는 이것을 QT 프레임 워크와 함께 사용했습니다.
- Q :이 프로젝트는 지금은 꽤 오래되었고 업데이트가 많지 않지만 여전히 사용해야합니까?
- A : 예,이 라이브러리는 저 또는 다른 사람이 SAE J1939의 더 많은 기능을 포함 할 때만 업데이트됩니다. 내가 이것을
ANSI C (C89) 로 쓴 이유는 업계 표준이기 때문에이 라이브러리를 컴파일하고 모든 시스템에서 사용할 수 있기 때문입니다.
- Q : 도서관과의 계획은 무엇입니까?
- A : SAE J1939를 모두에게 제공합니다
- Q : 캔 버스가 없지만 UART, USB, WiFi 등과 함께이 라이브러리를 사용할 수 있습니까?
- A : 그렇습니다. 이것은 특정 방식으로 메시지를 형성하는 방법 일뿐입니다.
- Q : CAN 버스가 없어도이 라이브러리로 데이터를 보낼 수 있습니까?
- A : 그렇습니다. DM14 전송 요청, DM15 상태 응답 및 DM16 이진 전송이라는 것이 있습니다. 산업적으로 데이터를 전송하려면 사용하십시오.
- Q : 다중 ECU에서 동시에 하나의 ECU로 멀티 패키지 메시지를 보낼 수 있습니까?
- A : 아니요. 여러 ECU에서 다른 ECU로 다중 패키지를 보내기 시작하면 ECU가 메시지를 이해할 수 없습니다. 대상 주소가 동일 한 경우 1 분만에 멀티 패키지 메시지 만 전송합니다.
- Q : Open SAE J1939와 함께
ANSI C (C89) 사용하고 싶지 않습니다. Open SAE J1939에서 최신 C 표준을 사용할 수 있습니까?- 예,이 라이브러리와 함께 최신 C 표준을 사용할 수 있습니다.
- Q :이 라이브러리를 Windows MS-DOS 또는 Windows 95 시스템에 컴파일 할 수 있습니까?
- C89 호환 컴파일러 및 IDE는 문제가되지 않아야합니다.
- Q : 프로그램에서 차지하는 메모리를 조정할 수 있습니까?
- A : 예, 사용 사례에 따라
Structs.h 파일의 MAX_PROPRIETARY_A , MAX_PROPRIETARY_B 및 MAX_PROPRIETARY_B_PGNS 정의를 조정할 수 있습니다. 'Sane'기본값이 제공되지만 독점적 인 PGNS 지원이 필요하지 않은 경우 최소로 설정하거나 더 많은 PGNS를 사용해야하는 경우 증가시킬 수 있습니다.
문제와 답변
- I :이 라이브러리를 컴파일 할 수 없습니다. 나는
Keil Microvision 사용하고 있습니다.- A :
Keil Microvision 0b010101 과 같은 이진 번호를 처리 할 수 없습니다. Open SAE J1939 STM32CubeIDE 에서 만들어 졌기 때문에 STM32CubeIDE 사용해보십시오.
- I :
STM32 와 같은 하드웨어 예제를 제공 할 수 있습니까?- A : 네! STM32 메시지의 인터럽트 리스너를 포함하여 CAN 버스와 연결하는 방법이 있습니다.
CAN_STM32.txt Examples -> Hardware 찾으십시오. 또한 QT C++ 에 대한 USB 예제도 있습니다.