第二十一章 machine.UART類實驗 1)實驗平臺:正點原子DNK210開發板 2)章節摘自【正點原子】DNK210使用指南 - CanMV版 V1.0 3)購買鏈接:https://detail.tmall.com/item.htm?&id=782801398750 4)全套實驗源碼+手冊+ ...
第二十一章 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個,其特點如下所示:
-
可編程收發波特率
-
3個UART的發送FIFO以及接收FIFO共用1024*8bit RAM全雙工非同步通信
-
支持輸出信號波特率自動檢測功能
-
支持5、6、7、8位數據長度
-
支持1、1.5、2、3、4位停止位長度
-
支持奇偶校驗位
-
支持RS485協議
-
支持IrDA協議
-
支持DMA高速數據通信
-
支持UART喚醒模式
-
支持軟體流控和硬體流控
UARTHS一共有1個,其特點如下所示:
-
通訊速率可達5Mbps
-
8位元組接收和發送FIFO
-
可編程中斷模式
-
不支持硬體流控或者其他調製解調控制信號,或非同步串列數據轉換器
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 常式功能
-
創建兩個UART對象,兩個UART對象除了UART編號使用相同的配置參數。
-
當KEY0按鍵被按下後,使用UART1往UART2發送數據,並將UART2接收到的數據通過print()列印輸出。
-
當KEY1按鍵被按下後,使用UATY2往UART1發送數據,並將UART1接收到的數據通過printf()列印輸出。
21.2.2 硬體資源
-
擴展串口介面1
UART1_TXD - IO7
UART1_RXD - IO9
-
擴展串口介面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發送的數據,這與理論推斷的結果一致。