class CAN – Controller Area Network Kommunikationsbus¶
CAN bietet Unterstützung sowohl für klassisches CAN (bxCAN, verwendet auf der OpenMV Cam M4 und M7) als auch für CAN FD (FDCAN, verwendet auf der OpenMV Cam H7, H7 Plus und Pure Thermal). Auf der physikalischen Ebene besteht der CAN-Bus aus zwei Leitungen, RX und TX. Um eine OpenMV Cam mit einem CAN-Bus zu verbinden, müssen Sie einen CAN-Transceiver verwenden, der die logischen CAN-Signale des MCU in die korrekten Spannungspegel auf dem Bus umwandelt.
Klassisches CAN im Loopback-Modus (ohne Transceiver):
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 mit allen aktivierten optionalen Funktionen (FD-Frame, Bitratenumschaltung, erweiterte Frame-IDs; 500 kbit/s Arbitrierungsphase, 1 Mbit/s Datenphase):
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)
Die folgenden CAN-Modulfunktionen und ihre Argumente sind sowohl für klassische als auch für FD-CAN-Controller verfügbar, sofern nicht anders angegeben.
Konstruktoren¶
- class pyb.CAN(bus: int | str, *args, **kwargs)¶
Erstellt ein CAN-Objekt auf dem angegebenen
bus(ein ganzzahliger Peripherie-Index, z. B.1fürCAN1,2fürCAN2). Ohne zusätzliche Parameter wird das Objekt erstellt, aber nicht initialisiert (es behält die vorherigen Bus-Einstellungen bei, falls vorhanden); werden zusätzliche Argumente angegeben, wird der Bus initialisiert. SieheCAN.init()für die verfügbaren Parameter.CAN(2)ist auf jeder OpenMV Cam, diepyb.CANbereitstellt (M4 / M7 / H7 / H7 Plus / Pure Thermal), mit denselben Header-Pins verdrahtet:Signal
Header-Pin
Hinweise
RXP3TXP2Das CAN-Peripheriegerät liefert nur Signale auf Logikpegel; ein externer CAN-Transceiver ist erforderlich, um einen echten CAN-Bus anzusteuern.
pyb.CANist auf der OpenMV Cam N6 nicht verfügbar.Methoden¶
- 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¶
Initialisiert den CAN-Bus mit den angegebenen Parametern:
mode ist einer von: NORMAL, LOOPBACK, SILENT, SILENT_LOOPBACK
prescaler ist der Wert, durch den der CAN-Eingangstakt geteilt wird, um die nominalen Bitzeit-Quanten zu erzeugen. Der Prescaler kann für klassisches CAN ein Wert zwischen 1 und 1024 einschließlich sein und für CAN FD zwischen 1 und 512 einschließlich.
sjw ist die Resynchronisations-Sprungweite in Einheiten von Zeitquanten für nominale Bits; sie kann für klassisches CAN ein Wert zwischen 1 und 4 einschließlich sein und für CAN FD zwischen 1 und 128 einschließlich.
bs1 legt die Position des Abtastpunkts in Einheiten der Zeitquanten für nominale Bits fest; es kann für klassisches CAN ein Wert zwischen 1 und 16 einschließlich sein und für CAN FD zwischen 2 und 256 einschließlich.
bs2 legt die Position des Sendepunkts in Einheiten der Zeitquanten für nominale Bits fest; es kann für klassisches CAN ein Wert zwischen 1 und 8 einschließlich sein und für CAN FD zwischen 2 und 128 einschließlich.
auto_restart legt fest, ob der Controller nach dem Eintritt in den Bus-Off-Zustand automatisch versucht, die Kommunikation neu zu starten; ist dies deaktiviert, kann
restart()verwendet werden, um den Bus-Off-Zustand zu verlassenbaudrate wenn eine andere Baudrate als 0 angegeben wird, versucht diese Funktion automatisch die nominale CAN-Bitzeit zu berechnen (wobei prescaler, bs1 und bs2 überschrieben werden), die sowohl die baudrate (innerhalb von 0,1 %) als auch den gewünschten sample_point (auf das nächste 1 %) erfüllt. Für eine genauere Kontrolle über das CAN-Timing setzen Sie die Parameter prescaler, bs1 und bs2 direkt.
sample_point gibt die Position der Bit-Abtastung in Bezug auf die gesamte nominale Bitzeit an, ausgedrückt als ganzzahliger Prozentsatz der nominalen Bitzeit. Der Standardwert für sample_point ist 75 %. Dieser Parameter wird ignoriert, sofern baudrate nicht gesetzt ist.
num_filter_banks für klassisches CAN ist dies die Anzahl der Bänke, die CAN(1) zugewiesen werden; die übrigen der 28 werden CAN(2) zugewiesen.
Die übrigen Parameter sind nur auf Boards mit CAN-FD-Unterstützung vorhanden und konfigurieren die optionale CAN-FD-Bitratenumschaltung (Bit Rate Switch, BRS):
brs_prescaler ist der Wert, durch den der CAN-FD-Eingangstakt geteilt wird, um die Datenbitzeit-Quanten zu erzeugen. Der Prescaler kann ein Wert zwischen 1 und 32 einschließlich sein.
brs_sjw ist die Resynchronisations-Sprungweite in Einheiten von Zeitquanten für Datenbits; sie kann ein Wert zwischen 1 und 16 einschließlich sein
brs_bs1 legt die Position des Abtastpunkts in Einheiten der Zeitquanten für Datenbits fest; es kann ein Wert zwischen 1 und 32 einschließlich sein
brs_bs2 legt die Position des Sendepunkts in Einheiten der Zeitquanten für Datenbits fest; es kann ein Wert zwischen 1 und 16 einschließlich sein
brs_baudrate wenn eine andere Baudrate als 0 angegeben wird, versucht diese Funktion automatisch die CAN-Datenbitzeit zu berechnen (wobei brs_prescaler, brs_bs1 und brs_bs2 überschrieben werden), die sowohl die brs_baudrate (innerhalb von 0,1 %) als auch den gewünschten brs_sample_point (auf das nächste 1 %) erfüllt. Für eine genauere Kontrolle über das BRS-Timing setzen Sie die Parameter brs_prescaler, brs_bs1 und brs_bs2 direkt.
brs_sample_point gibt die Position der Bit-Abtastung in Bezug auf die gesamte nominale Bitzeit an, ausgedrückt als ganzzahliger Prozentsatz der nominalen Bitzeit. Der Standardwert für brs_sample_point ist 75 %. Dieser Parameter wird ignoriert, sofern brs_baudrate nicht gesetzt ist.
Das Zeitquantum tq ist die grundlegende Zeiteinheit für den CAN-Bus. tq ist der CAN-Prescaler-Wert geteilt durch PCLK1 (die Frequenz des internen Peripheriebusses 1); siehe
pyb.freq(), um PCLK1 zu bestimmen.Ein einzelnes Bit besteht aus dem Synchronisationssegment, das immer 1 tq beträgt. Es folgt Bitsegment 1, dann Bitsegment 2. Der Abtastpunkt liegt nach dem Ende von Bitsegment 1. Der Sendepunkt liegt nach dem Ende von Bitsegment 2. Die Baudrate ist 1/bittime, wobei die bittime gleich 1 + BS1 + BS2 multipliziert mit dem Zeitquantum tq ist.
Zum Beispiel kann auf der OpenMV Cam H7 (PCLK1 = 100 MHz) 250 kbps CAN mit einem Abtastpunkt von 75 % als
prescaler=25, sjw=1, bs1=11, bs2=4konfiguriert werden:tq = 25 / 100 MHz = 250 ns,bittime = (1 + 11 + 4) × 250 ns = 4 µs, Abtastpunkt =(1 + 11) / 16 = 75%, und die Baudrate ist1 / 4 µs = 250 kHz.Weitere Einzelheiten finden Sie im Abschnitt bxCAN / FDCAN des STM32-Referenzhandbuchs für den MCU der OpenMV Cam.
- restart() None¶
Erzwingt einen Software-Neustart des CAN-Controllers, ohne dessen Konfiguration zurückzusetzen.
Wenn der Controller in den Bus-Off-Zustand eintritt, nimmt er nicht mehr an der Bus-Aktivität teil. Ist der Controller nicht für einen automatischen Neustart konfiguriert (siehe
init()), kann diese Methode verwendet werden, um einen Neustart auszulösen; der Controller folgt dann dem CAN-Protokoll, um den Bus-Off-Zustand zu verlassen und in den Error-Active-Zustand überzugehen.
- state() int¶
Gibt den Zustand des Controllers zurück. Der Rückgabewert kann einer der folgenden sein:
CAN.STOPPED– der Controller ist vollständig ausgeschaltet und zurückgesetzt;CAN.ERROR_ACTIVE– der Controller ist eingeschaltet und im Error-Active-Zustand (sowohl TEC als auch REC sind kleiner als 96);CAN.ERROR_WARNING– der Controller ist eingeschaltet und im Error-Warning-Zustand (mindestens einer von TEC oder REC ist 96 oder größer);CAN.ERROR_PASSIVE– der Controller ist eingeschaltet und im Error-Passive-Zustand (mindestens einer von TEC oder REC ist 128 oder größer);CAN.BUS_OFF– der Controller ist eingeschaltet, nimmt aber nicht an der Bus-Aktivität teil (TEC ist über 255 hinaus übergelaufen).
- info(list: list | None = None) list¶
Ruft Informationen über die Fehlerzustände des Controllers sowie die TX- und RX-Puffer ab. Wird list angegeben, sollte es ein Listenobjekt mit mindestens 8 Einträgen sein, das mit den Informationen gefüllt wird. Andernfalls wird eine neue Liste erstellt und gefüllt. In beiden Fällen ist der Rückgabewert der Methode die gefüllte Liste.
Die Werte in der Liste sind:
TEC-Wert
REC-Wert
Anzahl der Male, die der Controller in den Error-Warning-Zustand eingetreten ist (nach 65535 auf 0 zurückgesetzt)
Anzahl der Male, die der Controller in den Error-Passive-Zustand eingetreten ist (nach 65535 auf 0 zurückgesetzt)
Anzahl der Male, die der Controller in den Bus-Off-Zustand eingetreten ist (nach 65535 auf 0 zurückgesetzt)
Anzahl der ausstehenden TX-Nachrichten
Anzahl der ausstehenden RX-Nachrichten in FIFO 0
Anzahl der ausstehenden RX-Nachrichten in FIFO 1
- setfilter(bank: int, mode: int, fifo: int, params: Tuple[int, ...], *, rtr: Tuple[bool, ...] | None = None, extframe: bool = False) None¶
Konfiguriert eine Filterbank:
bank ist die zu konfigurierende Filterbank des klassischen CAN-Controllers bzw. der CAN-FD-Filterindex.
mode ist der Modus, in dem der Filter arbeiten soll, siehe die Tabellen unten.
fifo gibt an, in welchem FIFO (0 oder 1) eine Nachricht gespeichert werden soll, wenn sie von diesem Filter akzeptiert wird.
params ist ein Array von Werten, die den Filter definieren. Der Inhalt des Arrays hängt vom Argument mode ab.
Inhalt des params-Arrays für klassische CAN-Controller (OpenMV Cam M4 / M7):
mode
Inhalt von params
CAN.LIST16Vier 16-Bit-IDs, die akzeptiert werden.
CAN.LIST32Zwei 32-Bit-IDs, die akzeptiert werden.
CAN.MASK16Zwei 16-Bit-id/mask-Paare, z. B.
(1, 3, 4, 4). Das erste Paar (1, 3) akzeptiert alle IDs mit Bit 0 = 1 und Bit 1 = 0; das zweite Paar (4, 4) akzeptiert alle IDs mit Bit 2 = 1.CAN.MASK32Ein 32-Bit-id/mask-Paar (ansonsten identisch mit
CAN.MASK16).Inhalt des params-Arrays für CAN FD-Controller (OpenMV Cam H7 / H7 Plus / Pure Thermal):
mode
Inhalt von params
CAN.RANGEZwei IDs, die einen Bereich akzeptierter IDs bilden.
CAN.DUALZwei IDs, die akzeptiert werden (z. B.
(1, 2)).CAN.MASKEin
(id, mask)-Paar (z. B.(0x111, 0x7FF)).rtr Für klassische CAN-Controller ist dies ein Array von Booleschen Werten, das angibt, ob ein Filter eine Remote-Transmission-Request-Nachricht akzeptieren soll. Wird dieses Argument nicht angegeben, ist es für alle Einträge standardmäßig
False. Die Länge hängt von mode ab:mode
len(rtr)Hinweise
CAN.LIST164
CAN.LIST322
CAN.MASK162
CAN.MASK321
Für CAN FD wird dieses Argument ignoriert.
extframe Wenn True, hat der Frame einen erweiterten Identifier (29 Bit), andernfalls wird ein Standard-Identifier (11 Bit) verwendet.
- clearfilter(bank: int, extframe: bool = False) None¶
Löscht und deaktiviert eine Filterbank:
bank ist die zu löschende Filterbank des klassischen CAN-Controllers bzw. der CAN-FD-Filterindex.
extframe Für CAN-FD-Controller: wenn True, wird ein erweiterter Filter gelöscht (konfiguriert mit extframe=True), andernfalls wird ein Standard-Identifier gelöscht (konfiguriert mit extframe=False).
- recv(fifo: int, list: list | None = None, *, timeout: int = 5000) list¶
Empfängt Daten auf dem Bus:
fifo ist eine Ganzzahl, die das FIFO angibt, auf dem empfangen werden soll
list ist ein optionales Listenobjekt, das als Rückgabewert verwendet wird
timeout ist die Wartezeit in Millisekunden für den Empfang.
Rückgabewert: Eine Liste mit fünf Werten.
Die ID der Nachricht.
Ein Boolescher Wert, der angibt, ob die Nachrichten-ID Standard oder erweitert ist.
Ein Boolescher Wert, der angibt, ob die Nachricht eine RTR-Nachricht ist.
Der FMI-Wert (Filter Match Index).
Ein Array, das die Daten enthält.
Wenn list
Noneist, wird eine neue Liste sowie ein neues bytes-Objekt zur Aufnahme der Daten (als fünftes Element der Liste) angelegt.Wenn list nicht
Noneist, sollte es ein Listenobjekt mit mindestens fünf Elementen sein. Das fünfte Element sollte ein memoryview-Objekt sein, das aus einem bytearray oder einem Array vom Typ ‚B‘ oder ‚b‘ erstellt wurde, und dieses Array muss Platz für mindestens 8 Bytes haben. Das Listenobjekt wird dann mit den ersten vier oben genannten Rückgabewerten gefüllt, und das memoryview-Objekt wird an Ort und Stelle auf die Größe der Daten angepasst und mit diesen Daten gefüllt. Dieselben list- und memoryview-Objekte können bei späteren Aufrufen dieser Methode wiederverwendet werden, was eine Möglichkeit bietet, Daten zu empfangen, ohne den Heap zu nutzen. Zum Beispiel: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¶
Sendet eine Nachricht auf dem Bus:
data sind die zu sendenden Daten (eine zu sendende Ganzzahl oder ein Pufferobjekt).
id ist die ID der zu sendenden Nachricht.
timeout ist die Wartezeit in Millisekunden für das Senden.
rtr ist ein Boolescher Wert, der angibt, ob die Nachricht als Remote-Transmission-Request gesendet werden soll. Ist rtr True, wird nur die Länge von data verwendet, um den DLC-Slot des Frames zu füllen; die eigentlichen Bytes in data werden nicht verwendet.
extframe wenn True, hat der Frame einen erweiterten Identifier (29 Bit), andernfalls wird ein Standard-Identifier (11 Bit) verwendet.
fdf für CAN-FD-Controller: wenn auf True gesetzt, hat der Frame ein FD-Frame-Format, das Datennutzlasten von bis zu 64 Bytes unterstützt.
brs für CAN-FD-Controller: wenn auf True gesetzt, ist der Bitratenumschaltungsmodus aktiviert, bei dem die Datenphase mit einer anderen Bitrate übertragen wird. Siehe
CAN.init()für die Konfigurationsparameter des Datenbit-Timings.
Ist timeout 0, wird die Nachricht in einen der drei Hardware-Puffer gelegt und die Methode kehrt sofort zurück. Sind alle drei Puffer belegt, wird eine Ausnahme ausgelöst. Ist timeout nicht 0, wartet die Methode, bis die Nachricht übertragen wurde. Kann die Nachricht nicht innerhalb der angegebenen Zeit übertragen werden, wird eine Ausnahme ausgelöst.
Rückgabewert:
None.
- rxcallback(fifo: int, fun: Callable[[CAN, int], None] | None) None¶
Registriert eine Funktion, die aufgerufen wird, wenn eine Nachricht in ein leeres FIFO aufgenommen wird:
fifo ist das empfangende FIFO.
fun ist die Funktion, die aufgerufen wird, wenn das FIFO nicht mehr leer ist.
Die Callback-Funktion nimmt zwei Argumente entgegen: das erste ist das CAN-Objekt selbst; das zweite ist eine Ganzzahl, die den Grund für den Callback angibt:
Grund
Bedeutung
0Eine Nachricht wurde in ein leeres FIFO aufgenommen.
1Das FIFO ist voll.
2Eine Nachricht ging aufgrund eines vollen FIFOs verloren.
Beispiel für die Verwendung von 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)
Konstanten¶
Bus-Modus-Konstanten (
mode-Argument voninit()):- NORMAL: int¶
Der Controller nimmt normal am Bus teil – sendet seine eigenen Frames und bestätigt gültige empfangene Frames.
- LOOPBACK: int¶
Interner Loopback-Modus: der Controller ist von den Pins getrennt und leitet gesendete Frames direkt zurück auf den Empfangspfad. Nützlich für Selbsttests ohne Transceiver.
- SILENT: int¶
Listen-only-Modus: der Controller empfängt Frames, treibt aber niemals den Bus an (kein ACK, keine Übertragungen). Nützlich zum Mitlesen des Busses.
- SILENT_LOOPBACK: int¶
Kombiniert
SILENTundLOOPBACK: keine Pin-Aktivität und keine Bestätigungen, mit internem Loopback von TX nach RX.
Controller-Zustands-Konstanten (zurückgegeben von
state()):- ERROR_ACTIVE: int¶
Der Controller ist eingeschaltet und im Error-Active-Zustand (sowohl TEC als auch REC sind kleiner als 96).
- ERROR_WARNING: int¶
Der Controller ist eingeschaltet und im Error-Warning-Zustand (mindestens einer von TEC oder REC ist 96 oder größer).
- ERROR_PASSIVE: int¶
Der Controller ist eingeschaltet und im Error-Passive-Zustand (mindestens einer von TEC oder REC ist 128 oder größer).
- BUS_OFF: int¶
Der Controller ist eingeschaltet, nimmt aber nicht an der Bus-Aktivität teil (TEC ist über 255 hinaus übergelaufen).
Klassische CAN-Filtermodi (
mode-Argument vonsetfilter()auf der OpenMV Cam M4 / M7):CAN-FD-Filtermodi (
mode-Argument vonsetfilter()auf der OpenMV Cam H7 / H7 Plus / Pure Thermal):