מחלקה UART – אפיק תקשורת טורית דו-כיוונית

UART מממש את פרוטוקול התקשורת הטורית הדו-כיוונית הסטנדרטי UART/USART. ברמה הפיזית הוא מורכב משני קווים: RX ו-TX. יחידת התקשורת היא תו (שאין לבלבל אותו עם תו של מחרוזת) שיכול להיות ברוחב 8 או 9 ביטים.

ניתן ליצור ולאתחל אובייקטי UART באמצעות:

from pyb import UART

# init with the given baudrate
uart = UART(3, 9600, timeout_char=1000)

# init with explicit parameters
uart.init(9600, bits=8, parity=None, stop=1, timeout_char=1000)

מספר הביטים יכול להיות 7, 8 או 9. הזוגיות (Parity) יכולה להיות None, 0 (זוגי) או 1 (אי-זוגי). ביטי העצירה (Stop) יכולים להיות 1 או 2.

הערה: עם parity=None, נתמכים רק 8 ו-9 ביטים. כאשר הזוגיות מאופשרת, נתמכים רק 7 ו-8 ביטים.

אובייקט UART מתנהג כמו אובייקט stream, וקריאה וכתיבה מתבצעות באמצעות מתודות הזרם הסטנדרטיות:

uart.read(10)       # read 10 characters, returns a bytes object
uart.read()         # read all available characters
uart.readline()     # read a line
uart.readinto(buf)  # read and store into the given buffer
uart.write('abc')   # write the 3 characters

ניתן לקרוא/לכתוב תווים בודדים באמצעות:

uart.readchar()     # read 1 character and returns it as an integer
uart.writechar(42)  # write 1 character

כדי לבדוק אם יש משהו לקריאה, יש להשתמש ב:

uart.any()          # returns the number of characters waiting

הערה: פונקציות הזרם read, write וכו« חדשות ב-MicroPython v1.3.4. גרסאות מוקדמות יותר משתמשות ב-uart.send וב-uart.recv.

בנאים

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

בונה אובייקט UART על האפיק bus הנתון (אינדקס מספרי של ההתקן ההיקפי, למשל 3 עבור UART3). ללא פרמטרים נוספים האובייקט נוצר אך אינו מאותחל (הוא שומר על הגדרות האפיק הקודמות, אם קיימות); אם ניתנים ארגומנטים נוספים, האפיק מאותחל. ראו init() עבור הפרמטרים הזמינים.

UART(3) מחווט לאותם פיני header בכל OpenMV Cam מסוג STM32:

אות

פין Header

TX

P4

RX

P5

אפיקי UART נוספים זמינים בחלק מהלוחות:

אפיק

פין TX

פין RX

זמין על

UART(1)

P1

P0

OpenMV Cam M7 / H7 / H7 Plus / Pure Thermal

UART(4)

P2

P3

OpenMV Cam N6

UART(7)

P14

P13

OpenMV Cam N6

מתודות

init(baudrate: int, bits: int = 8, parity: int | None = None, stop: int = 1, *, timeout: int = 1000, flow: int = 0, timeout_char: int = 0, read_buf_len: int = 64) None

מאתחל את אפיק ה-UART עם הפרמטרים הנתונים:

  • baudrate הוא קצב השעון.

  • bits הוא מספר הביטים לכל תו, 7, 8 או 9.

  • parity היא הזוגיות, None, 0 (זוגי) או 1 (אי-זוגי).

  • stop הוא מספר ביטי העצירה, 1 או 2.

  • flow מגדיר את סוג בקרת הזרימה. יכול להיות 0, UART.RTS, UART.CTS או UART.RTS | UART.CTS.

  • timeout הוא זמן הקצוב (timeout) באלפיות שנייה להמתנה לכתיבה/קריאה של התו הראשון.

  • timeout_char הוא הזמן הקצוב (timeout) באלפיות שנייה להמתנה בין תווים במהלך כתיבה או קריאה.

  • read_buf_len הוא אורך חוצץ הקריאה בתווים (0 לביטול).

מתודה זו תזרוק חריגה אם לא ניתן להגדיר את ה-baudrate בטווח של 5% מהערך הרצוי.

הערה: עם parity=None, נתמכים רק 8 ו-9 ביטים. כאשר הזוגיות מאופשרת, נתמכים רק 7 ו-8 ביטים.

deinit() None

מכבה את אפיק ה-UART.

any() int

מחזיר את מספר הבייטים הממתינים (עשוי להיות 0).

read(nbytes: int | None = None) bytes | None

קורא תווים. אם nbytes מצוין אזי נקראים לכל היותר אותו מספר בייטים. אם nbytes זמינים בחוצץ, מוחזר מיד, אחרת מוחזר כאשר מגיעים מספיק תווים או כאשר הזמן הקצוב חולף.

אם nbytes אינו ניתן אזי המתודה קוראת כמה שיותר נתונים. היא חוזרת לאחר שהזמן הקצוב חלף.

הערה: עבור תווים בני 9 ביטים כל תו תופס שני בייטים, nbytes חייב להיות זוגי, ומספר התווים הוא nbytes/2.

ערך מוחזר: אובייקט bytes המכיל את הבייטים שנקראו. מחזיר None במקרה של פקיעת זמן.

readchar() int

קולט תו בודד מהאפיק.

ערך מוחזר: התו שנקרא, כמספר שלם. מחזיר -1 במקרה של פקיעת זמן.

readinto(buf: bytearray, nbytes: int | None = None) int | None

קורא בייטים לתוך buf. אם nbytes מצוין אזי נקראים לכל היותר אותו מספר בייטים. אחרת, נקראים לכל היותר len(buf) בייטים.

ערך מוחזר: מספר הבייטים שנקראו ואוחסנו ב-buf או None במקרה של פקיעת זמן.

readline() bytes | None

קורא שורה, המסתיימת בתו של שורה חדשה. אם שורה כזו קיימת, החזרה מיידית. אם הזמן הקצוב חולף, כל הנתונים הזמינים מוחזרים בלי קשר לקיומו של תו שורה חדשה.

ערך מוחזר: השורה שנקראה או None במקרה של פקיעת זמן אם אין נתונים זמינים.

write(buf: bytes | bytearray | str) int | None

כותב את חוצץ הבייטים לאפיק. אם התווים ברוחב 7 או 8 ביטים אזי כל בייט הוא תו אחד. אם התווים ברוחב 9 ביטים אזי משתמשים בשני בייטים עבור כל תו (little endian), ו-buf חייב להכיל מספר זוגי של בייטים.

ערך מוחזר: מספר הבייטים שנכתבו. אם מתרחשת פקיעת זמן ולא נכתבו בייטים, מחזיר None.

writechar(char: int) None

כותב תו בודד לאפיק. char הוא מספר שלם לכתיבה. ראו את הסעיף CTS flow control למטה לגבי סמנטיקת החסימה כאשר בקרת זרימה של CTS מאופשרת.

sendbreak() None

שולח תנאי break לאפיק. זה מנמיך את האפיק למשך 13 ביטים.

קבועים

RTS: int

דגל ביט עבור הארגומנט flow של init(); מאפשר בקרת זרימה חומרתית של RTS (request-to-send) בנתיב הקליטה.

CTS: int

דגל ביט עבור הארגומנט flow של init(); מאפשר בקרת זרימה חומרתית של CTS (clear-to-send) בנתיב השידור. ניתן לבצע עליו OR עם RTS כדי לאפשר את שני הכיוונים.

בקרת זרימה

UART(3) תומך בבקרת זרימה חומרתית של RTS/CTS. ב-OpenMV Cam M7, H7, H7 Plus ו-Pure Thermal פיני בקרת הזרימה הם:

(TX, RX, nRTS, nCTS) = (P4, P5, P1, P2)

ב-OpenMV Cam N6 רק nRTS חשוף (על פין ה-header P7); nCTS אינו מנותב אל ה-header של ה-I/O.

בפסקאות הבאות המונח ”target“ מתייחס להתקן המחובר ל-UART.

כאשר המתודה init() של ה-UART נקראת עם flow המוגדר לאחד או לשניהם מתוך UART.RTS ו-UART.CTS, פיני בקרת הזרימה הרלוונטיים מוגדרים. nRTS הוא פלט פעיל-נמוך ו-nCTS הוא קלט פעיל-נמוך עם pull-up מאופשר. כדי לחווט בקרת זרימה, חברו את nCTS של ה-OpenMV Cam אל nRTS של ה-target ואת nRTS של ה-OpenMV Cam אל nCTS של ה-target.

CTS: ה-target שולט במשדר של ה-OpenMV Cam

אם בקרת זרימה של CTS מאופשרת, התנהגות הכתיבה היא כדלקמן:

אם המתודה UART.write(buf) של ה-OpenMV Cam נקראת, השידור ייעצר בכל פרק זמן שבו nCTS הוא False. הדבר יגרום לפקיעת זמן אם החוצץ כולו לא שודר בתוך פרק הזמן הקצוב. המתודה מחזירה את מספר הבייטים שנכתבו, ומאפשרת למשתמש לכתוב את יתרת הנתונים במידת הצורך. במקרה של פקיעת זמן, תו יישאר ב-UART בהמתנה ל-nCTS. מספר הבייטים המרכיבים תו זה ייכלל בערך המוחזר.

אם UART.writechar() נקראת כאשר nCTS הוא False המתודה תפקע אלא אם ה-target יחזיק את nCTS בזמן. אם היא פוקעת ייזרק OSError 116. התו ישודר ברגע שה-target יחזיק את nCTS.

RTS: ה-OpenMV Cam שולט במשדר של ה-target

אם בקרת זרימה של RTS מאופשרת, ההתנהגות היא כדלקמן:

אם נעשה שימוש בקלט עם חוצץ (read_buf_len > 0), התווים הנכנסים נשמרים בחוצץ. אם החוצץ מתמלא, התו הבא שיגיע יגרום ל-nRTS להפוך ל-False: ה-target אמור להפסיק את השידור. nRTS יהפוך ל-True כאשר תווים נקראים מהחוצץ.

שימו לב שהמתודה any() מחזירה את מספר הבייטים בחוצץ. נניח אורך חוצץ של N בייטים. אם החוצץ מתמלא, ותו נוסף מגיע, nRTS יוגדר ל-False, ו-any() תחזיר את הספירה N. כאשר תווים נקראים התו הנוסף יוצב בחוצץ וייכלל בתוצאה של קריאת any() עוקבת.

אם לא נעשה שימוש בקלט עם חוצץ (read_buf_len == 0) הגעת תו תגרום ל-nRTS להפוך ל-False עד שהתו נקרא.