LinkedIn YouTube Facebook
Szukaj

Newsletter

Proszę czekać.

Dziękujemy za zgłoszenie!

Wstecz
Artykuły

CAN od zera część 1: Jak przesłać dane między CAN1, a CAN2 w STM32 bez użycia transceivera?

W artykule przedstawię implementację protokołu CAN na procesorze STM32G4, uwzględniając i tłumacząc filtry programowe, pokażę jak przesłać informację pomiędzy CAN1 i CAN2 używając jednego procesora, a to wszystko bez użycia transceivera.

Czasem chcemy przetestować działanie magistrali CAN lub filtrów programowych bez konieczności użycia dwóch osobnych płytek lub dodatkowych transceiverów. Taki testowy setup pozwala zweryfikować poprawność konfiguracji CAN w STM32 oraz logikę aplikacji przed wdrożeniem sprzętowym.

Przedstawienie schematu podłączenia:

Połączony układ wygląda następująco:

Rys. 1. Podłączony układ w rzeczywistości

Działanie układu:

Konfiguracja pinów:

CAN1_Tx oraz CAN2_Tx są wyjściami typu push-pull, dlatego potrzebne są diody zabezpieczające.
CAN1_Rx oraz CAN2_Rx skonfigurowane są jako wejścia AF (Alternate Function) bez pull-up oraz bez pull-down.

Zasada działania:

CAN na warstwie fizycznej rozróżnia stan dominujący (logiczne 0) i recesywny (logiczna 1). W normalnej magistrali robi to transceiver różnicowy (CAN_H/CAN_L). Tutaj transceiver jest pominięty, za to uzyskujemy zachowanie podobne do magistrali open-drain:

  • Diody separujące zabezpieczają wyjścia przed sytuacją, gdzie na jednym z CAN_Tx byłby stan niski, a na drugim stan wysoki. Taka sytuacja doprowadziłaby do uszkodzenia wyjść CAN_Tx mikrokotrolera.
  • Rezystor podciągający ustala pasywnie stan recesywny, poprzez podciągnięcie wspólnej linii do 3.3V.
  • Kiedy któryś CAN_Tx chce nadać bit dominujący, jego wyjście ciągnie linię do zera, przez diodę przepływa prąd do masy i wspólny punkt zostaje sprowadzony do niskiego poziomu.

Dlaczego RX odbiera poprawnie?

Peryferium CAN w STM32 oczekuje sygnału z transceivera w postaci jednokanałowego poziomu logicznego: niski – dominujący, wysoki – recesywny. W tym układzie wspólny węzeł daje taki właśnie poziom (podciągnięty = 1, ściągnięty do 0 = 0), więc kanał Rx widzi poprawne stany i dekoduje ramki poprawnie.

Analiza przebiegu:

Na poniższym przebiegu przedstawiłem na kanale 0 sygnał na katodzie diody CAN1_Tx, zaś na kanale 1 przedstawiłem sygnał na liniach Rx. Jak widać na przebiegu sygnał CAN dekodowany jest poprawnie.

Konfiguracja procesora w środowisku CubeIDE:

Na początku zacznę od przedstawienia konfiguracji procesora jakiej użyję we wpisie w środowisku CubeIDE:

Konfiguracja CAN1:

Konfiguracja przerwania CAN1:

Konfiguracja CAN2:

Włączenie przerwania CAN2:

Filtry programowe CAN:

Protokół CAN jest komunikacją rozproszeniową, czyli wszystkie urządzenie podpięte do jednej magistrali otrzymują dane. W takim razie w jaki sposób urządzenia wiedzą, że informacje są przekazywane właśnie do nich? Z pomocą przychodzą filtry programowe zaimplementowane w programie. Peryferium CAN reaguje na ramkę o określonym ID, które to ID jest zgodne z ustawionymi filtrami.

Filtry jakie można wybrać podczas konfiguracji CAN w FilterType:

  • RANGE FILTER – czyli ramki z zakresu od ID1 do ID2 będą uwzględniane. Służy do testów lub prostych przypadków,
  • MASK FILTER – ID1 to wzorzec ID, ID2 to maska bitowa. Jeśli jest bit 1 w masce, wtedy dany bit jest porównywany, jeśli w masce jest bit 0 wtedy bit jest ignorowany. Przepuszczane są ramki które na konkretnych maski jest 1 logiczna, a ramka przychodząca ma tą samą wartość jak wzorzec ID1. Najlepszy filtr, gdy chcemy odbierać grupy ramek o wspólnym prefiksie ID,
  • DUAL FILTER – dla ramek o dwóch ID równych ID1 lub ID2. Najlepszy, gdy chcemy odebrać konkretne dwa ID bez pisania osobnych filtrów,
  • RANGE FILTER NO EIDM – działa tak samo jak range filter, lecz ignoruje bit (IDE) określający czy ramka jest standardowej długości czy rozszerzonej. Ten filtr jest przydatny, gdy system pracuje z mieszanymi ramkami: standardowymi i rozszerzonymi, a użytkownik chce filtrować ramki tylko po numerze ID.


Kod:

Callback od CAN1:



Callback od CAN2:



Nagłówek ramki CAN1 oraz CAN2:



Główna pętla programu:



Prezentacja funkcjonowania układu:

CAN1 wysyła informacje na temat częstotliwości i ilości mrugnięć diodą do CAN2 po naciśnięciu przycisku. CAN2 odbiera dane o częstotliwości i ilości mrugnięć diodą. Dalej następują mrugnięcia diodą z określoną częstotliwością i określoną ilością razy.

Uwagi praktyczne:

Na co uważać przy testach bez transceivera?

  • Linie CAN_TX i CAN_RX w STM32 są CMOS, więc nie mają odporności na zakłócenia ani zabezpieczeń ESD.
  • Działa tylko w krótkim połączeniu (na tej samej płytce).
  • W realnym zastosowaniu zawsze wymagany jest transceiver (np. TJA1051, MCP2551, SN65HVD230).

Podsumowanie:

W artykule przedstawiłem prosty, testowy sposób na implementację protokołu CAN, kiedy pod ręką nie mamy transceivera oraz dysponujemy tylko jednym procesorem. W kolejnych pokażę, jak dołączyć zewnętrzny transceiver i komunikować się między dwoma różnymi mikrokontrolerami STM32 po magistrali CAN.

Artykuł powstał jako część wewnętrznych testów i eksperymentów z komunikacją CAN w STM32.


[1] Dostęp w Internecie

Źródło: DMPB

Autor: Mateusz Pluta
Absolwent Politechniki Warszawskiej, specjalizujący się w elektronice przemysłowej. Zainteresowany zagadnieniami z zakresu hardware’u, w szczególności szybkimi interfejsami, kompatybilnością elektromagnetyczną oraz przekształtnikami energoelektronicznymi. Na blogu DMBP dzieli się wiedzą techniczną wynikającą z pasji i doświadczenia.