คลาส CAN -- บัสการสื่อสารเครือข่ายในพื้นที่ควบคุม¶
CAN รองรับทั้งคอนโทรลเลอร์ classic CAN (bxCAN ใช้บน OpenMV Cam M4 และ M7) และ CAN FD (FDCAN ใช้บน OpenMV Cam H7, H7 Plus และ Pure Thermal) ในระดับทางกายภาพ บัส CAN ประกอบด้วยสายสองเส้น คือ RX และ TX เพื่อเชื่อมต่อ OpenMV Cam เข้ากับบัส CAN คุณต้องใช้ CAN transceiver เพื่อแปลงสัญญาณลอจิก CAN จาก MCU ให้เป็นระดับแรงดันที่ถูกต้องบนบัส
Classic CAN ในโหมด loopback (ไม่ใช้ 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 พร้อมฟีเจอร์เสริมทั้งหมดที่เปิดใช้งาน (FD frame, การสลับอัตราบิต, extended frame IDs; arbitration phase 500 kbit/s, data phase 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 และอาร์กิวเมนต์ต่อไปนี้พร้อมใช้งานสำหรับทั้งคอนโทรลเลอร์ classic CAN และ FD CAN เว้นแต่จะระบุไว้เป็นอย่างอื่น
ตัวสร้าง¶
- 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 transceiver ภายนอกเพื่อขับบัส 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 เพื่อสร้างหน่วยเวลาบิตนามแฝง ค่า prescaler อยู่ระหว่าง 1 ถึง 1024 สำหรับ classic CAN และ 1 ถึง 512 สำหรับ CAN FD
sjw คือความกว้างการกระโดดการซิงค์ใหม่ในหน่วยของหน่วยเวลาสำหรับบิตนามแฝง อยู่ระหว่าง 1 ถึง 4 สำหรับ classic CAN และ 1 ถึง 128 สำหรับ CAN FD
bs1 กำหนดตำแหน่งของจุดตัวอย่างในหน่วยของหน่วยเวลาสำหรับบิตนามแฝง อยู่ระหว่าง 1 ถึง 16 สำหรับ classic CAN และ 2 ถึง 256 สำหรับ CAN FD
bs2 กำหนดตำแหน่งของจุดส่งในหน่วยของหน่วยเวลาสำหรับบิตนามแฝง อยู่ระหว่าง 1 ถึง 8 สำหรับ classic CAN และ 2 ถึง 128 สำหรับ CAN FD
auto_restart ตั้งค่าว่าคอนโทรลเลอร์จะพยายามรีสตาร์ทการสื่อสารโดยอัตโนมัติหลังจากเข้าสู่สถานะ bus-off หรือไม่ หากปิดใช้งาน สามารถใช้
restart()เพื่อออกจากสถานะ bus-offbaudrate หากระบุ baudrate ที่ไม่ใช่ 0 ฟังก์ชันนี้จะพยายามคำนวณเวลาบิตนามแฝง CAN โดยอัตโนมัติ (แทนที่ prescaler, bs1 และ bs2) ที่ตรงกับทั้ง baudrate (ภายใน .1%) และ sample_point ที่ต้องการ (ใกล้เคียง 1%) สำหรับการควบคุมที่แม่นยำยิ่งขึ้น ให้ตั้งค่าพารามิเตอร์ prescaler, bs1 และ bs2 โดยตรง
sample_point ระบุตำแหน่งของจุดตัวอย่างบิตเทียบกับเวลาบิตนามแฝงทั้งหมด แสดงเป็นเปอร์เซ็นต์จำนวนเต็มของเวลาบิตนามแฝง ค่าเริ่มต้นของ sample_point คือ 75% พารามิเตอร์นี้จะถูกละเว้นหากไม่ได้ตั้งค่า baudrate
num_filter_banks สำหรับ classic CAN คือจำนวนแบงก์ที่จะถูกกำหนดให้กับ CAN(1) ส่วนที่เหลือจาก 28 จะถูกกำหนดให้กับ CAN(2)
พารามิเตอร์ที่เหลือมีเฉพาะบนบอร์ดที่รองรับ CAN FD และกำหนดค่าฟีเจอร์เสริม CAN FD Bit Rate Switch (BRS):
brs_prescaler คือค่าที่ใช้หารสัญญาณนาฬิกาอินพุต CAN FD เพื่อสร้างหน่วยเวลาบิตข้อมูล ค่า prescaler อยู่ระหว่าง 1 ถึง 32
brs_sjw คือความกว้างการกระโดดการซิงค์ใหม่ในหน่วยของหน่วยเวลาสำหรับบิตข้อมูล อยู่ระหว่าง 1 ถึง 16
brs_bs1 กำหนดตำแหน่งของจุดตัวอย่างในหน่วยของหน่วยเวลาสำหรับบิตข้อมูล อยู่ระหว่าง 1 ถึง 32
brs_bs2 กำหนดตำแหน่งของจุดส่งในหน่วยของหน่วยเวลาสำหรับบิตข้อมูล อยู่ระหว่าง 1 ถึง 16
brs_baudrate หากระบุ baudrate ที่ไม่ใช่ 0 ฟังก์ชันนี้จะพยายามคำนวณเวลาบิตข้อมูล CAN โดยอัตโนมัติ (แทนที่ brs_prescaler, brs_bs1 และ brs_bs2) ที่ตรงกับทั้ง brs_baudrate (ภายใน .1%) และ brs_sample_point ที่ต้องการ (ใกล้เคียง 1%) สำหรับการควบคุมที่แม่นยำยิ่งขึ้น ให้ตั้งค่าพารามิเตอร์ brs_prescaler, brs_bs1 และ brs_bs2 โดยตรง
brs_sample_point ระบุตำแหน่งของจุดตัวอย่างบิตเทียบกับเวลาบิตนามแฝงทั้งหมด แสดงเป็นเปอร์เซ็นต์จำนวนเต็มของเวลาบิตนามแฝง ค่าเริ่มต้นของ brs_sample_point คือ 75% พารามิเตอร์นี้จะถูกละเว้นหากไม่ได้ตั้งค่า brs_baudrate
หน่วยเวลา tq คือหน่วยเวลาพื้นฐานสำหรับบัส CAN tq คือค่า prescaler CAN หารด้วย PCLK1 (ความถี่ของบัสอุปกรณ์ต่อพ่วงภายใน 1) ดู
pyb.freq()เพื่อตรวจสอบค่า PCLK1บิตเดียวประกอบด้วยเซกเมนต์การซิงโครไนซ์ ซึ่งมีขนาด 1 tq เสมอ ตามด้วย bit segment 1 แล้วก็ bit segment 2 จุดตัวอย่างอยู่หลังจาก bit segment 1 สิ้นสุด จุดส่งอยู่หลังจาก bit segment 2 สิ้นสุด อัตราบอดจะเป็น 1/bittime โดย bittime คือ 1 + BS1 + BS2 คูณด้วยหน่วยเวลา tq
ตัวอย่างเช่น บน OpenMV Cam H7 (PCLK1 = 100 MHz) CAN 250 kbps พร้อม sample point 75% สามารถกำหนดค่าได้เป็น
prescaler=25, sjw=1, bs1=11, bs2=4:tq = 25 / 100 MHz = 250 ns,bittime = (1 + 11 + 4) × 250 ns = 4 µs, sample point =(1 + 11) / 16 = 75%, และ baudrate คือ1 / 4 µs = 250 kHzดูส่วน bxCAN / FDCAN ในคู่มืออ้างอิง STM32 สำหรับ MCU ของ OpenMV Cam เพื่อดูรายละเอียดเพิ่มเติม
- restart() None¶
บังคับให้รีสตาร์ทคอนโทรลเลอร์ CAN ด้วยซอฟต์แวร์โดยไม่รีเซ็ตการกำหนดค่า
หากคอนโทรลเลอร์เข้าสู่สถานะ bus-off จะไม่มีส่วนร่วมในกิจกรรมบัสอีกต่อไป หากคอนโทรลเลอร์ไม่ได้กำหนดค่าให้รีสตาร์ทโดยอัตโนมัติ (ดู
init()) สามารถใช้เมธอดนี้เพื่อกระตุ้นการรีสตาร์ท และคอนโทรลเลอร์จะปฏิบัติตามโปรโตคอล CAN เพื่อออกจากสถานะ bus-off และเข้าสู่สถานะ error active
- state() int¶
ส่งคืนสถานะของคอนโทรลเลอร์ ค่าที่ส่งคืนสามารถเป็นหนึ่งใน:
CAN.STOPPED-- คอนโทรลเลอร์ปิดอยู่และถูกรีเซ็ตสมบูรณ์CAN.ERROR_ACTIVE-- คอนโทรลเลอร์เปิดอยู่และอยู่ในสถานะ Error Active (ทั้ง TEC และ REC น้อยกว่า 96)CAN.ERROR_WARNING-- คอนโทรลเลอร์เปิดอยู่และอยู่ในสถานะ Error Warning (อย่างน้อยหนึ่งใน TEC หรือ REC มีค่า 96 หรือมากกว่า)CAN.ERROR_PASSIVE-- คอนโทรลเลอร์เปิดอยู่และอยู่ในสถานะ Error Passive (อย่างน้อยหนึ่งใน TEC หรือ REC มีค่า 128 หรือมากกว่า)CAN.BUS_OFF-- คอนโทรลเลอร์เปิดอยู่แต่ไม่มีส่วนร่วมในกิจกรรมบัส (TEC เกิน 255)
- info(list: list | None = None) list¶
รับข้อมูลเกี่ยวกับสถานะข้อผิดพลาดของคอนโทรลเลอร์และบัฟเฟอร์ TX และ RX หาก list ถูกระบุ ควรเป็นออบเจ็กต์ลิสต์ที่มีอย่างน้อย 8 รายการ ซึ่งจะถูกเติมด้วยข้อมูล มิฉะนั้นจะสร้างลิสต์ใหม่และเติมข้อมูล ในทั้งสองกรณี ค่าที่ส่งคืนของเมธอดคือลิสต์ที่ถูกเติมข้อมูลแล้ว
ค่าในลิสต์คือ:
ค่า TEC
ค่า REC
จำนวนครั้งที่คอนโทรลเลอร์เข้าสู่สถานะ Error Warning (วนกลับเป็น 0 หลังจาก 65535)
จำนวนครั้งที่คอนโทรลเลอร์เข้าสู่สถานะ Error Passive (วนกลับเป็น 0 หลังจาก 65535)
จำนวนครั้งที่คอนโทรลเลอร์เข้าสู่สถานะ Bus Off (วนกลับเป็น 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¶
กำหนดค่า filter bank:
bank คือ filter bank ของคอนโทรลเลอร์ classic CAN หรือดัชนีฟิลเตอร์ CAN FD ที่จะกำหนดค่า
mode คือโหมดที่ฟิลเตอร์ควรทำงาน ดูตารางด้านล่าง
fifo คือ fifo (0 หรือ 1) ที่ข้อความควรถูกจัดเก็บ หากข้อความผ่านการยอมรับโดยฟิลเตอร์นี้
params คืออาร์เรย์ของค่าที่กำหนดฟิลเตอร์ เนื้อหาของอาร์เรย์ขึ้นอยู่กับอาร์กิวเมนต์ mode
เนื้อหาของอาร์เรย์ params สำหรับคอนโทรลเลอร์ classic CAN (OpenMV Cam M4 / M7):
mode
เนื้อหาของ params
CAN.LIST16ID 16 บิตสี่รายการที่จะถูกยอมรับ
CAN.LIST32ID 32 บิตสองรายการที่จะถูกยอมรับ
CAN.MASK16คู่ id/mask 16 บิตสองคู่ เช่น
(1, 3, 4, 4)คู่แรก (1, 3) ยอมรับ ID ทั้งหมดที่มี bit 0 = 1 และ bit 1 = 0; คู่ที่สอง (4, 4) ยอมรับ ID ทั้งหมดที่มี bit 2 = 1CAN.MASK32คู่ id/mask 32 บิตหนึ่งคู่ (มิฉะนั้นเหมือนกับ
CAN.MASK16)เนื้อหาของอาร์เรย์ params สำหรับคอนโทรลเลอร์ CAN FD (OpenMV Cam H7 / H7 Plus / Pure Thermal):
mode
เนื้อหาของ params
CAN.RANGEID สองรายการที่ก่อตัวเป็นช่วงของ ID ที่ยอมรับ
CAN.DUALID สองรายการที่จะถูกยอมรับ (เช่น
(1, 2))CAN.MASKคู่
(id, mask)หนึ่งคู่ (เช่น(0x111, 0x7FF))rtr สำหรับคอนโทรลเลอร์ classic CAN นี่คืออาร์เรย์ของบูลีนที่ระบุว่าฟิลเตอร์ควรยอมรับข้อความ remote transmission request หรือไม่ หากไม่ระบุอาร์กิวเมนต์นี้จะใช้ค่าเริ่มต้น
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¶
ล้างและปิดใช้งาน filter bank:
bank คือ filter bank ของคอนโทรลเลอร์ classic CAN หรือดัชนีฟิลเตอร์ CAN FD ที่จะล้าง
extframe สำหรับคอนโทรลเลอร์ CAN FD หาก True ให้ล้าง extended filter (กำหนดค่าด้วย extframe=True) มิฉะนั้นให้ล้างตัวระบุมาตรฐาน (กำหนดค่าด้วย extframe=False)
- recv(fifo: int, list: list | None = None, *, timeout: int = 5000) list¶
รับข้อมูลบนบัส:
fifo เป็นจำนวนเต็ม ซึ่งคือ FIFO ที่จะรับ
list เป็นออบเจ็กต์ลิสต์ที่เป็นตัวเลือก ใช้เป็นค่าที่ส่งคืน
timeout คือ timeout ในมิลลิวินาทีที่รอรับ
ค่าที่ส่งคืน: ลิสต์ที่มีค่าห้ารายการ
ID ของข้อความ
บูลีนที่ระบุว่า message ID เป็นมาตรฐานหรือขยาย
บูลีนที่ระบุว่าข้อความเป็นข้อความ RTR หรือไม่
ค่า FMI (Filter Match Index)
อาร์เรย์ที่มีข้อมูล
หาก list เป็น
Noneจะมีการจัดสรรลิสต์ใหม่ รวมถึงออบเจ็กต์ bytes ใหม่เพื่อเก็บข้อมูล (เป็นองค์ประกอบที่ห้าในลิสต์)หาก list ไม่ใช่
Noneควรเป็นออบเจ็กต์ลิสต์ที่มีอย่างน้อยห้าองค์ประกอบ องค์ประกอบที่ห้าควรเป็นออบเจ็กต์ memoryview ที่สร้างจาก bytearray หรืออาร์เรย์ประเภท 'B' หรือ 'b' และอาร์เรย์นี้ต้องมีพื้นที่เพียงพอสำหรับอย่างน้อย 8 ไบต์ จากนั้นออบเจ็กต์ลิสต์จะถูกเติมด้วยค่าส่งคืนสี่รายการแรกด้านบน และออบเจ็กต์ memoryview จะถูกปรับขนาดแบบ inplace ให้มีขนาดของข้อมูลและเติมด้วยข้อมูลนั้น ออบเจ็กต์ลิสต์และ 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 คือข้อมูลที่จะส่ง (จำนวนเต็มที่จะส่ง หรือออบเจ็กต์ buffer)
id คือ id ของข้อความที่จะส่ง
timeout คือ timeout ในมิลลิวินาทีที่รอการส่ง
rtr เป็นบูลีนที่ระบุว่าข้อความจะถูกส่งเป็น remote transmission request หรือไม่ หาก rtr เป็น True จะใช้เฉพาะความยาวของ data เพื่อเติมสล็อต DLC ของเฟรม ไม่ใช้ไบต์จริงใน data
extframe หาก True เฟรมจะมีตัวระบุแบบขยาย (29 บิต) มิฉะนั้นจะใช้ตัวระบุมาตรฐาน (11 บิต)
fdf สำหรับคอนโทรลเลอร์ CAN FD หากตั้งค่าเป็น True เฟรมจะมีรูปแบบเฟรม FD ซึ่งรองรับ payload ข้อมูลสูงสุด 64 ไบต์
brs สำหรับคอนโทรลเลอร์ CAN FD หากตั้งค่าเป็น True โหมด bitrate switching จะถูกเปิดใช้งาน ซึ่ง data phase จะถูกส่งที่ bitrate ต่างกัน ดู
CAN.init()สำหรับพารามิเตอร์การกำหนดเวลาบิตข้อมูล
หาก timeout เป็น 0 ข้อความจะถูกวางในบัฟเฟอร์หนึ่งในสามบัฟเฟอร์ฮาร์ดแวร์ และเมธอดจะส่งคืนทันที หากบัฟเฟอร์ทั้งสามถูกใช้งานอยู่จะเกิดข้อยกเว้น หาก timeout ไม่ใช่ 0 เมธอดจะรอจนกว่าข้อความจะถูกส่ง หากไม่สามารถส่งข้อความภายในเวลาที่กำหนดจะเกิดข้อยกเว้น
ค่าที่ส่งคืน:
None
- rxcallback(fifo: int, fun: Callable[[CAN, int], None] | None) None¶
ลงทะเบียนฟังก์ชันที่จะถูกเรียกเมื่อมีข้อความถูกยอมรับเข้าสู่ FIFO ที่ว่าง:
fifo คือ FIFO ที่รับ
fun คือฟังก์ชันที่จะถูกเรียกเมื่อ FIFO ไม่ว่าง
ฟังก์ชัน callback รับสองอาร์กิวเมนต์: อันแรกคือออบเจ็กต์ CAN เอง อันที่สองเป็นจำนวนเต็มที่ระบุเหตุผลของ callback:
เหตุผล
ความหมาย
0ข้อความถูกยอมรับเข้าสู่ FIFO ที่ว่าง
1FIFO เต็ม
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¶
คอนโทรลเลอร์มีส่วนร่วมในบัสตามปกติ -- ส่งเฟรมของตนเองและยืนยัน (ACK) เฟรมที่ได้รับที่ถูกต้อง
- LOOPBACK: int¶
โหมด internal loopback: คอนโทรลเลอร์ถูกตัดการเชื่อมต่อจากพินและส่งเฟรมที่ส่งออกกลับไปยังเส้นทางรับโดยตรง มีประโยชน์สำหรับการทดสอบตัวเองโดยไม่ต้องใช้ transceiver
- SILENT: int¶
โหมด listen-only: คอนโทรลเลอร์รับเฟรมแต่ไม่ขับบัส (ไม่มี ACK ไม่มีการส่ง) มีประโยชน์สำหรับการดักจับบัส
- SILENT_LOOPBACK: int¶
รวม
SILENTและLOOPBACK: ไม่มีกิจกรรมพินและไม่มีการยืนยัน พร้อม internal loopback ของ TX เข้าสู่ RX
ค่าคงที่สถานะคอนโทรลเลอร์ (ส่งคืนโดย
state()):- ERROR_WARNING: int¶
คอนโทรลเลอร์เปิดอยู่และอยู่ในสถานะ Error Warning (อย่างน้อยหนึ่งใน TEC หรือ REC มีค่า 96 หรือมากกว่า)
- ERROR_PASSIVE: int¶
คอนโทรลเลอร์เปิดอยู่และอยู่ในสถานะ Error Passive (อย่างน้อยหนึ่งใน TEC หรือ REC มีค่า 128 หรือมากกว่า)
โหมดฟิลเตอร์ Classic CAN (อาร์กิวเมนต์
modeของsetfilter()บน OpenMV Cam M4 / M7):โหมดฟิลเตอร์ CAN FD (อาร์กิวเมนต์
modeของsetfilter()บน OpenMV Cam H7 / H7 Plus / Pure Thermal):