klass CAN – kommunikationsbuss för controller area network

CAN implementerar stöd för både klassisk CAN (bxCAN, som används på OpenMV Cam M4 och M7) och CAN FD (FDCAN, som används på OpenMV Cam H7, H7 Plus och Pure Thermal). På den fysiska nivån består CAN-bussen av två ledningar, RX och TX. För att ansluta en OpenMV Cam till en CAN-buss måste du använda en CAN-transceiver för att omvandla CAN-logiksignalerna från MCU:n till rätt spänningsnivåer på bussen.

Klassisk CAN i loopback-läge (utan 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 med alla valfria funktioner aktiverade (FD-bildruta, bithastighetsväxling, utökade bildrute-ID:n; 500 kbit/s arbitreringsfas, 1 Mbit/s datafas):

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)

Följande CAN-modulfunktioner och deras argument är tillgängliga för både klassiska och FD CAN-styrenheter, om inte annat anges.

Konstruktorer

class pyb.CAN(bus: int | str, *args, **kwargs)

Konstruera ett CAN-objekt på den angivna bus (ett heltal som anger kringutrustningsindex, t.ex. 1 för CAN1, 2 för CAN2). Utan ytterligare parametrar skapas objektet men initieras inte (det behåller de tidigare bussinställningarna, om sådana finns); om extra argument anges initieras bussen. Se CAN.init() för de tillgängliga parametrarna.

CAN(2) är kopplad till samma header-stift på alla OpenMV Cam som exponerar pyb.CAN (M4 / M7 / H7 / H7 Plus / Pure Thermal):

Signal

Header-stift

Anmärkningar

RX

P3

TX

P2

CAN-kringutrustningen tillhandahåller endast logiknivåsignaler; en extern CAN-transceiver krävs för att driva en riktig CAN-buss.

pyb.CAN är inte tillgänglig på OpenMV Cam N6.

Metoder

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

Initiera CAN-bussen med de angivna parametrarna:

  • mode är en av: NORMAL, LOOPBACK, SILENT, SILENT_LOOPBACK

  • prescaler är värdet som CAN-ingångsklockan divideras med för att generera de nominella bittidskvantana. Förskalaren kan vara ett värde mellan 1 och 1024 inklusive för klassisk CAN, och mellan 1 och 512 inklusive för CAN FD.

  • sjw är resynkroniseringshopplängden i enheter av tidskvanta för nominella bitar; den kan vara ett värde mellan 1 och 4 inklusive för klassisk CAN, och mellan 1 och 128 inklusive för CAN FD.

  • bs1 definierar samplingspunktens placering i enheter av tidskvanta för nominella bitar; den kan vara ett värde mellan 1 och 16 inklusive för klassisk CAN, och mellan 2 och 256 inklusive för CAN FD.

  • bs2 definierar sändningspunktens placering i enheter av tidskvanta för nominella bitar; den kan vara ett värde mellan 1 och 8 inklusive för klassisk CAN, och mellan 2 och 128 inklusive för CAN FD.

  • auto_restart anger om styrenheten automatiskt ska försöka starta om kommunikationen efter att ha gått in i bus-off-tillståndet; om detta är inaktiverat kan restart() användas för att lämna bus-off-tillståndet

  • baudrate om en baudhastighet annan än 0 anges försöker denna funktion automatiskt beräkna den nominella CAN-bittiden (vilket åsidosätter prescaler, bs1 och bs2) som uppfyller både baudrate (inom 0,1 %) och den önskade sample_point (till närmaste 1 %). För mer exakt kontroll över CAN-timingen, ställ in parametrarna prescaler, bs1 och bs2 direkt.

  • sample_point anger bitsamplingens position i förhållande till hela den nominella bittiden, uttryckt som en heltalsprocent av den nominella bittiden. Standardvärdet för sample_point är 75 %. Denna parameter ignoreras om inte baudrate är inställt.

  • num_filter_banks för klassisk CAN är detta antalet banker som tilldelas CAN(1), resten av de 28 tilldelas CAN(2).

De återstående parametrarna finns endast på kort med CAN FD-stöd och konfigurerar den valfria CAN FD Bit Rate Switch (BRS)-funktionen:

  • brs_prescaler är värdet som CAN FD-ingångsklockan divideras med för att generera databittidskvantana. Förskalaren kan vara ett värde mellan 1 och 32 inklusive.

  • brs_sjw är resynkroniseringshopplängden i enheter av tidskvanta för databitar; den kan vara ett värde mellan 1 och 16 inklusive

  • brs_bs1 definierar samplingspunktens placering i enheter av tidskvanta för databitar; den kan vara ett värde mellan 1 och 32 inklusive

  • brs_bs2 definierar sändningspunktens placering i enheter av tidskvanta för databitar; den kan vara ett värde mellan 1 och 16 inklusive

  • brs_baudrate om en baudhastighet annan än 0 anges försöker denna funktion automatiskt beräkna CAN-databittiden (vilket åsidosätter brs_prescaler, brs_bs1 och brs_bs2) som uppfyller både brs_baudrate (inom 0,1 %) och den önskade brs_sample_point (till närmaste 1 %). För mer exakt kontroll över BRS-timingen, ställ in parametrarna brs_prescaler, brs_bs1 och brs_bs2 direkt.

  • brs_sample_point anger bitsamplingens position i förhållande till hela den nominella bittiden, uttryckt som en heltalsprocent av den nominella bittiden. Standardvärdet för brs_sample_point är 75 %. Denna parameter ignoreras om inte brs_baudrate är inställt.

Tidskvantat tq är den grundläggande tidsenheten för CAN-bussen. tq är CAN-förskalarvärdet dividerat med PCLK1 (frekvensen för den interna kringutrustningsbussen 1); se pyb.freq() för att fastställa PCLK1.

En enskild bit utgörs av synkroniseringssegmentet, som alltid är 1 tq. Därefter följer bitsegment 1, sedan bitsegment 2. Samplingspunkten är efter att bitsegment 1 avslutats. Sändningspunkten är efter att bitsegment 2 avslutats. Baudhastigheten blir 1/bittid, där bittiden är 1 + BS1 + BS2 multiplicerat med tidskvantat tq.

Till exempel, på OpenMV Cam H7 (PCLK1 = 100 MHz), kan 250 kbps CAN med en 75 % samplingspunkt konfigureras som prescaler=25, sjw=1, bs1=11, bs2=4: tq = 25 / 100 MHz = 250 ns, bittime = (1 + 11 + 4) × 250 ns = 4 µs, samplingspunkt = (1 + 11) / 16 = 75%, och baudhastigheten är 1 / 4 µs = 250 kHz.

Se avsnittet bxCAN / FDCAN i STM32-referensmanualen för OpenMV Cam:s MCU för mer information.

deinit() None

Stäng av CAN-bussen.

restart() None

Tvinga fram en programvarustart om CAN-styrenheten utan att återställa dess konfiguration.

Om styrenheten går in i bus-off-tillståndet deltar den inte längre i bussaktiviteten. Om styrenheten inte är konfigurerad att starta om automatiskt (se init()) kan denna metod användas för att utlösa en omstart, och styrenheten kommer att följa CAN-protokollet för att lämna bus-off-tillståndet och gå in i error active-tillståndet.

state() int

Returnerar styrenhetens tillstånd. Returvärdet kan vara ett av:

  • CAN.STOPPED – styrenheten är helt avstängd och återställd;

  • CAN.ERROR_ACTIVE – styrenheten är på och i Error Active-tillståndet (både TEC och REC är mindre än 96);

  • CAN.ERROR_WARNING – styrenheten är på och i Error Warning-tillståndet (minst en av TEC eller REC är 96 eller större);

  • CAN.ERROR_PASSIVE – styrenheten är på och i Error Passive-tillståndet (minst en av TEC eller REC är 128 eller större);

  • CAN.BUS_OFF – styrenheten är på men deltar inte i bussaktiviteten (TEC har överskridit 255).

info(list: list | None = None) list

Hämta information om styrenhetens feltillstånd samt TX- och RX-buffertar. Om list anges ska det vara ett listobjekt med minst 8 poster, som fylls i med informationen. I annat fall skapas en ny lista och fylls i. I båda fallen är metodens returvärde den ifyllda listan.

Värdena i listan är:

  • TEC-värde

  • REC-värde

  • antal gånger styrenheten gick in i Error Warning-tillståndet (slår runt till 0 efter 65535)

  • antal gånger styrenheten gick in i Error Passive-tillståndet (slår runt till 0 efter 65535)

  • antal gånger styrenheten gick in i Bus Off-tillståndet (slår runt till 0 efter 65535)

  • antal väntande TX-meddelanden

  • antal väntande RX-meddelanden på fifo 0

  • antal väntande RX-meddelanden på fifo 1

setfilter(bank: int, mode: int, fifo: int, params: Tuple[int, ...], *, rtr: Tuple[bool, ...] | None = None, extframe: bool = False) None

Konfigurera en filterbank:

  • bank är den klassiska CAN-styrenhetens filterbank, eller CAN FD-filterindex, som ska konfigureras.

  • mode är läget som filtret ska arbeta i, se tabellerna nedan.

  • fifo anger i vilken fifo (0 eller 1) ett meddelande ska lagras om det accepteras av detta filter.

  • params är en array med värden som definierar filtret. Innehållet i arrayen beror på argumentet mode.

Innehåll i params-arrayen för styrenheter med klassisk CAN (OpenMV Cam M4 / M7):

mode

Innehåll i params

CAN.LIST16

Fyra 16-bitars ID:n som kommer att accepteras.

CAN.LIST32

Två 32-bitars ID:n som kommer att accepteras.

CAN.MASK16

Två 16-bitars id/mask-par, t.ex. (1, 3, 4, 4). Det första paret (1, 3) accepterar alla ID:n med bit 0 = 1 och bit 1 = 0; det andra paret (4, 4) accepterar alla ID:n med bit 2 = 1.

CAN.MASK32

Ett 32-bitars id/mask-par (i övrigt samma som CAN.MASK16).

Innehåll i params-arrayen för styrenheter med CAN FD (OpenMV Cam H7 / H7 Plus / Pure Thermal):

mode

Innehåll i params

CAN.RANGE

Två ID:n som bildar ett intervall av accepterade ID:n.

CAN.DUAL

Två ID:n som kommer att accepteras (t.ex. (1, 2)).

CAN.MASK

Ett (id, mask)-par (t.ex. (0x111, 0x7FF)).

  • rtr För klassiska CAN-styrenheter är detta en array av booleska värden som anger om ett filter ska acceptera ett meddelande med begäran om fjärröverföring. Om detta argument inte anges får det standardvärdet False för alla poster. Längden beror på mode:

    mode

    len(rtr)

    Anmärkningar

    CAN.LIST16

    4

    CAN.LIST32

    2

    CAN.MASK16

    2

    CAN.MASK32

    1

    För CAN FD ignoreras detta argument.

  • extframe Om True kommer bildrutan att ha en utökad identifierare (29 bitar), annars används en standardidentifierare (11 bitar).

clearfilter(bank: int, extframe: bool = False) None

Rensar och inaktiverar en filterbank:

  • bank är den klassiska CAN-styrenhetens filterbank, eller CAN FD-filterindex, som ska rensas.

  • extframe För CAN FD-styrenheter, om True rensas ett utökat filter (konfigurerat med extframe=True), annars rensas en standardidentifierare (konfigurerad med extframe=False).

any(fifo: int) bool

Returnerar True om något meddelande väntar på FIFO:n, annars False.

recv(fifo: int, list: list | None = None, *, timeout: int = 5000) list

Ta emot data på bussen:

  • fifo är ett heltal, som anger vilken FIFO som ska tas emot på

  • list är ett valfritt listobjekt som ska användas som returvärde

  • timeout är tidsgränsen i millisekunder att vänta på mottagningen.

Returvärde: En lista som innehåller fem värden.

  • Meddelandets id.

  • Ett booleskt värde som anger om meddelande-ID:t är standard eller utökat.

  • Ett booleskt värde som anger om meddelandet är ett RTR-meddelande.

  • FMI-värdet (Filter Match Index).

  • En array som innehåller datan.

Om list är None allokeras en ny lista, samt ett nytt bytes-objekt som innehåller datan (som det femte elementet i listan).

Om list inte är None ska det vara ett listobjekt med minst fem element. Det femte elementet ska vara ett memoryview-objekt som skapas från antingen en bytearray eller en array av typen ’B’ eller ’b’, och denna array måste ha tillräckligt med utrymme för minst 8 byte. Listobjektet fylls sedan i med de fyra första returvärdena ovan, och memoryview-objektet ändras i storlek på plats till datans storlek och fylls i med den datan. Samma list- och memoryview-objekt kan återanvändas i efterföljande anrop till denna metod, vilket ger ett sätt att ta emot data utan att använda heapen. Till exempel:

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

Skicka ett meddelande på bussen:

  • data är datan som ska skickas (ett heltal att skicka, eller ett buffertobjekt).

  • id är id:t för meddelandet som ska skickas.

  • timeout är tidsgränsen i millisekunder att vänta på sändningen.

  • rtr är ett booleskt värde som anger om meddelandet ska skickas som en begäran om fjärröverföring. Om rtr är True används endast längden på data för att fylla i DLC-fältet i bildrutan; de faktiska byten i data används inte.

  • extframe om True kommer bildrutan att ha en utökad identifierare (29 bitar), annars används en standardidentifierare (11 bitar).

  • fdf för CAN FD-styrenheter, om satt till True kommer bildrutan att ha ett FD-bildruteformat, vilket stöder datanyttolaster på upp till 64 byte.

  • brs för CAN FD-styrenheter, om satt till True aktiveras bithastighetsväxlingsläget, där datafasen sänds med en annan bithastighet. Se CAN.init() för konfigurationsparametrarna för databittimingen.

Om timeout är 0 placeras meddelandet i en buffert i en av tre hårdvarubuffertar och metoden returnerar omedelbart. Om alla tre buffertar används kastas ett undantag. Om timeout inte är 0 väntar metoden tills meddelandet har sänts. Om meddelandet inte kan sändas inom den angivna tiden kastas ett undantag.

Returvärde: None.

rxcallback(fifo: int, fun: Callable[[CAN, int], None] | None) None

Registrera en funktion som ska anropas när ett meddelande accepteras i en tom FIFO:

  • fifo är den mottagande FIFO:n.

  • fun är funktionen som ska anropas när FIFO:n blir icke-tom.

Återanropsfunktionen tar två argument: det första är själva CAN-objektet; det andra är ett heltal som anger orsaken till återanropet:

Orsak

Betydelse

0

Ett meddelande har accepterats i en tom FIFO.

1

FIFO:n är full.

2

Ett meddelande har gått förlorat på grund av en full FIFO.

Exempel på användning av 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)

Konstanter

Bussläge-konstanter (argumentet mode till init()):

NORMAL: int

Styrenheten deltar normalt på bussen – sänder sina egna bildrutor och bekräftar giltiga mottagna bildrutor.

LOOPBACK: int

Internt loopback-läge: styrenheten är frånkopplad från stiften och dirigerar sända bildrutor direkt tillbaka till mottagningsvägen. Användbart för självtester utan en transceiver.

SILENT: int

Avlyssningsläge (listen-only): styrenheten tar emot bildrutor men driver aldrig bussen (ingen ACK, inga sändningar). Användbart för bussavlyssning.

SILENT_LOOPBACK: int

Kombinerar SILENT och LOOPBACK: ingen stiftaktivitet och inga bekräftelser, med intern loopback av TX till RX.

Styrenhetstillstånd-konstanter (returneras av state()):

STOPPED: int

Styrenheten är helt avstängd och återställd.

ERROR_ACTIVE: int

Styrenheten är på och i Error Active-tillståndet (både TEC och REC är mindre än 96).

ERROR_WARNING: int

Styrenheten är på och i Error Warning-tillståndet (minst en av TEC eller REC är 96 eller större).

ERROR_PASSIVE: int

Styrenheten är på och i Error Passive-tillståndet (minst en av TEC eller REC är 128 eller större).

BUS_OFF: int

Styrenheten är på men deltar inte i bussaktiviteten (TEC har överskridit 255).

Filterlägen för klassisk CAN (argumentet mode till setfilter() på OpenMV Cam M4 / M7):

LIST16: int

Filtrets params-array innehåller fyra 16-bitars ID:n som kommer att accepteras.

LIST32: int

Filtrets params-array innehåller två 32-bitars ID:n som kommer att accepteras.

MASK16: int

Filtrets params-array innehåller två 16-bitars (id, mask)-par.

MASK32: int

Filtrets params-array innehåller ett 32-bitars (id, mask)-par.

Filterlägen för CAN FD (argumentet mode till setfilter() på OpenMV Cam H7 / H7 Plus / Pure Thermal):

RANGE: int

Filtrets params-array innehåller två ID:n som bildar ett intervall av accepterade ID:n.

DUAL: int

Filtrets params-array innehåller två specifika ID:n att acceptera.

MASK: int

Filtrets params-array innehåller ett (id, mask)-par.