الفئة CAN -- ناقل اتصالات شبكة منطقة التحكم (controller area network)¶
يطبّق CAN الدعم لكل من CAN الكلاسيكي (bxCAN، المستخدم في OpenMV Cam M4 وM7) وCAN FD (FDCAN، المستخدم في OpenMV Cam H7 وH7 Plus وPure Thermal). على المستوى الفيزيائي يتكوّن ناقل CAN من خطين، RX وTX. لتوصيل OpenMV Cam بناقل CAN يجب عليك استخدام جهاز إرسال واستقبال CAN لتحويل إشارات منطق CAN من وحدة التحكم الدقيقة (MCU) إلى مستويات الجهد الصحيحة على الناقل.
CAN الكلاسيكي في وضع الاسترجاع الحلقي (بدون جهاز إرسال واستقبال):
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 مع تمكين جميع الميزات الاختيارية (إطار FD، تبديل معدل البت، معرّفات الإطار الممتدة؛ مرحلة تحكيم بسرعة 500 kbit/s، مرحلة بيانات بسرعة 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)
دوال وحدة CAN التالية ووسائطها متاحة لكل من وحدتي تحكم CAN الكلاسيكية وFD، ما لم يُذكر خلاف ذلك.
المُنشِئات¶
- class pyb.CAN(bus: int | str, *args, **kwargs)¶
ينشئ كائن CAN على
busالمعطى (فهرس طرفية صحيح، مثلاً1لـCAN1، و2لـCAN2). بدون معاملات إضافية يُنشأ الكائن لكن لا تتم تهيئته (فيحتفظ بإعدادات الناقل السابقة، إن وُجدت)؛ أما إذا أُعطيت وسائط إضافية فتتم تهيئة الناقل. انظرCAN.init()للاطلاع على المعاملات المتاحة.CAN(2)موصول بدبابيس الترويسة نفسها على كل OpenMV Cam يُتيحpyb.CAN(M4 / M7 / H7 / H7 Plus / Pure Thermal):الإشارة
دبوس الترويسة
ملاحظات
RXP3TXP2توفّر طرفية CAN إشارات على مستوى المنطق فقط؛ يلزم جهاز إرسال واستقبال CAN خارجي لقيادة ناقل CAN حقيقي.
pyb.CANغير متاح على OpenMV Cam N6.الطرائق¶
- 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¶
تهيئة ناقل CAN بالمعاملات المعطاة:
mode هو أحد التالي: NORMAL، LOOPBACK، SILENT، SILENT_LOOPBACK
prescaler هو القيمة التي يُقسَّم بها ساعة دخل CAN لتوليد كمّات زمن البت الاسمي. يمكن أن يكون المقسّم المسبق قيمة بين 1 و1024 شاملة لـ CAN الكلاسيكي، وبين 1 و512 شاملة لـ CAN FD.
sjw هو عرض قفزة إعادة التزامن بوحدات كمّات الزمن للبتات الاسمية؛ ويمكن أن يكون قيمة بين 1 و4 شاملة لـ CAN الكلاسيكي، وبين 1 و128 شاملة لـ CAN FD.
bs1 يحدّد موقع نقطة أخذ العينة بوحدات كمّات الزمن للبتات الاسمية؛ ويمكن أن يكون قيمة بين 1 و16 شاملة لـ CAN الكلاسيكي، وبين 2 و256 شاملة لـ CAN FD.
bs2 يحدّد موقع نقطة الإرسال بوحدات كمّات الزمن للبتات الاسمية؛ ويمكن أن يكون قيمة بين 1 و8 شاملة لـ CAN الكلاسيكي، وبين 2 و128 شاملة لـ CAN FD.
auto_restart يحدّد ما إذا كانت وحدة التحكم ستحاول تلقائياً إعادة تشغيل الاتصالات بعد دخولها حالة الانفصال عن الناقل (bus-off)؛ فإذا كان هذا معطّلاً يمكن استخدام
restart()لمغادرة حالة الانفصال عن الناقلbaudrate إذا وُفِّر معدل باود غير 0، فستحاول هذه الدالة حساب زمن البت الاسمي لـ CAN تلقائياً (متجاوزةً prescaler وbs1 وbs2) بما يحقّق كلاً من baudrate (ضمن .1%) ونقطة العينة المرغوبة sample_point (لأقرب 1%). للتحكم الأدق في توقيت CAN، اضبط معاملات prescaler وbs1 وbs2 مباشرة.
sample_point يحدّد موضع أخذ عينة البت بالنسبة إلى زمن البت الاسمي الكامل، معبَّراً عنه كنسبة مئوية صحيحة من زمن البت الاسمي. القيمة الافتراضية لـ sample_point هي 75%. يُتجاهَل هذا المعامل ما لم يُضبَط baudrate.
num_filter_banks لـ CAN الكلاسيكي، هذا هو عدد البنوك التي ستُخصَّص لـ CAN(1)، وتُخصَّص بقية البنوك الـ 28 لـ CAN(2).
المعاملات المتبقية موجودة فقط على اللوحات الداعمة لـ CAN FD، وهي تُهيّئ ميزة تبديل معدل البت الاختيارية في CAN FD (BRS):
brs_prescaler هو القيمة التي يُقسَّم بها ساعة دخل CAN FD لتوليد كمّات زمن بت البيانات. يمكن أن يكون المقسّم المسبق قيمة بين 1 و32 شاملة.
brs_sjw هو عرض قفزة إعادة التزامن بوحدات كمّات الزمن لبتات البيانات؛ ويمكن أن يكون قيمة بين 1 و16 شاملة
brs_bs1 يحدّد موقع نقطة أخذ العينة بوحدات كمّات الزمن لبتات البيانات؛ ويمكن أن يكون قيمة بين 1 و32 شاملة
brs_bs2 يحدّد موقع نقطة الإرسال بوحدات كمّات الزمن لبتات البيانات؛ ويمكن أن يكون قيمة بين 1 و16 شاملة
brs_baudrate إذا وُفِّر معدل باود غير 0، فستحاول هذه الدالة حساب زمن بت بيانات CAN تلقائياً (متجاوزةً brs_prescaler وbrs_bs1 وbrs_bs2) بما يحقّق كلاً من brs_baudrate (ضمن .1%) ونقطة العينة المرغوبة brs_sample_point (لأقرب 1%). للتحكم الأدق في توقيت BRS، اضبط معاملات brs_prescaler وbrs_bs1 وbrs_bs2 مباشرة.
brs_sample_point يحدّد موضع أخذ عينة البت بالنسبة إلى زمن البت الاسمي الكامل، معبَّراً عنه كنسبة مئوية صحيحة من زمن البت الاسمي. القيمة الافتراضية لـ brs_sample_point هي 75%. يُتجاهَل هذا المعامل ما لم يُضبَط brs_baudrate.
كمّة الزمن tq هي الوحدة الأساسية للزمن في ناقل CAN. tq هي قيمة المقسّم المسبق لـ CAN مقسومة على PCLK1 (تردد ناقل الطرفيات الداخلي 1)؛ انظر
pyb.freq()لتحديد PCLK1.يتألف البت الواحد من قطعة التزامن، التي تساوي دائماً 1 tq. ثم تليها قطعة البت 1، ثم قطعة البت 2. تقع نقطة أخذ العينة بعد انتهاء قطعة البت 1. وتقع نقطة الإرسال بعد انتهاء قطعة البت 2. ويكون معدل الباود 1/bittime، حيث bittime هو 1 + BS1 + BS2 مضروباً في كمّة الزمن tq.
على سبيل المثال، على OpenMV Cam H7 (PCLK1 = 100 MHz)، يمكن تهيئة CAN بسرعة 250 kbps بنقطة عينة 75% على النحو التالي
prescaler=25, sjw=1, bs1=11, bs2=4:tq = 25 / 100 MHz = 250 ns، وbittime = (1 + 11 + 4) × 250 ns = 4 µs، ونقطة العينة =(1 + 11) / 16 = 75%، ويكون معدل الباود1 / 4 µs = 250 kHz.انظر قسم bxCAN / FDCAN في دليل مرجع STM32 الخاص بوحدة التحكم الدقيقة (MCU) في OpenMV Cam لمزيد من التفاصيل.
- restart() None¶
فرض إعادة تشغيل برمجية لوحدة تحكم CAN دون إعادة ضبط إعداداتها.
إذا دخلت وحدة التحكم حالة الانفصال عن الناقل (bus-off) فلن تشارك بعد ذلك في نشاط الناقل. وإذا لم تكن وحدة التحكم مهيّأة لإعادة التشغيل تلقائياً (انظر
init()) فيمكن استخدام هذه الطريقة لإطلاق إعادة تشغيل، وستتبع وحدة التحكم بروتوكول CAN لمغادرة حالة الانفصال عن الناقل والانتقال إلى حالة الخطأ النشط (error active).
- state() int¶
إرجاع حالة وحدة التحكم. يمكن أن تكون القيمة المُرجَعة إحدى التالي:
CAN.STOPPED-- وحدة التحكم متوقفة تماماً وأُعيد ضبطها؛CAN.ERROR_ACTIVE-- وحدة التحكم قيد التشغيل وفي حالة الخطأ النشط (كلا TEC وREC أقل من 96)؛CAN.ERROR_WARNING-- وحدة التحكم قيد التشغيل وفي حالة تحذير الخطأ (واحد على الأقل من TEC أو REC يساوي 96 أو أكثر)؛CAN.ERROR_PASSIVE-- وحدة التحكم قيد التشغيل وفي حالة الخطأ السلبي (واحد على الأقل من TEC أو REC يساوي 128 أو أكثر)؛CAN.BUS_OFF-- وحدة التحكم قيد التشغيل لكنها لا تشارك في نشاط الناقل (تجاوز TEC القيمة 255).
- info(list: list | None = None) list¶
الحصول على معلومات حول حالات الخطأ في وحدة التحكم ومخازن TX وRX المؤقتة. إذا أُعطي list فينبغي أن يكون كائن قائمة بثمانية مدخلات على الأقل، وستُملأ بالمعلومات. وإلا فستُنشأ قائمة جديدة وتُملأ. في كلتا الحالتين تكون القيمة المُرجَعة من الطريقة هي القائمة المملوءة.
القيم في القائمة هي:
قيمة TEC
قيمة REC
عدد المرات التي دخلت فيها وحدة التحكم حالة تحذير الخطأ (تلتف إلى 0 بعد 65535)
عدد المرات التي دخلت فيها وحدة التحكم حالة الخطأ السلبي (تلتف إلى 0 بعد 65535)
عدد المرات التي دخلت فيها وحدة التحكم حالة الانفصال عن الناقل (تلتف إلى 0 بعد 65535)
عدد رسائل TX المعلّقة
عدد رسائل RX المعلّقة على fifo 0
عدد رسائل RX المعلّقة على fifo 1
- setfilter(bank: int, mode: int, fifo: int, params: Tuple[int, ...], *, rtr: Tuple[bool, ...] | None = None, extframe: bool = False) None¶
تهيئة بنك مرشّح:
bank هو بنك مرشّح وحدة تحكم CAN الكلاسيكي، أو فهرس مرشّح CAN FD، المراد تهيئته.
mode هو الوضع الذي ينبغي أن يعمل به المرشّح، انظر الجداول أدناه.
fifo هو الـ fifo (0 أو 1) الذي ينبغي أن تُخزَّن فيه الرسالة، إن قبلها هذا المرشّح.
params هو مصفوفة من القيم تعرّف المرشّح. تعتمد محتويات المصفوفة على الوسيط mode.
محتويات مصفوفة params لوحدات تحكم CAN الكلاسيكي (OpenMV Cam M4 / M7):
mode
محتويات params
CAN.LIST16أربعة معرّفات بطول 16 بت سيتم قبولها.
CAN.LIST32معرّفان بطول 32 بت سيتم قبولهما.
CAN.MASK16زوجان من معرّف/قناع بطول 16 بت، مثلاً
(1, 3, 4, 4). يقبل الزوج الأول (1, 3) جميع المعرّفات التي يكون فيها البت 0 = 1 والبت 1 = 0؛ ويقبل الزوج الثاني (4, 4) جميع المعرّفات التي يكون فيها البت 2 = 1.CAN.MASK32زوج واحد من معرّف/قناع بطول 32 بت (وهو خلاف ذلك مماثل لـ
CAN.MASK16).محتويات مصفوفة params لوحدات تحكم CAN FD (OpenMV Cam H7 / H7 Plus / Pure Thermal):
mode
محتويات params
CAN.RANGEمعرّفان يشكّلان نطاقاً من المعرّفات المقبولة.
CAN.DUALمعرّفان سيتم قبولهما (مثلاً
(1, 2)).CAN.MASKزوج واحد من
(id, mask)(مثلاً(0x111, 0x7FF)).rtr لوحدات تحكم CAN الكلاسيكي، هذه مصفوفة من القيم المنطقية تحدّد ما إذا كان ينبغي للمرشّح قبول رسالة طلب إرسال عن بُعد. إذا لم يُعطَ هذا الوسيط فإنه يكون
Falseافتراضياً لجميع المدخلات. يعتمد الطول على mode:mode
len(rtr)ملاحظات
CAN.LIST164
CAN.LIST322
CAN.MASK162
CAN.MASK321
بالنسبة لـ CAN FD يُتجاهَل هذا الوسيط.
extframe إذا كان True فسيكون للإطار معرّف ممتد (29 بت)، وإلا فيُستخدَم معرّف قياسي (11 بت).
- clearfilter(bank: int, extframe: bool = False) None¶
مسح بنك مرشّح وتعطيله:
bank هو بنك مرشّح وحدة تحكم CAN الكلاسيكي، أو فهرس مرشّح CAN FD، المراد مسحه.
extframe لوحدات تحكم CAN FD، إذا كان True، يُمسَح مرشّح ممتد (مهيّأ بـ extframe=True)، وإلا فيُمسَح معرّف قياسي (مهيّأ بـ extframe=False).
- recv(fifo: int, list: list | None = None, *, timeout: int = 5000) list¶
استقبال البيانات على الناقل:
fifo عدد صحيح، وهو الـ FIFO المراد الاستقبال عليه
list هو كائن قائمة اختياري يُستخدَم كقيمة مُرجَعة
timeout هو المهلة بالميلي ثانية للانتظار للاستقبال.
القيمة المُرجَعة: قائمة تحتوي على خمس قيم.
معرّف الرسالة.
قيمة منطقية تشير إلى ما إذا كان معرّف الرسالة قياسياً أم ممتداً.
قيمة منطقية تشير إلى ما إذا كانت الرسالة رسالة RTR.
قيمة FMI (فهرس مطابقة المرشّح).
مصفوفة تحتوي على البيانات.
إذا كان list يساوي
Noneفستُخصَّص قائمة جديدة، إضافةً إلى كائن bytes جديد لاحتواء البيانات (كالعنصر الخامس في القائمة).إذا لم يكن list يساوي
Noneفينبغي أن يكون كائن قائمة بخمسة عناصر على الأقل. وينبغي أن يكون العنصر الخامس كائن memoryview مُنشأً من إما bytearray أو مصفوفة من النوع 'B' أو 'b'، ويجب أن تتسع هذه المصفوفة لـ 8 بايتات على الأقل. عندئذٍ تُملأ القائمة بالقيم المُرجَعة الأربع الأولى أعلاه، ويُعاد تحجيم كائن memoryview في مكانه إلى حجم البيانات ويُملأ بتلك البيانات. ويمكن إعادة استخدام كائني القائمة وmemoryview نفسيهما في الاستدعاءات اللاحقة لهذه الطريقة، مما يوفّر وسيلة لاستقبال البيانات دون استخدام الكومة (heap). على سبيل المثال: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¶
إرسال رسالة على الناقل:
data هي البيانات المراد إرسالها (عدد صحيح للإرسال، أو كائن مخزن مؤقت).
id هو معرّف الرسالة المراد إرسالها.
timeout هو المهلة بالميلي ثانية للانتظار للإرسال.
rtr قيمة منطقية تحدّد ما إذا كانت الرسالة سترسَل كطلب إرسال عن بُعد. إذا كان rtr يساوي True فلن يُستخدَم سوى طول data لملء خانة DLC في الإطار؛ أما البايتات الفعلية في data فلا تُستخدَم.
extframe إذا كان True فسيكون للإطار معرّف ممتد (29 بت)، وإلا فيُستخدَم معرّف قياسي (11 بت).
fdf لوحدات تحكم CAN FD، إذا ضُبِط على True، فسيكون للإطار تنسيق إطار FD، الذي يدعم حمولات بيانات حتى 64 بايت.
brs لوحدات تحكم CAN FD، إذا ضُبِط على True، فسيُمكَّن وضع تبديل معدل البت، حيث تُرسَل مرحلة البيانات بمعدل بت مختلف. انظر
CAN.init()لمعاملات تهيئة توقيت بت البيانات.
إذا كانت المهلة 0 فستوضَع الرسالة في أحد ثلاثة مخازن أجهزة مؤقتة وتعود الطريقة فوراً. وإذا كانت المخازن الثلاثة جميعها قيد الاستخدام يُطرَح استثناء. وإذا لم تكن المهلة 0، فإن الطريقة تنتظر حتى تُرسَل الرسالة. وإذا تعذّر إرسال الرسالة ضمن الوقت المحدّد يُطرَح استثناء.
القيمة المُرجَعة:
None.
- rxcallback(fifo: int, fun: Callable[[CAN, int], None] | None) None¶
تسجيل دالة لاستدعائها عندما تُقبَل رسالة في FIFO فارغ:
fifo هو الـ FIFO المستقبِل.
fun هي الدالة المراد استدعاؤها عندما يصبح الـ FIFO غير فارغ.
تأخذ دالة رد النداء وسيطين: الأول هو كائن CAN نفسه؛ والثاني عدد صحيح يشير إلى سبب رد النداء:
السبب
المعنى
0قُبِلَت رسالة في FIFO فارغ.
1الـ FIFO ممتلئ.
2فُقِدَت رسالة بسبب امتلاء FIFO.
مثال على استخدام 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)
الثوابت¶
ثوابت وضع الناقل (الوسيط
modeفيinit()):- NORMAL: int¶
تشارك وحدة التحكم بشكل طبيعي على الناقل -- ترسل إطاراتها الخاصة وتُقرّ باستلام الإطارات الصالحة.
- LOOPBACK: int¶
وضع الاسترجاع الحلقي الداخلي: تُفصَل وحدة التحكم عن الدبابيس وتوجّه الإطارات المرسَلة مباشرةً إلى مسار الاستقبال. مفيد للاختبارات الذاتية دون جهاز إرسال واستقبال.
- SILENT: int¶
وضع الاستماع فقط: تستقبل وحدة التحكم الإطارات لكنها لا تقود الناقل أبداً (لا ACK ولا إرسال). مفيد للتنصّت على الناقل.
- SILENT_LOOPBACK: int¶
يجمع بين
SILENTوLOOPBACK: لا نشاط على الدبابيس ولا إقرارات، مع استرجاع حلقي داخلي لـ TX إلى RX.
ثوابت حالة وحدة التحكم (المُرجَعة من
state()):- ERROR_WARNING: int¶
وحدة التحكم قيد التشغيل وفي حالة تحذير الخطأ (واحد على الأقل من TEC أو REC يساوي 96 أو أكثر).
- ERROR_PASSIVE: int¶
وحدة التحكم قيد التشغيل وفي حالة الخطأ السلبي (واحد على الأقل من TEC أو REC يساوي 128 أو أكثر).
أوضاع مرشّح CAN الكلاسيكي (الوسيط
modeفيsetfilter()على OpenMV Cam M4 / M7):أوضاع مرشّح CAN FD (الوسيط
modeفيsetfilter()على OpenMV Cam H7 / H7 Plus / Pure Thermal):