class CAN – magistrală de comunicație controller area network¶
CAN oferă suport atât pentru CAN clasic (bxCAN, utilizat pe OpenMV Cam M4 și M7), cât și pentru CAN FD (FDCAN, utilizat pe OpenMV Cam H7, H7 Plus și Pure Thermal). La nivel fizic, magistrala CAN constă din două linii, RX și TX. Pentru a conecta o OpenMV Cam la o magistrală CAN trebuie să folosiți un transceiver CAN pentru a converti semnalele logice CAN de la MCU la nivelurile de tensiune corecte de pe magistrală.
CAN clasic în mod buclă (loopback, fără 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 cu toate caracteristicile opționale activate (cadru FD, comutarea ratei de biți, ID-uri de cadru extinse; fază de arbitrare de 500 kbit/s, fază de date de 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)
Următoarele funcții ale modulului CAN și argumentele lor sunt disponibile atât pentru controlerele CAN clasice, cât și pentru cele FD, dacă nu se specifică altfel.
Constructori¶
- class pyb.CAN(bus: int | str, *args, **kwargs)¶
Construiește un obiect CAN pe magistrala
busdată (un index întreg al perifericului, de exemplu1pentruCAN1,2pentruCAN2). Fără parametri suplimentari, obiectul este creat dar nu este inițializat (păstrează setările anterioare ale magistralei, dacă există); dacă se furnizează argumente suplimentare, magistrala este inițializată. ConsultațiCAN.init()pentru parametrii disponibili.CAN(2)este conectat la aceiași pini de antet pe fiecare OpenMV Cam care expunepyb.CAN(M4 / M7 / H7 / H7 Plus / Pure Thermal):Semnal
Pin de antet
Note
RXP3TXP2Perifericul CAN furnizează doar semnale la nivel logic; un transceiver CAN extern este necesar pentru a comanda o magistrală CAN reală.
pyb.CANnu este disponibil pe OpenMV Cam N6.Metode¶
- 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¶
Inițializează magistrala CAN cu parametrii dați:
mode este unul dintre: NORMAL, LOOPBACK, SILENT, SILENT_LOOPBACK
prescaler este valoarea cu care ceasul de intrare CAN este divizat pentru a genera cuantele de timp nominale ale bitului. Prescaler-ul poate fi o valoare între 1 și 1024 inclusiv pentru CAN clasic și între 1 și 512 inclusiv pentru CAN FD.
sjw este lățimea saltului de resincronizare în unități de cuante de timp pentru biții nominali; poate fi o valoare între 1 și 4 inclusiv pentru CAN clasic și între 1 și 128 inclusiv pentru CAN FD.
bs1 definește poziția punctului de eșantionare în unități de cuante de timp pentru biții nominali; poate fi o valoare între 1 și 16 inclusiv pentru CAN clasic și între 2 și 256 inclusiv pentru CAN FD.
bs2 definește poziția punctului de transmisie în unități de cuante de timp pentru biții nominali; poate fi o valoare între 1 și 8 inclusiv pentru CAN clasic și între 2 și 128 inclusiv pentru CAN FD.
auto_restart stabilește dacă controlerul va încerca automat să repornească comunicațiile după intrarea în starea bus-off; dacă acest lucru este dezactivat, atunci
restart()poate fi folosit pentru a părăsi starea bus-offbaudrate dacă se furnizează o rată baud diferită de 0, această funcție va încerca să calculeze automat timpul nominal al bitului CAN (suprascriind prescaler, bs1 și bs2) care satisface atât baudrate (în limita a .1%), cât și sample_point dorit (la cel mai apropiat 1%). Pentru un control mai precis al sincronizării CAN, setați direct parametrii prescaler, bs1 și bs2.
sample_point specifică poziția eșantionului bitului în raport cu întregul timp nominal al bitului, exprimată ca procent întreg din timpul nominal al bitului. Valoarea implicită pentru sample_point este 75%. Acest parametru este ignorat dacă baudrate nu este setat.
num_filter_banks pentru CAN clasic, acesta este numărul de bănci care vor fi atribuite lui CAN(1), restul celor 28 fiind atribuite lui CAN(2).
Parametrii rămași sunt prezenți doar pe plăcile cu suport CAN FD și configurează caracteristica opțională CAN FD Bit Rate Switch (BRS):
brs_prescaler este valoarea cu care ceasul de intrare CAN FD este divizat pentru a genera cuantele de timp ale bitului de date. Prescaler-ul poate fi o valoare între 1 și 32 inclusiv.
brs_sjw este lățimea saltului de resincronizare în unități de cuante de timp pentru biții de date; poate fi o valoare între 1 și 16 inclusiv
brs_bs1 definește poziția punctului de eșantionare în unități de cuante de timp pentru biții de date; poate fi o valoare între 1 și 32 inclusiv
brs_bs2 definește poziția punctului de transmisie în unități de cuante de timp pentru biții de date; poate fi o valoare între 1 și 16 inclusiv
brs_baudrate dacă se furnizează o rată baud diferită de 0, această funcție va încerca să calculeze automat timpul bitului de date CAN (suprascriind brs_prescaler, brs_bs1 și brs_bs2) care satisface atât brs_baudrate (în limita a .1%), cât și brs_sample_point dorit (la cel mai apropiat 1%). Pentru un control mai precis al sincronizării BRS, setați direct parametrii brs_prescaler, brs_bs1 și brs_bs2.
brs_sample_point specifică poziția eșantionului bitului în raport cu întregul timp nominal al bitului, exprimată ca procent întreg din timpul nominal al bitului. Valoarea implicită pentru brs_sample_point este 75%. Acest parametru este ignorat dacă brs_baudrate nu este setat.
Cuanta de timp tq este unitatea de bază de timp pentru magistrala CAN. tq este valoarea prescaler-ului CAN divizată la PCLK1 (frecvența magistralei interne de periferice 1); consultați
pyb.freq()pentru a determina PCLK1.Un singur bit este compus din segmentul de sincronizare, care este întotdeauna 1 tq. Apoi urmează segmentul de bit 1, apoi segmentul de bit 2. Punctul de eșantionare este după ce se termină segmentul de bit 1. Punctul de transmisie este după ce se termină segmentul de bit 2. Rata baud va fi 1/bittime, unde bittime este 1 + BS1 + BS2 înmulțit cu cuanta de timp tq.
De exemplu, pe OpenMV Cam H7 (PCLK1 = 100 MHz), CAN la 250 kbps cu un punct de eșantionare de 75% poate fi configurat ca
prescaler=25, sjw=1, bs1=11, bs2=4:tq = 25 / 100 MHz = 250 ns,bittime = (1 + 11 + 4) × 250 ns = 4 µs, punctul de eșantionare =(1 + 11) / 16 = 75%, iar rata baud este1 / 4 µs = 250 kHz.Consultați secțiunea bxCAN / FDCAN din manualul de referință STM32 pentru MCU-ul OpenMV Cam pentru mai multe detalii.
- restart() None¶
Forțează o repornire software a controlerului CAN fără a-i reseta configurația.
Dacă controlerul intră în starea bus-off, atunci nu va mai participa la activitatea de pe magistrală. Dacă controlerul nu este configurat să repornească automat (consultați
init()), atunci această metodă poate fi folosită pentru a declanșa o repornire, iar controlerul va urma protocolul CAN pentru a părăsi starea bus-off și a intra în starea error active.
- state() int¶
Returnează starea controlerului. Valoarea returnată poate fi una dintre:
CAN.STOPPED– controlerul este complet oprit și resetat;CAN.ERROR_ACTIVE– controlerul este pornit și în starea Error Active (atât TEC, cât și REC sunt mai mici decât 96);CAN.ERROR_WARNING– controlerul este pornit și în starea Error Warning (cel puțin unul dintre TEC sau REC este 96 sau mai mare);CAN.ERROR_PASSIVE– controlerul este pornit și în starea Error Passive (cel puțin unul dintre TEC sau REC este 128 sau mai mare);CAN.BUS_OFF– controlerul este pornit dar nu participă la activitatea de pe magistrală (TEC a depășit 255).
- info(list: list | None = None) list¶
Obține informații despre stările de eroare ale controlerului și despre tampoanele TX și RX. Dacă se furnizează list, atunci acesta ar trebui să fie un obiect listă cu cel puțin 8 intrări, care vor fi completate cu informațiile. În caz contrar, va fi creată și completată o nouă listă. În ambele cazuri, valoarea returnată de metodă este lista completată.
Valorile din listă sunt:
valoarea TEC
valoarea REC
numărul de dăți în care controlerul a intrat în starea Error Warning (revine la 0 după 65535)
numărul de dăți în care controlerul a intrat în starea Error Passive (revine la 0 după 65535)
numărul de dăți în care controlerul a intrat în starea Bus Off (revine la 0 după 65535)
numărul de mesaje TX în așteptare
numărul de mesaje RX în așteptare pe fifo 0
numărul de mesaje RX în așteptare pe fifo 1
- setfilter(bank: int, mode: int, fifo: int, params: Tuple[int, ...], *, rtr: Tuple[bool, ...] | None = None, extframe: bool = False) None¶
Configurează o bancă de filtre:
bank este banca de filtre a controlerului CAN clasic sau indexul de filtru CAN FD de configurat.
mode este modul în care ar trebui să funcționeze filtrul, consultați tabelele de mai jos.
fifo este fifo-ul (0 sau 1) în care ar trebui stocat un mesaj, dacă este acceptat de acest filtru.
params este o matrice de valori care definește filtrul. Conținutul matricei depinde de argumentul mode.
Conținutul matricei params pentru controlerele CAN clasic (OpenMV Cam M4 / M7):
mode
Conținutul lui params
CAN.LIST16Patru ID-uri pe 16 biți care vor fi acceptate.
CAN.LIST32Două ID-uri pe 32 de biți care vor fi acceptate.
CAN.MASK16Două perechi id/mască pe 16 biți, de exemplu
(1, 3, 4, 4). Prima pereche (1, 3) acceptă toate ID-urile cu bitul 0 = 1 și bitul 1 = 0; a doua pereche (4, 4) acceptă toate ID-urile cu bitul 2 = 1.CAN.MASK32O pereche id/mască pe 32 de biți (altfel la fel ca
CAN.MASK16).Conținutul matricei params pentru controlerele CAN FD (OpenMV Cam H7 / H7 Plus / Pure Thermal):
mode
Conținutul lui params
CAN.RANGEDouă ID-uri care formează un interval de ID-uri acceptate.
CAN.DUALDouă ID-uri care vor fi acceptate (de exemplu
(1, 2)).CAN.MASKO pereche
(id, mask)(de exemplu(0x111, 0x7FF)).rtr Pentru controlerele CAN clasice, acesta este o matrice de valori booleene care stabilește dacă un filtru ar trebui să accepte un mesaj de cerere de transmisie la distanță. Dacă acest argument nu este dat, valoarea implicită este
Falsepentru toate intrările. Lungimea depinde de mode:mode
len(rtr)Note
CAN.LIST164
CAN.LIST322
CAN.MASK162
CAN.MASK321
Pentru CAN FD acest argument este ignorat.
extframe Dacă este True, cadrul va avea un identificator extins (29 de biți), altfel se folosește un identificator standard (11 biți).
- clearfilter(bank: int, extframe: bool = False) None¶
Șterge și dezactivează o bancă de filtre:
bank este banca de filtre a controlerului CAN clasic sau indexul de filtru CAN FD de șters.
extframe Pentru controlerele CAN FD, dacă este True, șterge un filtru extins (configurat cu extframe=True), altfel șterge un identificator standard (configurat cu extframe=False).
- recv(fifo: int, list: list | None = None, *, timeout: int = 5000) list¶
Recepționează date pe magistrală:
fifo este un întreg, care reprezintă FIFO-ul pe care se recepționează
list este un obiect listă opțional care va fi folosit ca valoare returnată
timeout este timpul de așteptare în milisecunde pentru recepție.
Valoare returnată: O listă conținând cinci valori.
ID-ul mesajului.
O valoare booleană care indică dacă ID-ul mesajului este standard sau extins.
O valoare booleană care indică dacă mesajul este un mesaj RTR.
Valoarea FMI (Filter Match Index).
O matrice conținând datele.
Dacă list este
None, atunci va fi alocată o nouă listă, precum și un nou obiect bytes pentru a conține datele (ca al cincilea element din listă).Dacă list nu este
None, atunci ar trebui să fie un obiect listă cu cel puțin cinci elemente. Al cincilea element ar trebui să fie un obiect memoryview creat fie dintr-un bytearray, fie dintr-o matrice de tip «B» sau «b», iar această matrice trebuie să aibă suficient spațiu pentru cel puțin 8 octeți. Obiectul listă va fi apoi completat cu primele patru valori returnate de mai sus, iar obiectul memoryview va fi redimensionat pe loc la dimensiunea datelor și completat cu acele date. Aceleași obiecte listă și memoryview pot fi reutilizate în apelurile ulterioare ale acestei metode, oferind o modalitate de a recepționa date fără a folosi heap-ul. De exemplu: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¶
Trimite un mesaj pe magistrală:
data sunt datele de trimis (un întreg de trimis sau un obiect tampon).
id este ID-ul mesajului care urmează să fie trimis.
timeout este timpul de așteptare în milisecunde pentru trimitere.
rtr este o valoare booleană care specifică dacă mesajul va fi trimis ca o cerere de transmisie la distanță. Dacă rtr este True, atunci doar lungimea lui data este folosită pentru a completa slotul DLC al cadrului; octeții efectivi din data nu sunt folosiți.
extframe dacă este True, cadrul va avea un identificator extins (29 de biți), altfel se folosește un identificator standard (11 biți).
fdf pentru controlerele CAN FD, dacă este setat la True, cadrul va avea un format de cadru FD, care suportă sarcini utile de date de până la 64 de octeți.
brs pentru controlerele CAN FD, dacă este setat la True, se activează modul de comutare a ratei de biți, în care faza de date este transmisă la o rată de biți diferită. Consultați
CAN.init()pentru parametrii de configurare a sincronizării bitului de date.
Dacă timeout este 0, mesajul este plasat într-un tampon dintr-unul din cele trei tampoane hardware și metoda revine imediat. Dacă toate cele trei tampoane sunt în uz, este aruncată o excepție. Dacă timeout nu este 0, metoda așteaptă până când mesajul este transmis. Dacă mesajul nu poate fi transmis în intervalul de timp specificat, este aruncată o excepție.
Valoare returnată:
None.
- rxcallback(fifo: int, fun: Callable[[CAN, int], None] | None) None¶
Înregistrează o funcție care va fi apelată atunci când un mesaj este acceptat într-un FIFO gol:
fifo este FIFO-ul de recepție.
fun este funcția care va fi apelată atunci când FIFO-ul devine ne-gol.
Funcția de retroapelare (callback) primește două argumente: primul este obiectul CAN însuși; al doilea este un întreg care indică motivul retroapelării:
Motiv
Semnificație
0Un mesaj a fost acceptat într-un FIFO gol.
1FIFO-ul este plin.
2Un mesaj a fost pierdut din cauza unui FIFO plin.
Exemplu de utilizare a 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)
Constante¶
Constante de mod al magistralei (argumentul
modealinit()):- NORMAL: int¶
Controlerul participă normal pe magistrală – transmite propriile cadre și confirmă cadrele valide recepționate.
- LOOPBACK: int¶
Mod de buclă internă: controlerul este deconectat de la pini și direcționează cadrele transmise direct înapoi pe calea de recepție. Util pentru autoteste fără un transceiver.
- SILENT: int¶
Mod doar de ascultare: controlerul recepționează cadre dar nu comandă niciodată magistrala (fără ACK, fără transmisii). Util pentru monitorizarea magistralei.
- SILENT_LOOPBACK: int¶
Combină
SILENTșiLOOPBACK: fără activitate pe pini și fără confirmări, cu buclă internă a TX în RX.
Constante de stare a controlerului (returnate de
state()):- ERROR_ACTIVE: int¶
Controlerul este pornit și în starea Error Active (atât TEC, cât și REC sunt mai mici decât 96).
- ERROR_WARNING: int¶
Controlerul este pornit și în starea Error Warning (cel puțin unul dintre TEC sau REC este 96 sau mai mare).
- ERROR_PASSIVE: int¶
Controlerul este pornit și în starea Error Passive (cel puțin unul dintre TEC sau REC este 128 sau mai mare).
- BUS_OFF: int¶
Controlerul este pornit dar nu participă la activitatea de pe magistrală (TEC a depășit 255).
Moduri de filtru CAN clasic (argumentul
modealsetfilter()pe OpenMV Cam M4 / M7):Moduri de filtru CAN FD (argumentul
modealsetfilter()pe OpenMV Cam H7 / H7 Plus / Pure Thermal):