class CAN – protokollet Controller Area Network¶
CAN är ett tvåtrådigt seriellt protokoll som används för tillförlitlig leverans av meddelanden i realtid mellan en eller flera noder anslutna till en gemensam buss. CAN 2.0 standardiserades i ISO-11898 och kallas numera även CAN Classic.
Det finns även ett nyare, bakåtkompatibelt protokoll som heter CAN FD (CAN with Flexible Data-Rate). Drivrutinen machine.CAN stöder för närvarande inte CAN FD-funktioner; använd pyb.CAN på STM32 om du behöver CAN FD.
CAN-stöd kräver en styrenhet (ofta en intern kringutrustning i mikrokontrollern) och en extern transceiver för att nivåanpassa signalerna till CAN-bussen.
Tillgängligt på STM32 OpenMV-kameror (M4 / M7 / H7 / H7 Plus / Pure Thermal / N6, samt de Arduino-märkta varianterna som har en transceiver inkopplad). Stöds ännu inte på OpenMV Cam RT1062 (mimxrt-porten) eller OpenMV Cam AE3 (alif-porten).
Gränssnittet machine.CAN är ett lågnivå-grundläggande CAN-meddelandegränssnitt som abstraherar en CAN-styrenhet som en utgående prioritetskö för att skicka meddelanden, en inkommande kö för att ta emot meddelanden, och mekanismer för att rapportera fel.
Anteckning
De planerade micropython-lib-modulerna can och aiocan kommer att vara det rekommenderade sättet att använda CAN med MicroPython.
Konstruktor¶
- class machine.CAN(id: int, *args, **kwargs)¶
Skapa ett CAN-styrenhetsobjekt med det givna id:t:
ididentifierar ett visst CAN-styrenhetsobjekt; det är kort- och portspecifikt.Alla övriga argument skickas vidare till
CAN.init(). Minst ett argument (bitrate) måste anges.
Framtida versioner av denna klass kan även komma att acceptera portspecifika nyckelordsargument här som konfigurerar hårdvaran. För närvarande finns inga sådana nyckelordsargument implementerade.
Exempel¶
Skapa och initiera CAN-styrenhet 1 med bithastigheten 500 kbps:
from machine import CAN can = CAN(1, 500_000)
Metoder¶
- init(bitrate: int, mode: int = CAN.MODE_NORMAL, sample_point: int = 75, sjw: int = 1, tseg1: int | None = None, tseg2: int | None = None) None¶
Initiera CAN-bussen med de givna parametrarna:
bitrate är den önskade bithastigheten på bussen i bitar per sekund.
mode är ett av värdena som visas under Lägen och anger det önskade driftläget. Standardvärdet är ”normal” drift på bussen.
Nästa parametrar är valfria och rör CAN-bittiming. I de flesta fall kan du lämna dessa parametrar inställda på standardvärdena:
sample_point är en heltalsprocent av databittiden. Den anger positionen för bitprovet i förhållande till hela den nominella bittiden. CAN-drivrutinen beräknar parametrarna därefter. Denna parameter ignoreras om tseg1 och tseg2 är inställda.
sjw är resynkroniseringssprångbredden i enheter av tidskvanta för nominella bitar; den kan vara ett värde mellan 1 och 4 inklusive för klassisk CAN.
tseg1 definierar provpunktens placering i enheter av tidskvanta för nominella bitar; den kan vara ett värde mellan 1 och 16 inklusive för klassisk CAN. Detta är summan av faserna
Prop_SegochPhase_Seg1enligt definitionen i standarden ISO-11898. Om detta värde anges måste även tseg2 anges och sample_point ignoreras.tseg2 definierar sändpunktens placering i enheter av tidskvanta för nominella bitar; den kan vara ett värde mellan 1 och 8 inklusive för klassisk CAN. Detta motsvarar
Phase_Seg2i standarden ISO-11898. Om detta värde anges måste även tseg1 anges.
Om dessa argument anges konfigureras CAN-styrenheten korrekt för den önskade bitrate och det angivna totala antalet tidskvanta per bit. Värdena tseg1 och tseg2 åsidosätter argumentet sample_point om alla dessa anges.
Anteckning
Enskild styrenhetshårdvara kan ha ytterligare begränsningar för giltiga värden på dessa parametrar och kommer att utlösa ett
ValueErrorom ett givet värde inte stöds.Anteckning
Specifik styrenhetshårdvara kan acceptera ytterligare valfria nyckelordsparametrar för hårdvaruspecifika funktioner såsom översampling.
- set_filters(filters: list | tuple | None) None¶
Ställ in mottagningsfilter i CAN-styrenheten. filters kan vara:
Noneför att acceptera alla inkommande meddelanden, eller[]eller()för att inaktivera all mottagning av meddelanden, ellerEn itererbar samling med en eller flera poster som definierar filterkriterierna. Varje post bör vara en tupel eller lista med tre element:
identifierär en CAN-identifierare (int).bit_maskär en bitmask för bitar i CAN-identifierarfältet (int).flagsär ett heltal med noll eller fler av bitarna som definieras i Meddelandeflaggor satta. Detta anger egenskaper som det inkommande meddelandet måste matcha. Alla styrenheter stöder inte filtrering på alla flaggor; ettValueErrorutlöses om en flagga som inte stöds begärs.
Inkommande meddelanden accepteras om bitarna som maskeras i
bit_maskmatchar mellan meddelandeidentifieraren och filtrets värdeidentifier, och flaggor satta i filtret matchar det inkommande meddelandet.Om biten
CAN.FLAG_EXT_IDär satt i flaggorna matchar filtret endast Extended CAN-ID:n. Om bitenCAN.FLAG_EXT_IDinte är satt matchar filtret endast Standard CAN-ID:n.Alla filter ELLER-kombineras i styrenheten. Att skicka en tom lista eller tupel som argumentet filters innebär att inga meddelanden kommer att tas emot.
Vissa CAN-styrenheter kräver att varje filter associeras med endast en mottagnings-FIFO. I dessa fall fördelas filterposterna i argumentet enligt round-robin till de tillgängliga FIFO:erna. Denna drivrutin skiljer inte mellan FIFO:er i mottagnings-IRQ:n.
Anteckning
Om anroparen skickar en itererbar samling med fler poster än
CAN.FILTERS_MAXutlösesValueError.Anteckning
Om antingen
identifierellerbit_maskligger utanför intervallet för den angivna ID-typen utlöses ettValueErrormed orsaken ”invalid id”.Exempel¶
Ta emot alla inkommande meddelanden:
can.set_filters(None)Ta emot endast meddelanden med Standard ID-värdena 0x301 och 0x700:
can.set_filters(((0x301, 0x7FF, 0), (0x700, 0x7FF, 0)))
Ta emot meddelanden med Standard ID-värden i intervallet 0x300-0x3FF och endast Extended ID-värdet 0x50700:
can.set_filters(((0x300, 0x700, 0), (0x50700, 0x1FFF_FFFF, CAN.FLAG_EXT_ID)))
- FILTERS_MAX: int¶
Konstant värde som läser av det maximala antalet mottagningsfilter som stöds för denna hårdvarustyrenhet.
Observera att vissa styrenheter kan ha mer komplexa hårdvarubegränsningar för antalet filter som används (till exempel genom att räkna Standard- och Extended ID-filter separat). I dessa fall kan
CAN.set_filtersutlösa ettValueErroräven när gränsenFILTERS_MAXinte överskrids.
- send(id: int, data: bytes, flags: int = 0) int | None¶
Kopiera ett nytt CAN-meddelande till styrenhetens hårdvarusändningskö för att skickas ut på bussen. Sändningskön är en prioritetskö sorterad efter CAN-identifierarprioritet (lägre numeriska identifierare har högre prioritet).
id är ett CAN-identifierarvärde av heltalstyp.
data är ett bytes-objekt (eller liknande) som innehåller CAN-meddelandedata, eller som beskriver en Remote Transmission Request (se nedan).
flags är ett heltal med noll eller fler av bitarna som definieras i Meddelandeflaggor satta, och anger egenskaper för det utgående CAN-meddelandet (Extended ID, Remote Transmission Request, osv.)
Om meddelandet köas för sändning på bussen returnerar funktionen ett heltal i intervallet
0tillCAN.TX_QUEUE_LEN(exklusivt). Detta värde är det sändningsbuffertindex där meddelandet köas för sändning och kan användas av funktionenCAN.cancel_sendoch iCAN.IRQ_TX-händelser.Om kön är full misslyckas sändningen och
Nonereturneras.Sändningen kan också misslyckas och returnera
Noneom det angivna id-värdet har samma prioritet som ett befintligt meddelande i sändningskön och CAN-styrenhetshårdvaran inte kan garantera att meddelanden med samma ID skickas ut på bussen i samma ordning som de lades till i kön. För att ändå köa meddelandet, skicka flagganCAN.FLAG_UNORDEREDi argumentet flags. Denna flagga anger att det är OK att skicka meddelanden med samma CAN-ID ut på bussen i valfri ordning.Om styrenheten befinner sig i feltillståndet ”Bus Off” eller är inaktiverad kommer ett anrop av denna funktion att utlösa ett
OSError.Anteckning
Denna avsiktligt lågnivåimplementering är utformad så att anroparen kan upprätta en mjukvarukö av utgående meddelanden.
Viktigt
CAN-”sändningskön” är inte en FIFO-kö, den är prioritetsordnad, och även om den kan rymma upp till
CAN.TX_QUEUE_LENposter kan det finnas andra hårdvarubegränsningar för meddelanden som kan köas samtidigt.Remote Transmission Requests¶
Om biten
CAN.FLAG_RTRär satt i argumentet flags skickar styrenheten en Remote Transmission Request istället för ett meddelande. I detta fall ignoreras innehållet i argumentet data. Styrenheten skickar en begäran där längdfältetDLCär lika med längden på argumentet data.Exempel¶
Försök att skicka ett meddelande med en nyttolast på tre byte
0a0b0coch Standard ID 0x200:can.send(0x200, b"\x0a\x0b\x0c", 0)Försök att skicka ett meddelande med en tom nyttolast och Extended ID 0x180008. Ange att styrenheten kan skicka meddelanden med detta ID i valfri ordning, ifall andra meddelanden redan är köade för sändning med samma ID:
can.send(0x180008, b"", can.FLAG_EXT_ID | can.FLAG_UNORDERED)Försök att skicka en Remote Transmission Request med längden 8 byte och Standard ID 0x555:
can.send(0x555, b" " * 8, can.FLAG_RTR)
- recv(arg: list | None = None) list | None¶
Returnera ett CAN-meddelande som har tagits emot av styrenheten, enligt filter inställda med
CAN.set_filters().Denna funktion tar ett enda valfritt argument; om det anges måste det vara en lista med minst 4 element där det andra elementet är ett
memoryview-objekt som refererar till ettbytearrayeller liknande objekt med tillräcklig kapacitet för att rymma vilket mottaget CAN-meddelande som helst (8 byte för CAN Classic, 64 byte för CAN FD). Den angivna listan returneras som ett lyckat resultat och undviker minnesallokering inuti funktionen.Om inga meddelanden har tagits emot av CAN-styrenheten returnerar denna funktion
None.Anteckning
CAN.set_filtersmåste anropas innan några meddelanden kan tas emot av styrenheten. För att ta emot alla meddelanden, anropaset_filters(None).Om ett meddelande har tagits emot av CAN-styrenheten returnerar denna funktion en lista med 4 element:
Index 0 är CAN-ID:t för det mottagna meddelandet, som ett heltal.
Index 1 är ett memoryview som ger åtkomst till det mottagna meddelandedatat.
Om arg inte anges är detta ett
memoryviewsom innehåller de byte som togs emot. Dettamemoryviewbackas upp av ett nyallokeratbytearraysom är tillräckligt stort för att rymma vilket mottaget CAN-meddelande som helst. Detta gör att resultatet kan återanvändas säkert som ett framtida arg, för att spara minnesallokeringar.Om arg anges kommer det tillhandahållna
memoryviewatt storleksändras så att det rymmer exakt de byte som togs emot. Anroparen ansvarar för att se till att det underliggande objektet förmemoryviewkan rymma ett CAN-meddelande av valfri längd.
Index 2 är ett heltal med noll eller fler av bitarna som definieras i Meddelandeflaggor satta. Det anger metadata om det mottagna meddelandet.
Index 3 är ett heltal med noll eller fler av bitarna som definieras i Mottagningsfelflaggor satta. Alla värden som inte är noll indikerar potentiella problem vid mottagning av CAN-meddelanden. Dessa flaggor nollställs inuti styrenheten varje gång denna funktion returnerar.
Remote Transmission Requests¶
Om en Remote Transmission Request tas emot kommer biten
CAN.FLAG_RTRatt vara satt i Index 2 och memoryview vid Index 1 kommer att innehålla enbart nollor, med en längd lika med fältetDLCi den mottagna begäran.Exempel¶
can.set_filters(None) # receive all while True: res = can.recv() if res: can_id, data, flags, errs = res print("Received", hex(can_id), data.hex(), hex(flags), hex(errs)) else: time.sleep_ms(1) # not a good pattern, use the irq instead!
- irq(handler: Callable[[CAN], None] | None = None, trigger: int = 0, hard: bool = False) None¶
Ställer in en avbrottsfunktion handler som ska anropas när en eller flera av de händelser som flaggats i trigger har inträffat.
handler är en funktion som ska anropas när avbrottshändelsen utlöses. Funktionen måste ta exakt ett argument, vilket är
CAN-instansen.trigger konfigurerar de händelser som kan generera ett avbrott. Möjliga värden är en mask med en eller flera av följande:
Händelsen
CAN.IRQ_RXinträffar efter att CAN-styrenheten har tagit emot minst ett meddelande till sin RX-FIFO (vilket innebär attCAN.recv()returnerar utan fel).Händelsen
CAN.IRQ_TXinträffar efter att CAN-styrenheten antingen har lyckats skicka ett meddelande ut på CAN-bussen eller misslyckats med att skicka ett meddelande. Denna trigger har ytterligare krav på funktionen, se IRQ-flaggor för detaljer.Händelsen
CAN.IRQ_STATEinträffar när CAN-styrenheten har övergått till ett allvarligare feltillstånd. AnropaCAN.state()för att få det uppdaterade tillståndet.
hard om True används ett hårt avbrott. Detta minskar fördröjningen mellan CAN-styrenhetshändelsen och att funktionen anropas. Hårda avbrottsfunktioner får inte allokera minne; se Skriva avbrottshanterare.
Returnerar ett irq-objekt. Om den anropas utan argument returneras ett tidigare konfigurerat irq-objekt.
Se IRQ-flaggor för ett exempel.
- cancel_send(index: int) bool¶
Begär att CAN-styrenheten avbryter sändningen av ett meddelande ut på bussen.
Argumentet index identifierar en enskild sändningsbuffert. Det bör vara ett heltal i intervallet
0tillCAN.TX_QUEUE_LEN(exklusivt). Vanligtvis är detta ett värde som tidigare returnerats avCAN.send().Resultatet är
Trueom ett meddelande väntade på sändning i denna buffert och sändningen avbröts.Resultatet är
Falseannars (antingen väntade inget meddelande på sändning i denna buffert, eller så lyckades sändningen redan).IRQ-händelsen
CAN.IRQ_TXbör användas för att avgöra om ett meddelande definitivt skickades eller inte, men observera att det finns potentiella kapplöpningstillstånd om en sändning avbryts och samma buffert sedan används för att skicka ett annat meddelande (särskilt om CAN-styrenhetens IRQ inte är ”hård”).
- state() int¶
Returnerar ett heltalsvärde som anger styrenhetens aktuella tillstånd. Värdet kommer att vara ett av värdena som definieras i Tillstånd.
Feltillstånd med lägre allvarlighetsgrad kan rensas automatiskt om bussen återhämtar sig, men tillståndet
CAN.STATE_BUS_OFFkan endast återställas genom att anropaCAN.restart().
- get_counters(list: list | None = None, /) list¶
Returnerar styrenhetens felräknarvärden. Resultatet är en lista med åtta värden. Om den valfria parametern list anges uppdateras det angivna listobjektet och returneras som resultat, för att undvika en allokering.
Listposterna är:
Värdet TEC (Transmit Error Counter)
Värdet REC (Receive Error Counter)
Antal gånger styrenheten gick in i Warning-tillståndet från Active-tillståndet.
Antal gånger styrenheten gick in i Error Passive-tillståndet från Warning-tillståndet.
Antal gånger styrenheten gick in i Bus Off-tillståndet från Error Passive-tillståndet.
Totalt antal väntande TX-meddelanden i hårdvarukön.
Totalt antal väntande RX-meddelanden i hårdvarukön.
Antal gånger ett RX-överflöde inträffade.
Anteckning
Beroende på styrenheten kan dessa värden svämma över tillbaka till 0 efter ett visst värde.
Anteckning
Om en styrenhet inte stöder en viss räknare returnerar den
Noneför det listelementet.
- get_timings(list: list | None = None, /) list¶
Returnerar en lista med element som anger de aktuella timinginställningarna i CAN-styrenheten. Detta kan användas för att verifiera timing i felsökningssyfte. Resultatet är en lista med sex värden. Om den valfria parametern list anges uppdateras det angivna listobjektet och returneras som resultat, för att undvika en allokering.
Listposterna är:
Exakt bithastighet som styrenheten använder. Kan avvika från argumentet bitrate som skickades till
CAN.init()på grund av kvantisering för att uppfylla hårdvarubegränsningar.Resynkroniseringssprångbredd (SJW) i enheter av tidskvanta för nominella bitar. Har samma betydelse som parametern sjw i
CAN.init().Provpunktens placering i enheter av tidskvanta för nominella bitar. Har samma betydelse som parametern tseg1 i
CAN.init().Sändpunktens placering i enheter av tidskvanta för nominella bitar. Har samma betydelse som parametern tseg2 i
CAN.init().Timinginformation för CAN FD.
Noneför styrenheter som inte stöder CAN FD, eller om CAN FD inte är initierat. Annars en nästlad lista med fyra element som motsvarar posterna ovan men gäller CAN FD BRS-funktionen.Valfri styrenhetsspecifik timinginformation. Beroende på styrenheten är detta antingen
Noneom styrenheten inte rapporterar någon, eller så är det en lista med konstant längd vars element är specifika för en viss hårdvarustyrenhet.
Anteckning
Om
CAN.init()inte har anropats returnerar denna funktion fortfarande ett resultat, men resultatet beror på styrenhetens interna tillstånd och kanske inte är korrekt.
- restart() None¶
Får styrenheten att lämna
STATE_BUS_OFFutan att rensa något annat internt tillstånd. Rensar även en del av felräknarna (alltid antalet gånger varje feltillstånd har inträtts, möjligen TEC och REC beroende på styrenheten.)Anrop av denna funktion avbryter även alla meddelanden som väntar på att skickas. Inga
IRQ_TX-avbrott levereras för dessa meddelanden.Observera att denna funktion kan komma att få styrenheten att lämna tillståndet ”Error Passive”, beroende på om styrenhetshårdvaran nollställer TEC och REC eller inte.
- deinit() None¶
Avinitierar en tidigare aktiv CAN-instans. Alla väntande meddelanden (sändning och mottagning) släpps och styrenheten slutar interagera på bussen. För att använda denna instans igen, anropa
CAN.init().Inga
IRQ_TX- ellerIRQ_RX-avbrott anropas som svar på anrop av denna funktion.Se även
CAN.restart().
Konstanter¶
- TX_QUEUE_LEN: int¶
Maximalt antal CAN-meddelanden som kan köas i styrenhetens utgående hårdvarumeddelandekö. ”Sändningsbuffertindexen” som används av
CAN.send(),CAN.cancel_send()och IRQ-flaggor kommer att ligga i detta intervall.
Lägen¶
Dessa värden representerar styrenhetens driftlägen, som skickas till
CAN.init(). Alla styrenheter stöder kanske inte alla lägen.Att ändra läget på en igångvarande styrenhet kräver att man anropar
CAN.deinit()och sedan anroparCAN.init()igen med det nya läget.- MODE_NORMAL: int¶
Styrenheten är aktiv som en standard CAN-nätverksnod (kommer att bekräfta giltiga meddelanden och kan sända fel beroende på dess aktuella tillstånd).
- MODE_SLEEP: int¶
CAN-styrenheten är i viloläge i ett lågeffektsläge. Beroende på styrenheten kan detta stödja väckning av styrenheten och övergång till
CAN.MODE_NORMALom CAN-trafik tas emot.
- MODE_LOOPBACK: int¶
Ett testläge. CAN-styrenheten är fortfarande ansluten till den externa bussen, men kommer även att ta emot sina egna sända meddelanden och ignorera eventuella ACK-fel.
Tillstånd¶
Dessa värden returneras av
CAN.state()och återspeglar CAN-styrenhetens feltillstånd:- STATE_ACTIVE: int¶
Styrenheten är aktiv och felräknarna
TECochRECligger båda under varningströskeln 96. SeCAN.get_counters().
- STATE_WARNING: int¶
Styrenheten är aktiv men minst en av felräknarna
TECochRECligger mellan 96 och 127. SeCAN.get_counters().
- STATE_PASSIVE: int¶
Styrenheten är i tillståndet ”Error Passive”, vilket innebär att den inte längre sänder aktiva fel till bussen, men den är i övrigt funktionsduglig. Detta tillstånd inträder när minst en av felräknarna
TECochRECär 128 eller större, menTECär mindre än 255. SeCAN.get_counters().
- STATE_BUS_OFF: int¶
Styrenheten är i Bus-Off-tillståndet, vilket innebär att felräknaren
TECär större än 255. CAN-styrenheten interagerar inte med bussen i detta tillstånd och behöver startas om viaCAN.restart()för att fortsätta.
Meddelandeflaggor¶
Dessa värden representerar metadata om ett CAN-meddelande. Funktionerna
CAN.send(),CAN.recv()ochCAN.set_filters()accepterar eller returnerar ett heltalsvärde bestående av noll eller fler av dessa flaggor bitvis ELLER-kombinerade.- FLAG_EXT_ID: int¶
Om satt anger den att en meddelandeidentifierare är Extended (29-bitars). Om inte satt anger den att en meddelandeidentifierare är Standard (11-bitars).
- FLAG_UNORDERED: int¶
Om satt i argumentet
flagstillCAN.send()anger den att det är OK om meddelanden med samma CAN-ID skickas i valfri ordning ut på bussen.Annars kan försök att köa flera meddelanden med samma ID resultera i att
CAN.send()misslyckas om styrenhetshårdvaran inte kan upprätthålla ordning.Denna flagga sätts aldrig på mottagna meddelanden och ignoreras av
CAN.set_filters().
Mottagningsfelflaggor¶
Resultatet av
CAN.recv()innehåller ett heltalsvärde bestående av noll eller fler av dessa flaggor bitvis ELLER-kombinerade. Om satta anger dessa flaggor potentiella allmänna problem med mottagning av CAN-meddelanden.IRQ-värden¶
- IRQ_RX: int¶
Skicka till argumentet
triggeriirq()för att utlösa funktionen varje gång CAN-styrenheten har tagit emot ett komplett meddelande till RX-FIFO:n. Läs meddelandet inuti funktionen medrecv().
- IRQ_TX: int¶
Skicka till argumentet
triggeriirq()för att utlösa funktionen varje gång CAN-styrenheten avslutar ett sändningsförsök (lyckat eller misslyckat). Använd inuti funktionen de ytterligare bitarna nedan för att ta reda på vilken brevlåda som slutfördes och om den misslyckades – se IRQ-flaggor.
- IRQ_STATE: int¶
Skicka till argumentet
triggeriirq()för att utlösa funktionen varje gång styrenheten övergår mellan värdenaSTATE_*(active / warning / passive / bus-off). Användstate()inuti funktionen för att läsa det nya tillståndet.
- IRQ_TX_FAILED: int¶
Statusflagga som kan sättas i
irq().flags()när enIRQ_TX-händelse utlöses. Anger att sändningsförsöket misslyckades (vanligtvis för attcancel_send()anropades, eller för att styrenheten gick in i ett feltillstånd).
- IRQ_TX_IDX_SHIFT: int¶
Bitposition för fältet sändnings-brevlådeindex inom värdet
irq().flags()under enIRQ_TX-händelse. Brevlådeindexet extraheras som(flags >> IRQ_TX_IDX_SHIFT) & IRQ_TX_IDX_MASK.
- IRQ_TX_IDX_MASK: int¶
Bitmask för fältet sändnings-brevlådeindex inom värdet
irq().flags()under enIRQ_TX-händelse. Det extraherade indexet matchar heltalet som returnerades av motsvarandesend()-anrop (ett int i intervallet0tillTX_QUEUE_LEN).
IRQ-flaggor¶
Anrop av CAN.irq() registrerar en avbrottsfunktion med en eller flera av triggrarna CAN.IRQ_RX, CAN.IRQ_TX och CAN.IRQ_STATE.
Funktionen returnerar ett IRQ-objekt, och att anropa funktionen flags() på detta objekt returnerar ett heltal som anger vilken eller vilka triggerhändelser som utlöste avbrottet. En CAN IRQ-funktion bör anropa funktionen flags() upprepade gånger tills den returnerar 0.
När funktionen flags() returnerar med biten CAN.IRQ_TX satt kan funktionen även kontrollera följande flaggbitar i resultatet för ytterligare information om TX-händelsen:
Biten
CAN.IRQ_TX_FAILEDär satt om sändningen misslyckades. Vanligtvis händer detta endast omCAN.cancel_send()anropades, även om det också kan hända om styrenheten går in i ett feltillstånd.CAN.IRQ_TX_IDX_MASK << CAN.IRQ_TX_IDX_SHIFTär ett bitmaskat område av flaggvärdet som innehåller indexet för den sändningsbuffert som genererade händelsen. Detta kommer att vara ett heltal i intervallet0tillCAN.TX_QUEUE_LEN(exklusivt), och kommer att matcha resultatet av ett tidigare anrop tillCAN.send().
IRQ_TX-exempel¶
from machine import CAN
def irq_send(can):
while flags := can.irq().flags():
if flags & can.IRQ_TX:
idx = (flags >> can.IRQ_TX_IDX_SHIFT) & can.IRQ_TX_IDX_MASK
success = not (flags & can.IRQ_TX_FAILED)
print("irq_send", idx, success)
can = CAN(1, 500_000)
can.irq(irq_send, trigger=can.IRQ_TX, hard=True)
Viktigt
Om triggern CAN.IRQ_TX är satt måste funktionen anropa flags() upprepade gånger tills den returnerar 0, som visas i detta exempel. Annars kanske CAN-avbrott inte återaktiveras korrekt.