Procure pelo erro FDCAN que não é

Sempre trabalhando com o CAN era simples, mas algo deu errado (no dispositivo no KDPV) ...

imagem

Recentemente, muitas vezes eu consigo usar o microcontrolador STM32H750VB e em um dispositivo eu precisava usar o barramento CAN, mas a primeira tentativa que fiz mostrou toda a minha autoconfiança deu um resultado estranho. A história é descrita abaixo.

Então, primeiro sobre circuitos. No KDPV, ele é circulado em verde, é claro, o culpado é o microcontrolador, não há nada complicado com o CAN - ele é conectado de acordo com

imagem

O MAX3051 é usado como camada física (bem, eu gosto ..), assim:

imagem

Anteriormente, em vez do STM32H750VB, o STM32F107 estava no mesmo sistema, mas o velho não conseguia lidar com as tarefas e foi decidido substituí-lo por um mais moderno e jovem .

Mas aqui está a má sorte - o microcontrolador antigo possuía o bxCAN e o novo já possuía o FDCAN. Embora existam diferenças, mas do ponto de vista do código (e trabalho - os dispositivos no barramento são antigos): a substituição é muito simples. Para quem desejar, você pode comparar:
WasTornou-se
  MX_CAN1_Init (); 
  MX_FDCAN1_Init (); 
     hcan1.Instance = CAN1;
     hcan1.Init.Prescaler = 4;
     hcan1.Init.Mode = CAN_MODE_NORMAL;
     hcan1.Init.SyncJumpWidth = CAN_SJW_4TQ;
     hcan1.Init.TimeSeg1 = CAN_BS1_15TQ;
     hcan1.Init.TimeSeg2 = CAN_BS2_2TQ;
     hcan1.Init.TimeTriggeredMode = DISABLE;
     hcan1.Init.AutoBusOff = ENABLE;
     hcan1.Init.AutoWakeUp = DISABLE;
     hcan1.Init.AutoRetransmission = DISABLE;
     hcan1.Init.ReceiveFifoLocked = DISABLE;
     hcan1.Init.TransmitFifoPriority = DISABLE; 
   hfdcan1.Instance = FDCAN1;
   hfdcan1.Init.FrameFormat = FDCAN_FRAME_FD_NO_BRS;
   hfdcan1.Init.Mode = FDCAN_MODE_NORMAL;
   hfdcan1.Init.AutoRetransmission = ENABLE;
   hfdcan1.Init.TransmitPause = DISABLE;
   hfdcan1.Init.ProtocolException = ENABLE;
   hfdcan1.Init.NominalPrescaler = 1;
   hfdcan1.Init.NominalSyncJumpWidth = 3;
   hfdcan1.Init.NominalTimeSeg1 = 11;
   hfdcan1.Init.NominalTimeSeg2 = 4;
   hfdcan1.Init.DataPrescaler = 1;
   hfdcan1.Init.DataSyncJumpWidth = 3;
   hfdcan1.Init.DataTimeSeg1 = 11;
   hfdcan1.Init.DataTimeSeg2 = 4;
   hfdcan1.Init.MessageRAMOffset = 64;
   hfdcan1.Init.StdFiltersNbr = 0;
   hfdcan1.Init.ExtFiltersNbr = 0;
   hfdcan1.Init.RxFifo0ElmtsNbr = 4;
   hfdcan1.Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_8;
   hfdcan1.Init.RxFifo1ElmtsNbr = 4;
   hfdcan1.Init.RxFifo1ElmtSize = FDCAN_DATA_BYTES_8;
   hfdcan1.Init.RxBuffersNbr = 4;
   hfdcan1.Init.RxBufferSize = FDCAN_DATA_BYTES_8;
   hfdcan1.Init.TxEventsNbr = 4;
  if (HAL_CAN_Init (& hcan1)! = HAL_OK) { 
  if (HAL_FDCAN_Start (& hfdcan1)! = HAL_OK) { 

Em geral, diferenças cosméticas. E me pareceu que funcionaria de uma só vez e corretamente.

No entanto, não funcionou imediatamente ...

O controlador CAN não pôde definir um nível dominante e entrou no estado Bus-Off, e nenhum dado foi recebido do barramento (apesar do fato de outro dispositivo no barramento enviar pacotes de forma estável duas vezes por segundo).

Bem, pensei, a linha de depuração chegou e soldou a fiação nas linhas CAN-RX e CAN-TX (na verdade, visualizar o próprio barramento parecia lógico - o dispositivo estava silencioso e o outro dispositivo conectado enviou pacotes , conforme acordado ).

Depois disso, o modo FDCAN_MODE_BUS_MONITORING foi ativado pela primeira vez. E eis que vi imediatamente pacotes do ônibus! (Nesse modo, o controlador CAN apenas escuta dados, mas não transmite nada). Tão bom ...

Em seguida, o modo FDCAN_MODE_EXTERNAL_LOOPBACK foi ativado (nesse modo, pelo contrário, apenas ouvimos a nós mesmos, mas depois transferimos tudo para o barramento). E nas linhas CAN_RX e CAN_TX todos os pacotes de dados apareceram - ambos enviados pelo próprio dispositivo e recebidos do barramento, aqui em
Na figura abaixo (dados em cinza TX do microcontrolador, linha de dados laranja RX), eles são visíveis como picos:

imagem

Assim, após esse experimento, ficou claro que o circuito está funcionando corretamente, o controlador CAN no microprocessador pode receber e transmitir dados.

No entanto, ao tentar receber e transmitir dados simultaneamente, o sistema ainda se tornou Bus-Off com um erro no registro de controle de erros (registro de status do protocolo FDCAN (FDCAN_PSR)) LEC [2: 0] = 5 - o que significa da folha de dados Bit0Error: a transmissão de uma mensagem (ou bit de reconhecimento ou erro ativo
flag ou overload flag), o dispositivo queria enviar um nível dominante (bit de dados ou identificador)
valor lógico 0), mas o valor do barramento monitorado era recessivo ...

Após dois dias de tormento (está claro qual é o erro, mas não está claro como corrigi-lo) e um estudo cuidadoso da folha de dados, erratas e um monte de códigos e manuais de terceiros, a iluminação chegou ao meu entendimento - estou fazendo tudo certo, mas não está funcionando!

Bem, pensei, talvez o problema esteja na tecnologia e ... substituiu o próprio microcontrolador (por outro do mesmo lote). E ... funcionou! Bem, isto é, aqui sem dançar com um pandeiro de problemas, com o código fonte e como deve ser a primeira vez.

Breve resumo


Aparentemente, um espécime tão astuto apareceu. Mas, por outro lado, consegui me aprofundar no trabalho da FDCAN em geral, que pode ser atribuído às vantagens. E aos pontos negativos ... E a eles pode ser atribuído o tempo perdido (o controlador pôde ser anexado a outro projeto) e o entendimento de que os controladores modernos são buggy com força terrível também é moderno (ou é também uma vantagem?).

Source: https://habr.com/ru/post/pt483590/


All Articles