klasa CAN – magistrala komunikacyjna controller area network¶
CAN zapewnia obsługę zarówno klasycznego CAN (bxCAN, używanego w OpenMV Cam M4 i M7), jak i CAN FD (FDCAN, używanego w OpenMV Cam H7, H7 Plus i Pure Thermal). Na poziomie fizycznym magistrala CAN składa się z dwóch linii, RX i TX. Aby podłączyć OpenMV Cam do magistrali CAN, należy użyć transceivera CAN, który przekształca logiczne sygnały CAN z MCU na właściwe poziomy napięć na magistrali.
Klasyczny CAN w trybie pętli zwrotnej (loopback, bez transceivera):
from pyb import CAN
can = CAN(1, CAN.LOOPBACK)
# Accept messages with id 123, 124, 125 or 126.
can.setfilter(0, CAN.LIST16, 0, (123, 124, 125, 126))
can.send("message!", 123) # send a message with id 123
can.recv(0) # receive a message on FIFO 0
CAN FD ze wszystkimi opcjonalnymi funkcjami włączonymi (ramka FD, przełączanie szybkości transmisji, rozszerzone identyfikatory ramek; faza arbitrażu 500 kbit/s, faza danych 1 Mbit/s):
from pyb import CAN
can = CAN(
1,
CAN.NORMAL,
baudrate=500_000,
brs_baudrate=1_000_000,
sample_point=80,
)
# Accept any id in the range 0xFFF0 .. 0xFFFF.
can.setfilter(0, CAN.RANGE, 0, (0xFFF0, 0xFFFF))
can.send(b"a" * 64, 0xFFFF, fdf=True, brs=True, extframe=True)
can.recv(0)
Następujące funkcje modułu CAN oraz ich argumenty są dostępne zarówno dla klasycznych kontrolerów CAN, jak i FD CAN, o ile nie zaznaczono inaczej.
Konstruktory¶
- class pyb.CAN(bus: int | str, *args, **kwargs)¶
Tworzy obiekt CAN na danej magistrali
bus(całkowity indeks urządzenia peryferyjnego, np.1dlaCAN1,2dlaCAN2). Bez dodatkowych parametrów obiekt jest tworzony, ale nie inicjalizowany (zachowuje poprzednie ustawienia magistrali, jeśli istnieją); jeśli podano dodatkowe argumenty, magistrala jest inicjalizowana. Dostępne parametry opisujeCAN.init().CAN(2)jest podłączony do tych samych pinów złącza w każdym OpenMV Cam, który udostępniapyb.CAN(M4 / M7 / H7 / H7 Plus / Pure Thermal):Sygnał
Pin złącza
Uwagi
RXP3TXP2Urządzenie peryferyjne CAN dostarcza wyłącznie sygnały na poziomie logicznym; do sterowania rzeczywistą magistralą CAN wymagany jest zewnętrzny transceiver CAN.
pyb.CANnie jest dostępny w OpenMV Cam N6.Metody¶
- init(mode: int, prescaler: int = 100, *, sjw: int = 1, bs1: int = 6, bs2: int = 8, auto_restart: bool = False, baudrate: int = 0, sample_point: int = 75, num_filter_banks: int = 14, brs_sjw: int = 1, brs_bs1: int = 8, brs_bs2: int = 3, brs_baudrate: int = 0, brs_sample_point: int = 75) None¶
Inicjalizuje magistralę CAN z podanymi parametrami:
mode przyjmuje jedną z wartości: NORMAL, LOOPBACK, SILENT, SILENT_LOOPBACK
prescaler to wartość, przez którą dzielony jest zegar wejściowy CAN w celu wygenerowania nominalnych kwantów czasu bitu. Preskaler może przyjmować wartość od 1 do 1024 włącznie dla klasycznego CAN oraz od 1 do 512 włącznie dla CAN FD.
sjw to szerokość skoku resynchronizacji w jednostkach kwantów czasu dla bitów nominalnych; może przyjmować wartość od 1 do 4 włącznie dla klasycznego CAN oraz od 1 do 128 włącznie dla CAN FD.
bs1 określa położenie punktu próbkowania w jednostkach kwantów czasu dla bitów nominalnych; może przyjmować wartość od 1 do 16 włącznie dla klasycznego CAN oraz od 2 do 256 włącznie dla CAN FD.
bs2 określa położenie punktu transmisji w jednostkach kwantów czasu dla bitów nominalnych; może przyjmować wartość od 1 do 8 włącznie dla klasycznego CAN oraz od 2 do 128 włącznie dla CAN FD.
auto_restart ustala, czy kontroler będzie automatycznie próbował wznowić komunikację po wejściu w stan bus-off; jeśli jest to wyłączone, do opuszczenia stanu bus-off można użyć metody
restart()baudrate jeśli podana zostanie szybkość transmisji inna niż 0, funkcja spróbuje automatycznie obliczyć nominalny czas bitu CAN (nadpisując prescaler, bs1 i bs2), który spełnia jednocześnie baudrate (z dokładnością do 0,1%) oraz pożądany sample_point (z dokładnością do najbliższego 1%). Aby uzyskać dokładniejszą kontrolę nad taktowaniem CAN, ustaw bezpośrednio parametry prescaler, bs1 i bs2.
sample_point określa położenie próbkowania bitu względem całego nominalnego czasu bitu, wyrażone jako całkowita wartość procentowa nominalnego czasu bitu. Domyślny sample_point wynosi 75%. Ten parametr jest ignorowany, chyba że ustawiono baudrate.
num_filter_banks dla klasycznego CAN to liczba banków, które zostaną przypisane do CAN(1), a pozostałe z 28 zostaną przypisane do CAN(2).
Pozostałe parametry występują tylko na płytkach z obsługą CAN FD i konfigurują opcjonalną funkcję przełączania szybkości transmisji CAN FD (Bit Rate Switch, BRS):
brs_prescaler to wartość, przez którą dzielony jest zegar wejściowy CAN FD w celu wygenerowania kwantów czasu bitu danych. Preskaler może przyjmować wartość od 1 do 32 włącznie.
brs_sjw to szerokość skoku resynchronizacji w jednostkach kwantów czasu dla bitów danych; może przyjmować wartość od 1 do 16 włącznie
brs_bs1 określa położenie punktu próbkowania w jednostkach kwantów czasu dla bitów danych; może przyjmować wartość od 1 do 32 włącznie
brs_bs2 określa położenie punktu transmisji w jednostkach kwantów czasu dla bitów danych; może przyjmować wartość od 1 do 16 włącznie
brs_baudrate jeśli podana zostanie szybkość transmisji inna niż 0, funkcja spróbuje automatycznie obliczyć czas bitu danych CAN (nadpisując brs_prescaler, brs_bs1 i brs_bs2), który spełnia jednocześnie brs_baudrate (z dokładnością do 0,1%) oraz pożądany brs_sample_point (z dokładnością do najbliższego 1%). Aby uzyskać dokładniejszą kontrolę nad taktowaniem BRS, ustaw bezpośrednio parametry brs_prescaler, brs_bs1 i brs_bs2.
brs_sample_point określa położenie próbkowania bitu względem całego nominalnego czasu bitu, wyrażone jako całkowita wartość procentowa nominalnego czasu bitu. Domyślny brs_sample_point wynosi 75%. Ten parametr jest ignorowany, chyba że ustawiono brs_baudrate.
Kwant czasu tq jest podstawową jednostką czasu dla magistrali CAN. tq to wartość preskalera CAN podzielona przez PCLK1 (częstotliwość wewnętrznej magistrali peryferyjnej 1); zobacz
pyb.freq(), aby ustalić PCLK1.Pojedynczy bit składa się z segmentu synchronizacji, który zawsze wynosi 1 tq. Następnie występuje segment bitu 1, a po nim segment bitu 2. Punkt próbkowania znajduje się po zakończeniu segmentu bitu 1. Punkt transmisji znajduje się po zakończeniu segmentu bitu 2. Szybkość transmisji będzie wynosić 1/bittime, gdzie bittime to 1 + BS1 + BS2 pomnożone przez kwant czasu tq.
Na przykład w OpenMV Cam H7 (PCLK1 = 100 MHz) CAN 250 kbps z punktem próbkowania 75% można skonfigurować jako
prescaler=25, sjw=1, bs1=11, bs2=4:tq = 25 / 100 MHz = 250 ns,bittime = (1 + 11 + 4) × 250 ns = 4 µs, punkt próbkowania =(1 + 11) / 16 = 75%, a szybkość transmisji wynosi1 / 4 µs = 250 kHz.Więcej szczegółów znajduje się w sekcji bxCAN / FDCAN w podręczniku referencyjnym STM32 dla MCU danego OpenMV Cam.
- restart() None¶
Wymusza programowe ponowne uruchomienie kontrolera CAN bez resetowania jego konfiguracji.
Jeśli kontroler wejdzie w stan bus-off, nie będzie już uczestniczył w aktywności magistrali. Jeśli kontroler nie jest skonfigurowany do automatycznego restartu (zobacz
init()), tej metody można użyć do wyzwolenia ponownego uruchomienia, a kontroler będzie postępował zgodnie z protokołem CAN, aby opuścić stan bus-off i przejść w stan error active.
- state() int¶
Zwraca stan kontrolera. Zwracana wartość może być jedną z:
CAN.STOPPED– kontroler jest całkowicie wyłączony i zresetowany;CAN.ERROR_ACTIVE– kontroler jest włączony i w stanie Error Active (zarówno TEC, jak i REC są mniejsze niż 96);CAN.ERROR_WARNING– kontroler jest włączony i w stanie Error Warning (przynajmniej jeden z TEC lub REC wynosi 96 lub więcej);CAN.ERROR_PASSIVE– kontroler jest włączony i w stanie Error Passive (przynajmniej jeden z TEC lub REC wynosi 128 lub więcej);CAN.BUS_OFF– kontroler jest włączony, ale nie uczestniczy w aktywności magistrali (TEC przekroczył 255).
- info(list: list | None = None) list¶
Pobiera informacje o stanach błędów kontrolera oraz buforach TX i RX. Jeśli podano list, powinien to być obiekt listy z co najmniej 8 elementami, które zostaną wypełnione tymi informacjami. W przeciwnym razie zostanie utworzona i wypełniona nowa lista. W obu przypadkach wartością zwracaną przez metodę jest wypełniona lista.
Wartości na liście to:
wartość TEC
wartość REC
liczba przypadków wejścia kontrolera w stan Error Warning (przewija się do 0 po 65535)
liczba przypadków wejścia kontrolera w stan Error Passive (przewija się do 0 po 65535)
liczba przypadków wejścia kontrolera w stan Bus Off (przewija się do 0 po 65535)
liczba oczekujących wiadomości TX
liczba oczekujących wiadomości RX w fifo 0
liczba oczekujących wiadomości RX w fifo 1
- setfilter(bank: int, mode: int, fifo: int, params: Tuple[int, ...], *, rtr: Tuple[bool, ...] | None = None, extframe: bool = False) None¶
Konfiguruje bank filtrów:
bank to bank filtrów klasycznego kontrolera CAN lub indeks filtra CAN FD, który ma zostać skonfigurowany.
mode to tryb, w którym filtr powinien działać, zobacz tabele poniżej.
fifo to fifo (0 lub 1), w którym wiadomość powinna zostać zapisana, jeśli zostanie zaakceptowana przez ten filtr.
params to tablica wartości definiujących filtr. Zawartość tablicy zależy od argumentu mode.
Zawartość tablicy params dla kontrolerów klasycznego CAN (OpenMV Cam M4 / M7):
mode
Zawartość params
CAN.LIST16Cztery 16-bitowe identyfikatory, które będą akceptowane.
CAN.LIST32Dwa 32-bitowe identyfikatory, które będą akceptowane.
CAN.MASK16Dwie pary 16-bitowy id/maska, np.
(1, 3, 4, 4). Pierwsza para (1, 3) akceptuje wszystkie identyfikatory z bitem 0 = 1 i bitem 1 = 0; druga para (4, 4) akceptuje wszystkie identyfikatory z bitem 2 = 1.CAN.MASK32Jedna 32-bitowa para id/maska (poza tym tak samo jak
CAN.MASK16).Zawartość tablicy params dla kontrolerów CAN FD (OpenMV Cam H7 / H7 Plus / Pure Thermal):
mode
Zawartość params
CAN.RANGEDwa identyfikatory tworzące zakres akceptowanych identyfikatorów.
CAN.DUALDwa identyfikatory, które będą akceptowane (np.
(1, 2)).CAN.MASKJedna para
(id, mask)(np.(0x111, 0x7FF)).rtr W przypadku klasycznych kontrolerów CAN jest to tablica wartości logicznych określająca, czy filtr powinien akceptować wiadomość remote transmission request. Jeśli ten argument nie zostanie podany, domyślnie przyjmuje wartość
Falsedla wszystkich elementów. Długość zależy od mode:mode
len(rtr)Uwagi
CAN.LIST164
CAN.LIST322
CAN.MASK162
CAN.MASK321
W przypadku CAN FD ten argument jest ignorowany.
extframe Jeśli True, ramka będzie miała rozszerzony identyfikator (29 bitów), w przeciwnym razie używany jest standardowy identyfikator (11 bitów).
- clearfilter(bank: int, extframe: bool = False) None¶
Czyści i wyłącza bank filtrów:
bank to bank filtrów klasycznego kontrolera CAN lub indeks filtra CAN FD, który ma zostać wyczyszczony.
extframe W przypadku kontrolerów CAN FD, jeśli True, czyści filtr rozszerzony (skonfigurowany z extframe=True), w przeciwnym razie czyści standardowy identyfikator (skonfigurowany z extframe=False).
- any(fifo: int) bool¶
Zwraca
True, jeśli na FIFO oczekuje jakakolwiek wiadomość, w przeciwnym razieFalse.
- recv(fifo: int, list: list | None = None, *, timeout: int = 5000) list¶
Odbiera dane z magistrali:
fifo to liczba całkowita określająca FIFO, na którym ma nastąpić odbiór
list to opcjonalny obiekt listy używany jako wartość zwracana
timeout to limit czasu w milisekundach na oczekiwanie na odbiór.
Wartość zwracana: lista zawierająca pięć wartości.
Identyfikator wiadomości.
Wartość logiczna wskazująca, czy identyfikator wiadomości jest standardowy, czy rozszerzony.
Wartość logiczna wskazująca, czy wiadomość jest wiadomością RTR.
Wartość FMI (Filter Match Index).
Tablica zawierająca dane.
Jeśli list ma wartość
None, zostanie przydzielona nowa lista, a także nowy obiekt bytes do przechowywania danych (jako piąty element listy).Jeśli list nie ma wartości
None, powinien to być obiekt listy z co najmniej pięcioma elementami. Piąty element powinien być obiektem memoryview utworzonym z bytearray lub tablicy typu «B» albo «b», a tablica ta musi mieć miejsce na co najmniej 8 bajtów. Obiekt listy zostanie następnie wypełniony pierwszymi czterema wartościami zwracanymi powyżej, a obiekt memoryview zostanie zmieniony w miejscu do rozmiaru danych i wypełniony tymi danymi. Te same obiekty listy i memoryview mogą być ponownie wykorzystywane w kolejnych wywołaniach tej metody, co umożliwia odbieranie danych bez użycia sterty. Na przykład:buf = bytearray(8) lst = [0, 0, 0, 0, memoryview(buf)] # No heap memory is allocated in the following call can.recv(0, lst)
- send(data: int | bytes | bytearray, id: int, *, timeout: int = 0, rtr: bool = False, extframe: bool = False, fdf: bool = False, brs: bool = False) None¶
Wysyła wiadomość na magistralę:
data to dane do wysłania (liczba całkowita do wysłania lub obiekt bufora).
id to identyfikator wiadomości, która ma zostać wysłana.
timeout to limit czasu w milisekundach na oczekiwanie na wysłanie.
rtr to wartość logiczna określająca, czy wiadomość ma zostać wysłana jako remote transmission request. Jeśli rtr ma wartość True, to do wypełnienia pola DLC ramki używana jest tylko długość data; rzeczywiste bajty w data nie są używane.
extframe jeśli True, ramka będzie miała rozszerzony identyfikator (29 bitów), w przeciwnym razie używany jest standardowy identyfikator (11 bitów).
fdf w przypadku kontrolerów CAN FD, jeśli ustawione na True, ramka będzie miała format ramki FD, który obsługuje ładunki danych do 64 bajtów.
brs w przypadku kontrolerów CAN FD, jeśli ustawione na True, włączany jest tryb przełączania szybkości transmisji, w którym faza danych jest transmitowana z inną szybkością transmisji. Parametry konfiguracji taktowania bitu danych opisuje
CAN.init().
Jeśli timeout wynosi 0, wiadomość jest umieszczana w jednym z trzech buforów sprzętowych, a metoda zwraca wynik natychmiast. Jeśli wszystkie trzy bufory są zajęte, zgłaszany jest wyjątek. Jeśli timeout jest różny od 0, metoda czeka, aż wiadomość zostanie wysłana. Jeśli wiadomość nie może zostać wysłana w określonym czasie, zgłaszany jest wyjątek.
Wartość zwracana:
None.
- rxcallback(fifo: int, fun: Callable[[CAN, int], None] | None) None¶
Rejestruje funkcję wywoływaną, gdy wiadomość zostaje zaakceptowana do pustego FIFO:
fifo to FIFO odbierające.
fun to funkcja wywoływana, gdy FIFO przestaje być puste.
Funkcja wywołania zwrotnego przyjmuje dwa argumenty: pierwszym jest sam obiekt CAN; drugim jest liczba całkowita wskazująca powód wywołania zwrotnego:
Powód
Znaczenie
0Wiadomość została zaakceptowana do pustego FIFO.
1FIFO jest pełne.
2Wiadomość została utracona z powodu pełnego FIFO.
Przykład użycia rxcallback:
def cb0(bus, reason): print('cb0') if reason == 0: print('pending') if reason == 1: print('full') if reason == 2: print('overflow') can = CAN(1, CAN.LOOPBACK) can.rxcallback(0, cb0)
Stałe¶
Stałe trybu magistrali (argument
modemetodyinit()):- NORMAL: int¶
Kontroler uczestniczy normalnie w komunikacji na magistrali – transmituje własne ramki i potwierdza prawidłowo odebrane ramki.
- LOOPBACK: int¶
Tryb wewnętrznej pętli zwrotnej: kontroler jest odłączony od pinów i kieruje transmitowane ramki bezpośrednio z powrotem na ścieżkę odbioru. Przydatny do testów własnych bez transceivera.
- SILENT: int¶
Tryb tylko nasłuchiwania: kontroler odbiera ramki, ale nigdy nie steruje magistralą (brak ACK, brak transmisji). Przydatny do podsłuchiwania magistrali.
- SILENT_LOOPBACK: int¶
Łączy
SILENTiLOOPBACK: brak aktywności na pinach i brak potwierdzeń, z wewnętrzną pętlą zwrotną TX do RX.
Stałe stanu kontrolera (zwracane przez
state()):- ERROR_ACTIVE: int¶
Kontroler jest włączony i w stanie Error Active (zarówno TEC, jak i REC są mniejsze niż 96).
- ERROR_WARNING: int¶
Kontroler jest włączony i w stanie Error Warning (przynajmniej jeden z TEC lub REC wynosi 96 lub więcej).
- ERROR_PASSIVE: int¶
Kontroler jest włączony i w stanie Error Passive (przynajmniej jeden z TEC lub REC wynosi 128 lub więcej).
- BUS_OFF: int¶
Kontroler jest włączony, ale nie uczestniczy w aktywności magistrali (TEC przekroczył 255).
Tryby filtra klasycznego CAN (argument
modemetodysetfilter()w OpenMV Cam M4 / M7):Tryby filtra CAN FD (argument
modemetodysetfilter()w OpenMV Cam H7 / H7 Plus / Pure Thermal):