class CAN – controller area network communicatiebus¶
CAN biedt ondersteuning voor zowel klassieke CAN (bxCAN, gebruikt op de OpenMV Cam M4 en M7) als CAN FD (FDCAN, gebruikt op de OpenMV Cam H7, H7 Plus en Pure Thermal) controllers. Op het fysieke niveau bestaat de CAN-bus uit twee lijnen, RX en TX. Om een OpenMV Cam op een CAN-bus aan te sluiten moet u een CAN-transceiver gebruiken om de CAN-logicasignalen van de MCU om te zetten naar de juiste spanningsniveaus op de bus.
Klassieke CAN in loopback-modus (zonder 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 met alle optionele functies ingeschakeld (FD-frame, bit-rate switching, uitgebreide frame-ID’s; 500 kbit/s arbitragefase, 1 Mbit/s datafase):
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)
De volgende CAN-modulefuncties en hun argumenten zijn beschikbaar voor zowel klassieke als FD CAN-controllers, tenzij anders vermeld.
Constructors¶
- class pyb.CAN(bus: int | str, *args, **kwargs)¶
Construeer een CAN-object op de gegeven
bus(een geheel getal als randapparaat-index, bijv.1voorCAN1,2voorCAN2). Zonder aanvullende parameters wordt het object aangemaakt maar niet geïnitialiseerd (het behoudt de vorige businstellingen, indien aanwezig); als er extra argumenten worden meegegeven, wordt de bus geïnitialiseerd. ZieCAN.init()voor de beschikbare parameters.CAN(2)is bedraad naar dezelfde headerpinnen op elke OpenMV Cam diepyb.CANblootstelt (M4 / M7 / H7 / H7 Plus / Pure Thermal):Signaal
Headerpin
Opmerkingen
RXP3TXP2Het CAN-randapparaat levert alleen signalen op logicaniveau; een externe CAN-transceiver is vereist om een echte CAN-bus aan te sturen.
pyb.CANis niet beschikbaar op de OpenMV Cam N6.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¶
Initialiseer de CAN-bus met de gegeven parameters:
mode is een van: NORMAL, LOOPBACK, SILENT, SILENT_LOOPBACK
prescaler is de waarde waardoor de CAN-ingangsklok wordt gedeeld om de nominale bittijd-quanta te genereren. De prescaler kan een waarde zijn tussen 1 en 1024 inclusief voor klassieke CAN, en tussen 1 en 512 inclusief voor CAN FD.
sjw is de resynchronisatie-sprongbreedte in eenheden van tijd-quanta voor nominale bits; het kan een waarde zijn tussen 1 en 4 inclusief voor klassieke CAN, en tussen 1 en 128 inclusief voor CAN FD.
bs1 bepaalt de locatie van het bemonsteringspunt in eenheden van de tijd-quanta voor nominale bits; het kan een waarde zijn tussen 1 en 16 inclusief voor klassieke CAN, en tussen 2 en 256 inclusief voor CAN FD.
bs2 bepaalt de locatie van het zendpunt in eenheden van de tijd-quanta voor nominale bits; het kan een waarde zijn tussen 1 en 8 inclusief voor klassieke CAN, en tussen 2 en 128 inclusief voor CAN FD.
auto_restart stelt in of de controller automatisch zal proberen de communicatie te herstarten nadat hij de bus-off-toestand is binnengegaan; als dit is uitgeschakeld kan
restart()worden gebruikt om de bus-off-toestand te verlatenbaudrate als er een andere baudrate dan 0 wordt opgegeven, zal deze functie proberen automatisch de nominale CAN-bittijd te berekenen (waarbij prescaler, bs1 en bs2 worden overschreven) die voldoet aan zowel de baudrate (binnen 0,1%) als het gewenste sample_point (tot op het dichtstbijzijnde 1%). Voor preciezere controle over de CAN-timing stelt u de parameters prescaler, bs1 en bs2 rechtstreeks in.
sample_point specificeert de positie van de bitbemonstering ten opzichte van de hele nominale bittijd, uitgedrukt als een geheel getal in procenten van de nominale bittijd. Het standaard sample_point is 75%. Deze parameter wordt genegeerd tenzij baudrate is ingesteld.
num_filter_banks voor klassieke CAN is dit het aantal banks dat aan CAN(1) wordt toegewezen, de rest van de 28 worden toegewezen aan CAN(2).
De resterende parameters zijn alleen aanwezig op borden met CAN FD-ondersteuning, en configureren de optionele CAN FD Bit Rate Switch (BRS)-functie:
brs_prescaler is de waarde waardoor de CAN FD-ingangsklok wordt gedeeld om de databittijd-quanta te genereren. De prescaler kan een waarde zijn tussen 1 en 32 inclusief.
brs_sjw is de resynchronisatie-sprongbreedte in eenheden van tijd-quanta voor databits; het kan een waarde zijn tussen 1 en 16 inclusief
brs_bs1 bepaalt de locatie van het bemonsteringspunt in eenheden van de tijd-quanta voor databits; het kan een waarde zijn tussen 1 en 32 inclusief
brs_bs2 bepaalt de locatie van het zendpunt in eenheden van de tijd-quanta voor databits; het kan een waarde zijn tussen 1 en 16 inclusief
brs_baudrate als er een andere baudrate dan 0 wordt opgegeven, zal deze functie proberen automatisch de CAN-databittijd te berekenen (waarbij brs_prescaler, brs_bs1 en brs_bs2 worden overschreven) die voldoet aan zowel de brs_baudrate (binnen 0,1%) als het gewenste brs_sample_point (tot op het dichtstbijzijnde 1%). Voor preciezere controle over de BRS-timing stelt u de parameters brs_prescaler, brs_bs1 en brs_bs2 rechtstreeks in.
brs_sample_point specificeert de positie van de bitbemonstering ten opzichte van de hele nominale bittijd, uitgedrukt als een geheel getal in procenten van de nominale bittijd. Het standaard brs_sample_point is 75%. Deze parameter wordt genegeerd tenzij brs_baudrate is ingesteld.
De tijd-quantum tq is de basiseenheid van tijd voor de CAN-bus. tq is de CAN-prescalerwaarde gedeeld door PCLK1 (de frequentie van interne randapparatenbus 1); zie
pyb.freq()om PCLK1 te bepalen.Een enkele bit bestaat uit het synchronisatiesegment, dat altijd 1 tq is. Daarna volgt bitsegment 1, dan bitsegment 2. Het bemonsteringspunt ligt nadat bitsegment 1 eindigt. Het zendpunt ligt nadat bitsegment 2 eindigt. De baudrate zal 1/bittijd zijn, waarbij de bittijd gelijk is aan 1 + BS1 + BS2 vermenigvuldigd met de tijd-quantum tq.
Bijvoorbeeld, op de OpenMV Cam H7 (PCLK1 = 100 MHz) kan 250 kbps CAN met een bemonsteringspunt van 75% worden geconfigureerd als
prescaler=25, sjw=1, bs1=11, bs2=4:tq = 25 / 100 MHz = 250 ns,bittime = (1 + 11 + 4) × 250 ns = 4 µs, bemonsteringspunt =(1 + 11) / 16 = 75%, en de baudrate is1 / 4 µs = 250 kHz.Zie de bxCAN / FDCAN-sectie van de STM32-referentiehandleiding voor de MCU van de OpenMV Cam voor meer details.
- restart() None¶
Forceer een softwareherstart van de CAN-controller zonder de configuratie ervan te resetten.
Als de controller de bus-off-toestand binnengaat, zal hij niet langer deelnemen aan busactiviteit. Als de controller niet is geconfigureerd om automatisch te herstarten (zie
init()) dan kan deze methode worden gebruikt om een herstart te activeren, en de controller zal het CAN-protocol volgen om de bus-off-toestand te verlaten en over te gaan naar de error-active-toestand.
- state() int¶
Geef de toestand van de controller terug. De retourwaarde kan een van de volgende zijn:
CAN.STOPPED– de controller is volledig uit en gereset;CAN.ERROR_ACTIVE– de controller is aan en in de Error Active-toestand (zowel TEC als REC zijn kleiner dan 96);CAN.ERROR_WARNING– de controller is aan en in de Error Warning-toestand (ten minste een van TEC of REC is 96 of hoger);CAN.ERROR_PASSIVE– de controller is aan en in de Error Passive-toestand (ten minste een van TEC of REC is 128 of hoger);CAN.BUS_OFF– de controller is aan maar neemt niet deel aan busactiviteit (TEC liep over boven 255).
- info(list: list | None = None) list¶
Verkrijg informatie over de fouttoestanden van de controller en de TX- en RX-buffers. Als list wordt opgegeven, moet het een lijstobject zijn met ten minste 8 elementen, die met de informatie zullen worden ingevuld. Anders wordt er een nieuwe lijst aangemaakt en ingevuld. In beide gevallen is de retourwaarde van de methode de ingevulde lijst.
De waarden in de lijst zijn:
TEC-waarde
REC-waarde
aantal keren dat de controller de Error Warning-toestand binnenging (wordt naar 0 teruggezet na 65535)
aantal keren dat de controller de Error Passive-toestand binnenging (wordt naar 0 teruggezet na 65535)
aantal keren dat de controller de Bus Off-toestand binnenging (wordt naar 0 teruggezet na 65535)
aantal in behandeling zijnde TX-berichten
aantal in behandeling zijnde RX-berichten op fifo 0
aantal in behandeling zijnde RX-berichten op fifo 1
- setfilter(bank: int, mode: int, fifo: int, params: Tuple[int, ...], *, rtr: Tuple[bool, ...] | None = None, extframe: bool = False) None¶
Configureer een filterbank:
bank is de filterbank van de klassieke CAN-controller, of de CAN FD-filterindex, die geconfigureerd moet worden.
mode is de modus waarin het filter moet werken, zie de onderstaande tabellen.
fifo is in welke fifo (0 of 1) een bericht moet worden opgeslagen, als het door dit filter wordt geaccepteerd.
params is een array van waarden die het filter definieert. De inhoud van de array hangt af van het argument mode.
Inhoud van de params-array voor klassieke CAN-controllers (OpenMV Cam M4 / M7):
mode
Inhoud van params
CAN.LIST16Vier 16-bits ID’s die worden geaccepteerd.
CAN.LIST32Twee 32-bits ID’s die worden geaccepteerd.
CAN.MASK16Twee 16-bits id/mask-paren, bijv.
(1, 3, 4, 4). Het eerste paar (1, 3) accepteert alle ID’s met bit 0 = 1 en bit 1 = 0; het tweede paar (4, 4) accepteert alle ID’s met bit 2 = 1.CAN.MASK32Eén 32-bits id/mask-paar (verder hetzelfde als
CAN.MASK16).Inhoud van de params-array voor CAN FD-controllers (OpenMV Cam H7 / H7 Plus / Pure Thermal):
mode
Inhoud van params
CAN.RANGETwee ID’s die een bereik van geaccepteerde ID’s vormen.
CAN.DUALTwee ID’s die worden geaccepteerd (bijv.
(1, 2)).CAN.MASKEén
(id, mask)-paar (bijv.(0x111, 0x7FF)).rtr Voor klassieke CAN-controllers is dit een array van booleans die aangeeft of een filter een remote transmission request-bericht moet accepteren. Als dit argument niet wordt opgegeven, is de standaardwaarde
Falsevoor alle elementen. De lengte hangt af van mode:mode
len(rtr)Opmerkingen
CAN.LIST164
CAN.LIST322
CAN.MASK162
CAN.MASK321
Voor CAN FD wordt dit argument genegeerd.
extframe Indien True heeft het frame een uitgebreide identifier (29 bits), anders wordt een standaard-identifier (11 bits) gebruikt.
- clearfilter(bank: int, extframe: bool = False) None¶
Wis en deactiveer een filterbank:
bank is de filterbank van de klassieke CAN-controller, of de CAN FD-filterindex, die gewist moet worden.
extframe Voor CAN FD-controllers, indien True, wist een uitgebreid filter (geconfigureerd met extframe=True), anders wordt een standaard-identifier gewist (geconfigureerd met extframe=False).
- recv(fifo: int, list: list | None = None, *, timeout: int = 5000) list¶
Ontvang data op de bus:
fifo is een geheel getal, dat de FIFO is om op te ontvangen
list is een optioneel lijstobject dat als retourwaarde wordt gebruikt
timeout is de time-out in milliseconden om op de ontvangst te wachten.
Retourwaarde: Een lijst met vijf waarden.
De id van het bericht.
Een boolean die aangeeft of de bericht-ID standaard of uitgebreid is.
Een boolean die aangeeft of het bericht een RTR-bericht is.
De FMI (Filter Match Index)-waarde.
Een array die de data bevat.
Als list gelijk is aan
Nonedan wordt er een nieuwe lijst toegewezen, evenals een nieuw bytes-object om de data te bevatten (als het vijfde element in de lijst).Als list niet gelijk is aan
Nonedan moet het een lijstobject zijn met ten minste vijf elementen. Het vijfde element moet een memoryview-object zijn dat is aangemaakt uit ofwel een bytearray ofwel een array van het type ‘B’ of ‘b’, en deze array moet genoeg ruimte hebben voor ten minste 8 bytes. Het lijstobject zal dan worden gevuld met de eerste vier retourwaarden hierboven, en het memoryview-object zal ter plaatse worden aangepast naar de grootte van de data en met die data worden ingevuld. Dezelfde lijst- en memoryview-objecten kunnen worden hergebruikt in opeenvolgende aanroepen van deze methode, wat een manier biedt om data te ontvangen zonder de heap te gebruiken. Bijvoorbeeld: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¶
Verstuur een bericht op de bus:
data is de te verzenden data (een te verzenden geheel getal, of een bufferobject).
id is de id van het te verzenden bericht.
timeout is de time-out in milliseconden om op het verzenden te wachten.
rtr is een boolean die specificeert of het bericht als een remote transmission request moet worden verzonden. Als rtr True is dan wordt alleen de lengte van data gebruikt om de DLC-sleuf van het frame in te vullen; de daadwerkelijke bytes in data worden niet gebruikt.
extframe indien True heeft het frame een uitgebreide identifier (29 bits), anders wordt een standaard-identifier (11 bits) gebruikt.
fdf voor CAN FD-controllers, indien ingesteld op True, heeft het frame een FD-frameformaat, dat datapayloads tot 64 bytes ondersteunt.
brs voor CAN FD-controllers, indien ingesteld op True, is de bitrate-switchingmodus ingeschakeld, waarbij de datafase op een andere bitrate wordt verzonden. Zie
CAN.init()voor de configuratieparameters van de databittiming.
Als timeout 0 is, wordt het bericht in een van de drie hardwarebuffers geplaatst en keert de methode onmiddellijk terug. Als alle drie de buffers in gebruik zijn, wordt er een uitzondering opgeworpen. Als timeout niet 0 is, wacht de methode tot het bericht is verzonden. Als het bericht niet binnen de opgegeven tijd kan worden verzonden, wordt er een uitzondering opgeworpen.
Retourwaarde:
None.
- rxcallback(fifo: int, fun: Callable[[CAN, int], None] | None) None¶
Registreer een functie die wordt aangeroepen wanneer een bericht in een lege FIFO wordt geaccepteerd:
fifo is de ontvangende FIFO.
fun is de functie die moet worden aangeroepen wanneer de FIFO niet-leeg wordt.
De callback-functie neemt twee argumenten: het eerste is het CAN-object zelf; het tweede is een geheel getal dat de reden voor de callback aangeeft:
Reden
Betekenis
0Een bericht is in een lege FIFO geaccepteerd.
1De FIFO is vol.
2Een bericht is verloren gegaan vanwege een volle FIFO.
Voorbeeld van het gebruik van 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)
Constanten¶
Busmodus-constanten (
mode-argument vaninit()):- NORMAL: int¶
De controller neemt normaal deel aan de bus – verzendt zijn eigen frames en bevestigt geldige ontvangen frames.
- LOOPBACK: int¶
Interne loopback-modus: de controller is losgekoppeld van de pinnen en routeert verzonden frames rechtstreeks terug naar het ontvangstpad. Handig voor zelftests zonder transceiver.
- SILENT: int¶
Listen-only-modus: de controller ontvangt frames maar stuurt de bus nooit aan (geen ACK, geen transmissies). Handig voor het meeluisteren op de bus.
- SILENT_LOOPBACK: int¶
Combineert
SILENTenLOOPBACK: geen pinactiviteit en geen bevestigingen, met interne loopback van TX naar RX.
Controllertoestand-constanten (geretourneerd door
state()):- ERROR_ACTIVE: int¶
De controller is aan en in de Error Active-toestand (zowel TEC als REC zijn kleiner dan 96).
- ERROR_WARNING: int¶
De controller is aan en in de Error Warning-toestand (ten minste een van TEC of REC is 96 of hoger).
- ERROR_PASSIVE: int¶
De controller is aan en in de Error Passive-toestand (ten minste een van TEC of REC is 128 of hoger).
- BUS_OFF: int¶
De controller is aan maar neemt niet deel aan busactiviteit (TEC liep over boven 255).
Klassieke-CAN-filtermodi (
mode-argument vansetfilter()op de OpenMV Cam M4 / M7):CAN FD-filtermodi (
mode-argument vansetfilter()op de OpenMV Cam H7 / H7 Plus / Pure Thermal):