UART 代表通用異步接收器/發送器,它是任何微控制器單元中有用的硬件功能。微控制器需要接收數據、處理數據并將其發送到其他設備。微控制器中有不同類型的通信協議可用,但是,UART 是 SPI 和 I2C 等其他通信協議中最常用的一種。如果有人需要串行接收或發送數據,UART 始終是最簡單和常見的選擇。UART的優點是它只需要兩條線在設備之間傳輸數據。繼續我們的Nuvoton 微控制器教程,在本文中,我們將學習如何使用 N76E003 微控制器執行串行通信。
UART通信基礎
現在,既然我們知道了什么是 UART,那么了解 UART 的相關參數很重要。
兩個 UART 設備以相同的頻率接收和發送數據。當接收 UART 設備檢測到一個起始位時,它開始以稱為波特率的特定頻率讀取傳入的位。波特率對于 UART 通信很重要,它用于測量數據傳輸的速度,以每秒位數 (bps) 為單位。這個波特率速度,對于發送和接收來說,必須是相同的波特率。在位時序偏離太遠之前,發送和接收 UART 之間的波特率速度差異只能約為 10%。最流行的波特率速度是 4800、9600、115200 bps 等。
N76E003 有兩個 UART—— UART0 和 UART1。在本教程中,我們將使用N76E003 微控制器單元上的 UART 外設。在不浪費太多時間的情況下,讓我們評估一下這個應用程序需要什么樣的硬件設置。
硬件要求和設置
該項目所需的主要組件是USB 到 UART 或 TTL 轉換器模塊,它將在 PC 或筆記本電腦與微控制器模塊之間建立所需的接口。對于這個項目,我們將使用基于CP2102的 USB 轉 UART 模塊,如下所示。
更不用說,除了上述組件,我們還需要基于N76E003 微控制器的開發板以及Nu-Link 編程器。如果編程器不用作電源,則可能需要額外的 5V 電源單元。
Nuvoton N76E003 UART通信電路圖
正如我們在下面的開發板示意圖中看到的,微控制器單元的第 2 和第 3 引腳分別用作 UART0 Tx 和 Rx。在最左側,顯示了編程接口連接。
Nuvoton N76E003 微控制器上的 UART 引腳
N76E003 有 20 個引腳,其中 4 個引腳可用于 UART 通信。下圖顯示了紅色方框 (Rx) 和藍色方框 (Tx) 中突出顯示的 UART 引腳。
對于 UART0,引腳 2 和 3 用于 UART 通信,對于 UART1,引腳 8 和 18 用于通信。
Nuvoton N76E003 微控制器中的 UART 寄存器
N76E003 具有兩個增強型全雙工 UART,具有自動地址識別和幀錯誤檢測功能 - UART0 和 UART1。這兩個 UART 使用分類為兩個不同 UART 的寄存器進行控制。N76E003 中有兩對 RX 和 TX 引腳可用于 UART 操作。因此,第一步是選擇所需的 UART 端口進行操作。
在本教程中,我們將使用UART0,因此僅顯示 UART0 的配置。UART1 將具有相同的配置,但寄存器將不同。
選擇一個 UART(本例中為 UART0)后,需要將需要用于 RX 和 TX 通信的 I/O 引腳配置為輸入和輸出。UART0 的 RX 引腳是微控制器的引腳 3,即端口 0.7。由于這是一個串口接收引腳,需要將端口 0.7 設置為輸入。另一方面,作為微控制器的第二個引腳的端口 0.6 是發送引腳或輸出引腳。需要設置為準雙向模式。這些可以使用 PxM1 和 PxM2 寄存器進行選擇。這兩個寄存器設置 I/O 模式,其中 x 代表端口號(例如,端口 P1.0 寄存器將是 P1M1 和 P1M2,對于 P3.0 它將是 P3M1 和 P3M2 等)配置可以如下圖所示 -
N76E003 中的 UART 操作模式
然后,下一步是確定UART 操作的模式。兩個 UART 可以在 4 種模式下運行。模式是-
我們可以看到,SM0 和 SM1(SCON 寄存器的第 7 位和第 6 位)選擇了 UART 操作模式。模式 0 是同步操作,其他三種模式是異步操作。但是,每種串行端口模式的波特率發生器和幀位都不同。可以根據應用要求選擇任何一種模式,UART1 也是如此。本教程使用 10 位運算,定時器 3 溢出率除以 32 或 16。
現在,是時候獲取信息并為 UART0 配置SCON 寄存器(UART1 的 SCON_1)了。
第 6 位和第 7 位將設置 UART 模式,如前所述。位 5 用于設置多處理器通信模式以啟用選項。但是,該過程取決于選擇的 UART 模式。除此之外,REN 位將設置為 1 以啟用接收,TI 標志將設置為 1 以使用printf功能代替自定義 UART0 發送功能。
下一個重要的寄存器是電源控制寄存器 (PCON)(UART1 的定時器 3 位 7 和 6)寄存器。如果您不熟悉計時器,請查看 Nuvoton N76E003 計時器教程以了解如何在 N76E003 微控制器上使用計時器。
SMOD 位對于選擇 UART0 模式 1 中的雙波特率很重要。現在,由于我們使用的是定時器 3,因此需要配置定時器 3 控制寄存器 T3CON。但是,第 7 位和第 6 位保留用于 UART1 的雙倍數據速率設置。
和定時器 3 預分頻器值-
第 5 位 BRCK 將定時器 3 設置為 UART1 的波特率時鐘源。現在,N76E003 的數據表給出了計算所需波特率的公式以及定時器 3(16 位)高低寄存器的采樣設置值。
16 Mhz 時鐘源的樣本值 -
因此需要使用上述公式在定時器 3 寄存器中配置波特率。對于我們的例子,它將是公式 4。之后,通過將 TR3 寄存器設置為 1 來啟動定時器 3 將完成 UART0 初始化定時器 3。要接收和發送 UART0 數據,請使用以下寄存器 -
SBUF 寄存器自動配置為接收和發送。要從 UART 接收數據,等待RI 標志置 1 并讀取 SBUF 寄存器并將數據發送到 UART0,將數據發送到 SBUF 并等待 TI 標志置 1 以確認數據傳輸成功。
為 UART 通信編程 Nuvoton N76E003
編碼部分很簡單,本教程中使用的完整代碼可以在本頁底部找到。代碼解釋如下,使用主函數中的語句將UART0初始化為9600波特率-
?
初始UART0_Timer3(9600);
?
上述函數在common.c文件中定義,它配置UART0,定時器3作為波特率源,模式1,波特率9600。函數定義如下-
?
void InitialUART0_Timer3(UINT32 u32Baudrate) //使用 timer3 作為波特率發生器 { P06_Quasi_Mode; //設置UART引腳為準模式傳輸 P07_Input_Mode; //將UART引腳設置為接收 SCON = 0x50的輸入模式;//UART0 Mode1,REN=1,TI=1 set_SMOD; //UART0 雙倍速率使能 T3CON &= 0xF8; //T3PS2=0,T3PS1=0,T3PS0=0(Prescale=1) set_BRCK; //UART0 波特率時鐘源 = Timer3 #ifdef FOSC_160000 RH3= HIBYTE(65536 - (1000000/u32Baudrate)-1); /*16 MHz */ RL3= LOBYTE(65536 - (1000000/u32Baudrate)-1); /*16 MHz */ #endif #ifdef FOSC_166000 RH3= HIBYTE(65536 - (1037500/u32Baudrate)); /*16.6 兆赫*/ RL3 = LOBYTE(65536 - (1037500/u32Baudrate)); /*16.6 MHz */ #endif set_TR3; //觸發Timer3 set_TI; //對于 printf 函數必須設置 TI = 1 }
?
如前所述,聲明是一步一步完成的,寄存器也相應地配置。但是,在N76E003的BSP庫中,有一個bug,就是代替P07_Input_Mode;有P07_Quasi_Mode。因此,UART 接收功能將不起作用。
波特率也根據波特率輸入并使用數據表中給出的公式進行配置。現在,在 main 函數或while 循環中,使用了 printf 函數。要使用printf函數,TI 需要設置為 1。除此之外,在while 循環中,使用 switch case 并根據接收到的 UART 數據打印該值。
?
while(1) { printf("\r\n按 1 或按 2 或按 3 或按 4"); 操作 = Receive_Data_From_UART0(); switch (oper) { case '1': printf("\r\n1 被按下"); 休息; case '2': printf("\r\n2 被按下"); 休息; case '3': printf("\r\n3 被按下"); 休息; case '4': printf("\r\n4 被按下"); 休息; 默認值: printf("\r\n按錯鍵"); } Timer0_Delay1ms(300); } }
?
好吧,對于 UART0 接收Receive_Data_From_UART0();?? 使用功能。它也在common.c庫中定義。
?
UINT8 Receive_Data_From_UART0(void) { UINT8 c; 而(!RI); c = SBUF; RI = 0; 返回(c); }
?
它將等待 RI 標志為 1 并使用變量 c 返回接收數據。
閃爍代碼和輸出
該代碼返回 0 個警告和 0 個錯誤,并使用 Keil 的默認閃爍方法進行閃爍。如果您不確定如何編譯和上傳代碼,請查看nuvoton 入門文章。以下幾行確認我們的代碼已成功上傳。
?
重建開始:項目:printf_UART0 重建目標'GPIO' 正在編譯PUTCHAR.C... 正在編譯Print_UART0.C...正在 編譯Delay.c...正在 編譯Common.c...正在 組裝STARTUP.A51...正在 鏈接... 程序大小:數據=54.2 xdata=0 代碼=2341 從“.\Output\Printf_UART1”... “.\Output\Printf_UART1”創建十六進制文件 - 0 個錯誤,0 個警告。 構建時間已用:00:00:02 加載“G:\\n76E003\\software\\N76E003_BSP_Keil_C51_V1.0.6\\Sample_Code\\UART0_Printf\\Output\\Printf_UART1” 閃存擦除完成。 Flash 寫入完成:已編程 2341 字節。 Flash 驗證完成:已驗證 2341 字節。 閃存加載于 15:48:08 完成
?
開發板通過編程器和筆記本電腦使用 USB 轉 UART 模塊連接到電源。要顯示或發送 UART 數據,需要串行監控軟件。我在這個過程中使用了tera 術語。
如下圖所示,我能夠顯示從我們的 nuvoton 控制器發送的字符串,并將其顯示在串行監視器軟件上。還能夠從串行監視器讀取值。
#include "N76E003.h"
#include "SFR_Macro.h"
#include "函數定義.h"
#include "Common.h"
#include "延遲.h"
/*================================================= ============================*/
無效主要(無效)
{
字符操作;
初始UART0_Timer3(9600);
TI = 1; // 使用了 printft 函數。
printf("Hello CircuitDigest\r\n");
而(1)
{
printf("\r\n按 1 或按 2 或按 3 或按 4");
操作 = Receive_Data_From_UART0();
開關(操作){
情況1':
printf("\r\n1 被按下");
休息;
案例“2”:
printf("\r\n2 被按下");
休息;
案例“3”:
printf("\r\n3 被按下");
休息;
案例“4”:
printf("\r\n4 被按下");
休息;
默認:
printf("\r\n按錯鍵");
}
Timer0_Delay1ms(300);
}
}
?
評論
查看更多