《DNK210使用指南 -CanMV版 V1.0》第二十一章 machine.UART類實驗

正点原子發表於2024-09-02

第二十一章 machine.UART類實驗

1)實驗平臺:正點原子DNK210開發板

2)章節摘自【正點原子】DNK210使用指南 - CanMV版 V1.0

3)購買連結:https://detail.tmall.com/item.htm?&id=782801398750

4)全套實驗原始碼+手冊+影片下載地址:http://www.openedv.com/docs/boards/k210/ATK-DNK210.html

5)正點原子官方B站:https://space.bilibili.com/394620890

6)正點原子K210技術交流企鵝群:605557868

本章將介紹machine模組中的UART類。透過本章的學習,讀者將學習到machine模組中UART類的使用。

本章分為如下幾個小節:

21.1 machine.UART類介紹

21.2 硬體設計

21.3 程式設計

21.4 執行驗證

21.1 machine.UART類介紹

machine.UART類是machine模組內提供的類,該類用於訪問和控制Kendryte K210硬體上的UART和UARTHS控制器。Kendryte K210硬體上有3個UART控制器和1個UARTHS控制器,它們能夠靈活地與外部裝置進行全雙工資料交換。

UART一共有3個,其特點如下所示:

  1. 可程式設計收發波特率

  2. 3個UART的傳送FIFO以及接收FIFO共享1024*8bit RAM全雙工非同步通訊

  3. 支援輸出訊號波特率自動檢測功能

  4. 支援5、6、7、8位資料長度

  5. 支援1、1.5、2、3、4位停止位長度

  6. 支援奇偶校驗位

  7. 支援RS485協議

  8. 支援IrDA協議

  9. 支援DMA高速資料通訊

  10. 支援UART喚醒模式

  11. 支援軟體流控和硬體流控

UARTHS一共有1個,其特點如下所示:

  1. 通訊速率可達5Mbps

  2. 8位元組接收和傳送FIFO

  3. 可程式設計中斷模式

  4. 不支援硬體流控或者其他調製解調控制訊號,或非同步序列資料轉換器

machine.UART提供了UART建構函式,用於建立一個UART物件,UART建構函式如下所示:

class UART(id, baudrate=115200, bitwidth=8, parity=None, stop=None, timeout=1000, timeout_char=10, 
read_buf_len=2048, ide=False, from_ide=True)

透過UART建構函式可以透過指定引數建立並初始化一個UART物件。

id指的是UART編號,可以是UART.UART1~UART.UART3和UART.UARTHS,分別對應了Kendryte K210硬體上的UART1~UART3和UARTHS。

baudrate指的是UART通訊的波特率。

bitwidth指的是UART資料寬度,可以是5、6、7、8位。

parity指的是UART校驗位,可以是None、UART. PARITY_ODD和UART. PARITY_EVEN,分別對應無校驗位、奇校驗和偶校驗。

stop指的是UART停止位,可以是1、1.5、2位。

timeout指的是UART接收超時時間。

timeout_char指的是UART作為資料流被讀取時,等待一個位元組的最長超時時間。

read_buf_len指的是UART接收緩衝區的長度,UART透過中斷來接收資料,如果緩衝區滿了,則將自動停止資料接收。

ide和from_ide這兩個引數,在大多數情況下是在與CanMV IDE軟體連線時才使用到的。

UART建構函式的使用示例如下所示:

from board import board_info

from fpioa_manager import fm

from machine import UART

 

fm.register(board_info.EX_UART1_TX, fm.fpioa.UART1_TX)

fm.register(board_info.EX_UART1_RX, fm.fpioa.UART1_RX)

 

uart1 = UART(UART.UART1, 115200)

machine.UART類為UART物件提供了any()方法,用於獲取UART物件的接收緩衝區已有的資料量,any()方法如下所示:

UART.any()

any()方法用於獲取UART物件接收緩衝區中已有的資料量,當UART物件還沒有接收到資料,或接收到的資料均已被讀出,則any()方法將返回0。

any()方法的使用示例如下所示:

from board import board_info

from fpioa_manager import fm

from machine import UART

 

fm.register(board_info.EX_UART1_TX, fm.fpioa.UART1_TX)

fm.register(board_info.EX_UART1_RX, fm.fpioa.UART1_RX)

 

uart1 = UART(UART.UART1, 115200)

 

while True:

    if uart1.any() != 0:

        print("Data received!")

machine.UART類為UART物件提供了readchar ()方法,用於從UART物件的接收緩衝區中讀取一個位元組資料,readchar()方法如下所示:

UART.readchar()

readchar()方法用於讀取UART物件的接收緩衝區中的一個資料,若UART物件的接收緩衝區中沒有可用的資料,則readchar()方法將返回-1。

readchar()方法的使用示例如下所示:

from board import board_info

from fpioa_manager import fm

from machine import UART

 

fm.register(board_info.EX_UART1_TX, fm.fpioa.UART1_TX)

fm.register(board_info.EX_UART1_RX, fm.fpioa.UART1_RX)

 

uart1 = UART(UART.UART1, 115200)

 

while True:

    data = uart1.readchar()

    if data != -1:

        print(data, end='')

machine.UART類為UART物件提供了read()方法,用於從UART物件的接收緩衝區中讀取資料,read()方法如下所示:

UART.read(num)

read()方法用於從UART物件的接收緩衝區中讀取資料。

num指的是讀取資料的位元組數,一般情況下可以填入UART物件接收緩衝區的大小,如果接收緩衝區的有效資料沒有那麼多,read()方法將只返回有效的資料。

read()方法的使用示例如下所示:

from board import board_info

from fpioa_manager import fm

from machine import UART

 

fm.register(board_info.EX_UART1_TX, fm.fpioa.UART1_TX)

fm.register(board_info.EX_UART1_RX, fm.fpioa.UART1_RX)

 

uart1 = UART(UART.UART1, 115200)

 

print(uart1.read(2048))

machine.UART類為UART物件提供了readline()方法,用於從UART物件的接收緩衝區中讀取以行為單位的資料,readline()方法如下所示:

UART.readline(num)

readline()方法用於從UART物件的接收緩衝區中讀取以行為單位的資料,readline()方法會以“\n”字元作為行與行之間的分隔。

num指的是要讀取的行數。

readline()方法的使用示例如下所示:

from board import board_info

from fpioa_manager import fm

from machine import UART

 

fm.register(board_info.EX_UART1_TX, fm.fpioa.UART1_TX)

fm.register(board_info.EX_UART1_RX, fm.fpioa.UART1_RX)

 

uart1 = UART(UART.UART1, 115200)

 

print(uart1.readline(1))

machine.UART類為UART物件提供了write()方法,用於使用UART物件傳送資料,write()方法如下所示:

UART.write(buf)

write()方法用於使用UART物件透過UART傳送資料。

buf指的是待傳送的資料。

write()方法的使用示例如下所示:

from board import board_info

from fpioa_manager import fm

from machine import UART

 

fm.register(board_info.EX_UART1_TX, fm.fpioa.UART1_TX)

fm.register(board_info.EX_UART1_RX, fm.fpioa.UART1_RX)

 

uart1 = UART(UART.UART1, 115200)

 

uart1.write("Hello, World!")

21.2 硬體設計

21.2.1 例程功能

  1. 建立兩個UART物件,兩個UART物件除了UART編號使用相同的配置引數。

  2. 當KEY0按鍵被按下後,使用UART1往UART2傳送資料,並將UART2接收到的資料透過print()列印輸出。

  3. 當KEY1按鍵被按下後,使用UATY2往UART1傳送資料,並將UART1接收到的資料透過printf()列印輸出。

21.2.2 硬體資源

  1. 擴充套件串列埠介面1

    UART1_TXD - IO7

    UART1_RXD - IO9

  2. 擴充套件串列埠介面2

    UART2_TXD - IO6

    UART2_RXD - IO8

21.2.3 原理圖

本章實驗內容,需要使用到板載的擴充套件串列埠介面1和擴充套件串列埠介面2,正點原子DNK210開發板上的擴充套件串列埠介面連線原理圖,如下圖所示:


圖21.2.3.1 擴充套件串列埠介面連線原理圖

由於需要讓這兩個串列埠擴充套件介面相互通訊,因此需要使用杜邦線或其他線材從物理上連線這這兩個介面,連線時需要注意串列埠線路的連線需要將TXD訊號和RXD訊號交叉連線。

21.3 程式設計

21.3.1 machine.UART類

有關machine.UART類的介紹,請見第21.1小節《machine.UART類介紹》。

21.3.2 程式流程圖


圖21.3.2.1 machine.UART類實驗流程圖

21.3.3 main.py程式碼

main.py中的指令碼程式碼如下所示:

from board import board_info

from fpioa_manager import fm

from maix import GPIO

import time

from machine import UART

 

fm.register(board_info.KEY0, fm.fpioa.GPIOHS0)

fm.register(board_info.KEY1, fm.fpioa.GPIOHS1)

key0 = GPIO(GPIO.GPIOHS0, GPIO.IN, GPIO.PULL_UP)

key1 = GPIO(GPIO.GPIOHS1, GPIO.IN, GPIO.PULL_UP)

 

fm.register(board_info.EX_UART1_TX, fm.fpioa.UART1_TX)

fm.register(board_info.EX_UART1_RX, fm.fpioa.UART1_RX)

fm.register(board_info.EX_UART2_TX, fm.fpioa.UART2_TX)

fm.register(board_info.EX_UART2_RX, fm.fpioa.UART2_RX)

 

# 構造UART物件

uart1 = UART(UART.UART1, 115200)

uart2 = UART(UART.UART2, 115200)

 

while True:

    if key0.value() == 0:

        time.sleep_ms(20)

        if key0.value() == 0:

            # UART傳送資料

            uart1.write("From UART1!")

            while key0.value() == 0:

                pass

    elif key1.value() == 0:

        time.sleep_ms(20)

        if key1.value() == 0:

            # UART傳送資料

            uart2.write("From UART2!")

            while key1.value() == 0:

                pass

    if uart1.any() != 0:

        # UART接收資料

        data = uart1.read()

        print("UART1 get data:", data.decode())

    if uart2.any() != 0:

        # UART接收資料

        data = uart2.read()

        print("UART2 get data:", data.decode())

可以看到首先就是構造了兩個UART物件,並且配置了相同的通訊波特率。

接著便在一個迴圈中讀取按鍵狀態和兩個UART的資料接收狀態,如果KEY0按鍵被按下,則透過UART1物件傳送“From UART1!”的資料,如果KEY1按鍵被按下,則透過UART2物件傳送“From UART2!”的資料,如果UART1物件或UART2物件接收到資料,並將接收到的資料加上UART物件編號後透過print()列印輸出。

由於本章實驗要求板載的兩個擴充套件串列埠介面透過線材進行連線,因此當KEY0按鍵被按下後,UART1物件發出的資料將被UART2物件接收,並會被透過print()列印輸出,當KEY1按鍵被按下後,UART2物件發出的資料將被UART1物件接收,並會透過print()列印輸出。

21.4 執行驗證

將DNK210開發板連線CanMV IDE,並點選CanMV IDE上的“開始(執行指令碼)”按鈕後,同時將板載的兩個擴充套件串列埠介面透過線材按照要求進行相互連線。

此時,若分別按下KEY0按鍵和KEY1按鍵,CanMV IDE軟體的“序列中斷”將依次輸出UART2物件和UART1物件接收到的資料,如下圖所示:


圖21.4.1 “序列終端”視窗列印輸出

可以看到,首先UART2物件接收到了來自UART1物件傳送的資料,然後UART1物件接收到了來自UART2傳送的資料,這與理論推斷的結果一致。

相關文章