Open SAE J1939
O SAE J1939 é um protocolo para moldar a mensagem CAN-Bus de uma maneira específica que se adapte a veículos industriais, como tratores, máquinas, caminhões e muito mais.
O SAE J1939 é um protocolo muito fácil de usar, mas há uma falta de informações sobre o SAE J1939, devido ao custo do documento do protocolo, disponível como moldar uma mensagem CAN-Bus de acordo com o padrão de protocolo SAE J1939. Portanto, estou escrevendo um protocolo SAE J1939 disponível gratuitamente para usar em qualquer sistema incorporado, como STM32, Arduino, AVR, Pic etc ou PC.
Para aprender a desenvolver esse projeto, você precisa primeiro entender o SAE J1939. Eu escrevi este projeto no idioma C porque C é um padrão do setor. O dialeto da linguagem C que escolhi é ANSI C (C89) e não uso a alocação de memória dinâmica nesta biblioteca. Portanto, funcionará com MISRA C Standard.
Com esta biblioteca, você pode se comunicar com válvulas, motores, atuadores, máquinas, hardware e todas as outras coisas adequadas para aplicações móveis industriais pesadas. Eu construo uma estrutura básica do projeto e espero que outros usuários enviem solicitação de puxar de seu código C para funcionalidade extra para o padrão J1939, porque o SAE J1939 é um padrão enorme.
Procurando C Biblioteca C Canopen para sistemas incorporados? https://github.com/danielmartensson/easy-canopen
Procurando uma estrutura C ++ GUI que use o SAE J1939 aberto sobre o USB? https://github.com/danielmartensson/goobysoft
Procurando um projeto C STM32 com o Open SAE J1939? https://github.com/danielmartensson/stm32-plc
Começando
A primeira coisa que você precisa saber é ler meu próprio documento PDF do Open SAE J1939 dentro da pasta Documentation . Aprenda a estrutura do projeto, caso contrário, você não poderá entender o SAE J1939. Depois de ter um entendimento básico do projeto, você poderá desenvolvê -lo. Mantenha -o simples e siga o padrão SAE J1939!
Depois de entender a estrutura do projeto, selecione a escolha do processador no arquivo de Hardware -> Hardware.h . Aqui você pode selecionar, por exemplo, STM32 , Arduino , PIC , AVR etc. ou se desejar executá -lo no PC primeiro, selecione PROCESSOR_CHOICE 0 e execute alguns exemplos. Esse é o modo de depuração para feedback da lata interna.
Como usar o projeto
- Etapa 1: Baixe este repositório
- Etapa 2: vá para
Hardware -> Hardware.h e selecione seu processador, se não estiver disponível, escreva o código para ele e envie -me uma solicitação de tração - Etapa 3: Copie a pasta
Src para a pasta do projeto dentro do seu IDE. Renomeie Src para, por exemplo, Open SAE J1939 . Esse é um bom nome. - Etapa 4: use os
Examples -> Open SAE J1939 -> Main.txt Exemplo como seu código inicial inicial para um projeto 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 ;
} Consulte os exemplos em Examples -> SAE J1939 Como alterar o endereço, nome ou identificações da sua ECU.
A estrutura do projeto
Um exemplo de funcionamento de como a estrutura do SAE J1939 é feito
Esse fluxograma no código como está funcionando a biblioteca SAE J1939. Este exemplo demonstra como enviar uma solicitação e obter uma resposta.
- Etapa 1:
ECU X vai enviar um PGN para a ECU Y Interprete PGN como um código de função. | Enum_j1939_status_codes SAE_J1939_SEND_REQUEST_ECU_IDENTIFICAÇÃO ( J1939 * J1939 , UINT8_T DA ) { |
| return sae_j1939_send_request ( j1939 , da , pgn_ecu_identification ); |
| } |
- Etapa 2:
ECU Y vai ler essa mensagem PGN da ECU X | bool is_new_message = can_read_message ( & id , dados ); |
| if ( is_new_message ) { |
| / * Salvar mais recente */ |
| J1939 -> id = id ; |
| Memcpy ( J1939 -> Dados , dados , 8 ); |
| j1939 -> id_and_data_is_updated = true; |
| |
| uint8_t id0 = id >> 24 ; |
| uint8_t id1 = id >> 16 ; |
| uint8_t da = id >> 8 ; /* Endereço de destino que é esta ECU. se da = 0xff = transmissão para toda a ECU. Às vezes, o DA também pode ser um número de identificação */ |
| uint8_t sa = id ; / * Endereço de origem da ECU de que recebemos a mensagem */ |
| |
| / * Leia a solicitação de outra ECU */ |
| if ( id0 == 0x18 && id1 == 0Xea && ( da == j1939 -> Information_this_ecu . this_ecu_address || da == 0xff )) { |
| Sae_j1939_read_request ( J1939 , SA , dados ); |
- Etapa 3: O código da função
PGN será interpretado pela ECU Y | void sae_j1939_read_request ( j1939 * j1939 , uint8_t SA , uint8_t data []) { |
| uint32_t pgn = ( dados [ 2 ] << 16 ) | ( Dados [ 1 ] << 8 ) | dados [ 0 ]; |
| if ( PGN == PGN_ACKNOWLEDGEMENT ) { |
| SAE_J1939_SEND_ACKNOWLEDGEMENT ( J1939 , SA , CONTROL_BYTE_ACKNOWLEDGEMENT_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_ACKNOWLEDGEMENT_PGN_SUPPORTED , GROUP_FUNCTION_VALUE_NORMAL , PGN ); |
| } else if ( pgn == pgn_address_delete ) { |
| SAE_J1939_SEND_ACKNOWLEDGEMENT ( J1939 , SA , CONTROL_BYTE_ACKNOWLEDGEMENT_PGN_SUPPORTED , GROUP_FUNCTION_VALUE_NORMAL , PGN ); / * Não SAE J1939 Padrão */ |
| } 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_ACKNOWLEDGEMENT_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_ACKNOWLEDGEMENT_PGN_SUPPORTED , GROUP_FUNCTION_VALUE_NORMAL , PGN ); |
| } else if ( pgn == pgn_tp_cm ) { |
| SAE_J1939_SEND_ACKNOWLEDGEMENT ( J1939 , SA , CONTROL_BYTE_ACKNOWLEDGEMENT_PGN_SUPPORTED , GROUP_FUNCTION_VALUE_NORMAL , PGN ); |
| } else if ( pgn == pgn_tp_dt ) { |
| SAE_J1939_SEND_ACKNOWLEDGEMENT ( J1939 , SA , CONTROL_BYTE_ACKNOWLEDGEMENT_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 = valvar_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_Measured_Position ( J1939 , PGN & 0XF ); / * Pgn & 0xf = valvar_number */ |
| } else if ( pgn == pgn_software_identification ) { |
| SAE_J1939_RESPONSE_REQUEST_SOFTWARE_IDENTIFICATION ( J1939 , SA ); |
| } else if ( pgn == pgn_ecu_identification ) { |
| SAE_J1939_RESPONSE_REQUEST_ECU_IDENTIFICATION ( J1939 , SA ); |
- Etapa 4: O código da função
PGN agora é interpretado como ECU Identification pelo ECU Y Então ECU Y vai transmitir a ECU Identification para todas ECUs .- Etapa 4.1.1: Para uma mensagem de pacote,
ECU Y vai transmitir a ECU Identification . | Enum_j1939_status_codes SAE_J1939_RESPONSE_REQUEST_ECU_IDENTIFICAÇÃO ( J1939 * J1939 , UINT8_T DA ) { |
| / * Encontre o comprimento dos campos de matriz */ |
| uint8_t length_of_each_field = j1939 -> Information_this_ecu . this_Identificações . ECU_IDENTIFICAÇÃO . comprimento_of_each_field ; |
| if ( comprimento_of_each_field < 2 ) { |
| / * Se cada campo tiver o comprimento 1, podemos enviar a identificação da ECU, pois era uma mensagem normal */ |
| uint32_t id = ( 0x18fdc5 << 8 ) | J1939 -> Information_this_ecu . this_ecu_address ; |
| dados uint8_t [ 8 ]; |
| dados [ 0 ] = J1939 -> Information_this_ecu . this_Identificações . ECU_IDENTIFICAÇÃO . ECU_PART_NUMBER [ 0 ]; |
| dados [ 1 ] = J1939 -> Information_this_ecu . this_Identificações . ECU_IDENTIFICAÇÃO . ecu_serial_number [ 0 ]; |
| dados [ 2 ] = J1939 -> Information_this_ecu . this_Identificações . ECU_IDENTIFICAÇÃO . ecu_location [ 0 ]; |
| Dados [ 3 ] = J1939 -> Information_this_ecu . this_Identificações . ECU_IDENTIFICAÇÃO . ECU_TYPE [ 0 ]; |
| dados [ 4 ] = 0xff ; / * Reservado */ |
| dados [ 5 ] = 0xff ; / * Reservado */ |
| dados [ 6 ] = 0xff ; / * Reservado */ |
| dados [ 7 ] = 0xff ; / * Reservado */ |
| retornar can_send_message ( id , dados ); |
| } outro { |
- Etapa 4.1.2:
ECU X Leia a resposta da ECU Y porque a ECU Identification é transmitida. | } else if ( id0 == 0x18 && id1 == 0xfd && da == 0xc5 ) { |
| SAE_J1939_READ_RESPONSE_REQUEST_ECU_IDENTIFICATION ( J1939 , SA , Data ); |
- Etapa 4.2.1: Para uma mensagem multi -pacote, o byte de controle pode ser BAM ou RTS. O BAM é usado apenas se você enviar para todo o endereço
ECUs , por exemplo 0xFF = 255 . Mas se o byte de controle for RTS, o endereço, por exemplo, não será 0xFF , ECU Y enviará um RTS e ouvirá uma resposta do CTS pelo ECU X RTS é uma pergunta para "avise -me quando posso transmitir a mensagem?" E o CTS é resposta Now you can transmit the message to me . | J1939 -> this_ecu_tp_cm . total_message_size = 0 ; |
| uint8_t i ; |
| for ( i = 0 ; i < length_of_each_field ; i ++ ) { |
| J1939 -> this_ecu_tp_dt . dados [ i ] = J1939 -> Information_this_ecu . this_Identificações . ECU_IDENTIFICAÇÃO . ecu_part_number [ i ]; |
| J1939 -> this_ecu_tp_dt . Data [ comprimento_of_each_field + i ] = J1939 -> Information_this_ecu . this_Identificações . ECU_IDENTIFICAÇÃO . ecu_serial_number [ i ]; |
| J1939 -> this_ecu_tp_dt . Data [ comprimento_of_each_field * 2 + i ] = J1939 -> Information_this_ecu . this_Identificações . ECU_IDENTIFICAÇÃO . ecu_location [ i ]; |
| J1939 -> this_ecu_tp_dt . dados [ comprimento_of_each_field * 3 + i ] = j1939 -> Information_this_ecu . this_Identificações . ECU_IDENTIFICAÇÃO . ecu_type [ i ]; |
| J1939 -> this_ecu_tp_cm . total_message_size += 4 ; |
| } |
| |
| / * Envie tp cm */ |
| J1939 -> this_ecu_tp_cm . número_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 ; / * Arredondando */ |
| 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 ; / * Se transmitida, use Bam Control Byte */ |
| Enum_j1939_status_codes status = sae_j1939_send_transport_protocol_connection_management ( j1939 , da ); |
- Etapa 4.2.2: Se
ECU Y estiver enviando um RTS, ECU X lerá os RTs e a resposta com o CTS de volta ao ECU Y | if ( j1939 -> from_other_ecu_tp_cm . Control_byte == CONTROL_BYTE_TP_CM_RTS ) { |
| J1939 -> this_ecu_tp_cm = j1939 -> de_other_ecu_tp_cm ; / * Cópia - precisamos ter os mesmos dados */ |
| J1939 -> this_ecu_tp_cm . control_byte = control_byte_tp_cm_cts ; / * Precisamos apenas alterar o byte de controle de RTS para CTS */ |
| SAE_J1939_SEND_TRANSPORT_PROTOCOL_CONNECTION_MANGANGENTE ( J1939 , SA ); |
| } |
- Etapa 4.2.3: Depois que
ECU Y recebe o CTS, ele transmitirá os dados, neste caso ECU Identification , de volta ao 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 ); |
| } |
- Etapa 4.2.3: Depois que
ECU Y estiver enviando pacote após o pacote ... | 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 , pacote [ 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 ++ ) { |
| pacote [ 0 ] = i ; / * Número de pacote */ |
| for ( j = 0 ; j < 7 ; j ++ ) { |
| if ( bytes_sent < j1939 -> this_ecu_tp_cm . total_message_size ) { |
| pacote [ j + 1 ] = j1939 -> this_ecu_tp_dt . dados [ bytes_sent ++ ]; / * Dados que coletamos */ |
| } outro { |
| pacote [ j + 1 ] = 0xff ; / * Reservado */ |
| } |
| } |
| status = can_send_message ( id , pacote ); |
| Can_delay ( 100 ); / * Importante pode atrasar de acordo com o padrão */ |
| if ( status ! = status_send_ok ) { |
| status de retorno ; |
| } |
| } |
| status de retorno ; |
| } |
- Etapa 4.2.4: Então
ECU X está recebendo cada pacote e criando a mensagem conhecendo o código da função PNG . | void sae_j1939_read_transport_protocol_data_transfer ( j1939 * j1939 , uint8_t SA , uint8_t data []) { |
| / * Salvar os dados da sequência */ |
| J1939 -> From_other_ecu_tp_dt . sequence_number = dados [ 0 ]; |
| J1939 -> From_other_ecu_tp_dt . from_ecu_address = SA ; |
| uint8_t i , j , index = dados [ 0 ] - 1 ; |
| para ( i = 1 ; i < 8 ; i ++ ) { |
| J1939 -> From_other_ecu_tp_dt . dados [ índice * 7 + i - 1 ] = dados [ i ]; / * Para cada pacote, enviamos 7 bytes de dados em que os primeiros dados de bytes [0] são o número da sequência */ |
| } |
| / * Verifique se concluímos nossa mensagem - return = não concluído */ |
| if ( j1939 -> de_other_ecu_tp_cm . number_of_packages ! = j1939 -> de_other_ecu_tp_dt . sequence_number || j1939 -> de_other_ecu_tp_cm . number_of_packages == 0 ) { |
| retornar ; |
| } |
| |
| / * Nossa mensagem está completa - crie -a e chame -a complete_data [total_message_size] */ |
| uint32_t pgn = j1939 -> de_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 inserd_bytes = 0 ; |
| for ( i = 0 ; i < j1939 -> de_other_ecu_tp_dt . sequence_number ; i ++ ) { |
| for ( j = 0 ; j < 7 ; j ++ ) { |
| if ( insered_bytes < total_message_size ) { |
| complete_data [ inserd_bytes ++ ] = j1939 -> de_other_ecu_tp_dt . dados [ i * 7 + j ]; |
| } |
| } |
| } |
| |
| / * Envie um fim da mensagem ack de volta */ |
| 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 ); |
| } |
E finalmente implemente a mensagem. | CASE PGN_ECU_IDENTIFICATION : |
| SAE_J1939_READ_RESPONSE_REQUEST_ECU_IDENTIFICATION ( J1939 , SA , FELLE_DATA ); |
| quebrar ; |
SAE J1939 funcionalidade
- SAE J1939: 21 Camada de transporte
- Reconhecimento
- Solicitar
- Gerenciamento de conexão de protocolo de transporte com BAM, CTS, RTS e EOM
- Transferência de dados do protocolo de transporte
- SAE J1939: 71 Camada de aplicação
- Solicitar identificação de componentes
- Solicite identificação da ECU
- Solicitar identificação de software
- Solicitar proprietário a
- Solicitar proprietário b
- SAE J1939: 73 Camada de diagnóstico
- DM1
- DM2
- DM3
- DM14
- DM15
- DM16
- SAE J1939: 81 Camada de gerenciamento de rede
- Endereço reivindicado
- Endereço comandado
- Endereço não reivindicado
- Excluir endereço
Funcionalidade extra
- ISO 11783 Tratores e máquinas para agricultura e silvicultura
- ISO 11783-7 Implementar mensagens Aplicativo Camada de aplicativos
- Comando auxiliar da válvula
- Fluxo estimado da válvula auxiliar
- Posição Medida pela Válvula Auxiliar
- Comando de válvula de uso geral
- Fluxo estimado da válvula de uso geral
Perguntas e respostas
- P: Esta biblioteca pode ser usada com
C++ ?- A: Sim, pode ser usado com
C++
- P: Eu quero construir nesta biblioteca, o que devo fazer?
- R: Primeiro, você precisa conhecer as operações
ANSI C (C89) e Bitwise. Então você precisa entender a estrutura SAE J1939:21 Transport Layer . Não se esqueça de atualizar o PDF com sua nova funcionalidade.
- P: Posso usar isso no meu Arduino?
- R: Sim, esse código
C é 100% puro C código e apenas usando a biblioteca padrão C e também o código não leva em consideração qual hardware você está usando.
- P: Preciso instalar a biblioteca para usar a biblioteca?
- A: Não, basta copiar os arquivos
.c e .h para o seu projeto e compilar. Eu usei isso com a estrutura QT.
- P: Este projeto é bastante antigo agora e não tantas atualizações, ainda vale a pena usá -lo?
- R: Sim, esta biblioteca apenas atualiza quando eu ou outro inclui mais funcionalidades do SAE J1939. A razão pela qual escrevi isso na
ANSI C (C89) é porque é um padrão do setor e você sempre poderá compilar essa biblioteca e usá -la em todos os sistemas.
- P: Qual é o seu plano com a biblioteca?
- R: Para disponibilizar o SAE J1939 para todos
- P: Eu não tenho Can-Bus, mas posso usar esta biblioteca de qualquer maneira com UART, USB, WIFI etc?
- A: Sim. Esta é apenas uma maneira de moldar uma mensagem de uma maneira específica.
- P: Posso enviar dados com esta biblioteca, mesmo que eu não tenha o pode-se?
- A: Sim. Há algo chamado Solicitação de Transmissão DM14, resposta do status DM15 e transferência binária DM16. Use isso se você deseja transferir dados de maneira industrial.
- P: Posso enviar mensagens multi -pacote de vários ECUs para uma ECU ao mesmo tempo?
- R: Não. Se você começar a enviar multipackages de vários ECUs para outra ECU, essa ECU não poderá entender a mensagem. Transmitir apenas mensagens multipackage uma no momento se o endereço de destino for o mesmo.
- P: Não quero usar
ANSI C (C89) com o SAE J1939 aberto. Posso usar o padrão C mais recente com o Open SAE J1939?- Sim, você pode usar o padrão C mais recente com esta biblioteca.
- P: É possível compilar esta biblioteca em uma máquina Windows MS-DOS ou Windows 95?
- Um compilador compatível com C89 e um IDE e não deve ser nenhum problema
- P: Posso ajustar a memória ocupada pelo programa?
- A
MAX_PROPRIETARY_B_PGNS Sim, você Structs.h ajustar o MAX_PROPRIETARY_B MAX_PROPRIETARY_A Um valor padrão 'sã' é fornecido, mas você pode defini -los no mínimo se o suporte proprietário do PGNS não for necessário ou aumentá -lo se mais PGNs precisar ser usados.
Questões e respostas
- I: Não posso compilar esta biblioteca. Estou usando
Keil Microvision .- R:
Keil Microvision não pode lidar com números binários como 0b010101 . Experimente STM32CubeIDE porque Open SAE J1939 é fabricado no STM32CubeIDE
- I: Você pode nos fornecer alguns exemplos de hardware, por exemplo,
STM32 ?- A: Sim! Há um exemplo do STM32 como obter conexão com o Can-Bus, incluindo um ouvinte de interrupção para mensagens. Vá para
Examples -> Hardware para procurar CAN_STM32.txt . Também há um exemplo USB também para QT C++ .