通信网络
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);
}
}
全部0条评论
快来发表一下你的评论吧 !