计算机和微控制器之间最简单的通信方式是通过UART,即通用异步收发器。它是一种串行通信协议,它只使用两根电线来传输数据。通常情况下,我们需要用COM端口将微控制器连接到计算机。但是现代的电脑和笔记本电脑不包括COM端口,因为USB端口已经取代了它们。
因此现在,微控制器和计算机之间的接口是通过USB端口和USB到RS232模块的帮助,这些模块基于USB到UART桥接ic,如Silicon Labs的CP210x或FTDI的FT232R。
UART的基本知识
在讨论LPC2148 mcu中的UART编程之前,让我们先看一些UART协议的基础知识.如前所述,UART协议只使用两根电线(或微控制器等设备中的引脚)来传输数据。其中一个是用来传输数据的,这个引脚在设备中被称为TX引脚。另一个引脚用于接收数据,称为RX引脚。
由于UART是一种串行通信,因此数据是以一系列数据包的形式传输的。通常,一个数据包由4部分组成:起始位、实际数据位、校验位和停止位。下图显示了UART中数据包的典型结构。
UART在LPC2148
在LPC2148的UART中,LPC214x系列mcu有两个UART块,称为UART0和UART1。每个UART块与两个引脚相关联,一个用于传输,另一个用于接收。
在UART0块中,设备中的TXD0(发送)和RXD0(接收)引脚分别为P0.0和P0.1。对于UART1, TXD1和RXD1引脚分别为P0.8和P0.9。
UART0 | UART1 | ||
TXD0 | P0.0 | TXD1 | P0.8 |
RXD0 | P0.1 | RXD1 | P0.9 |
两个UART模块是相同的,除了UART1块有一个额外的全调制解调器接口。这包括RS232兼容的所有引脚,如流量控制引脚(CTS, RTS)等。
两个UART块都有16字节的接收和发送FIFO结构来保存发送和接收数据。为了控制数据访问和汇编,UART块各有两个寄存器。
对于发射机操作,TX有两个特殊的寄存器,称为发射保持寄存器(THR)和发射移位寄存器(TSR)。为了传输数据,它首先被发送到THR,然后移动到TSR。
对于接收操作,RX有两个特殊的寄存器,称为接收缓冲区寄存器(RBR)和接收移位寄存器(RSR)。当接收到数据时,它首先存储在RSR中,然后移动到RBR。
LPC2148中与UART相关的寄存器
UART块涉及到许多寄存器。UART0和UART1有类似的寄存器结构,这里我们要提到UART0块的一些重要寄存器。为了访问UART1块中的寄存器,只需将“0”替换为“1”。
接收缓冲区寄存器(U0RBR):接收缓冲区寄存器由RX FIFO的顶字节组成。这是最先到达的数据,第0位包含最古老的数据。如果接收到的数据小于8位,则其余的位用0填充。为了访问U0RBR寄存器,必须将UART0线路控制寄存器(U0LCR)中的除数锁存访问位(DLAB)设置为0。参考用户手册,建议先读U0LSR寄存器,再读U0RBR寄存器。
发送保持寄存器(U0THR):发送保持寄存器由TX FIFO的顶字节组成,即最古老的数据。第0位(LSB)是第一个被传输的数据。为了访问U0THR寄存器,必须使UART0线路控制寄存器(U0LCR)中的除数锁存访问位(DLAB)为零。
UART0除数锁存寄存器(U0DLL和U0DLM):除数锁存寄存器决定UART0的波特率。除数锁存器是波特率发生器的一部分。U0DLL和U0DLM寄存器包含除数的低8位和高8位,它们一起形成16位除数值。由于它包含除数值,U0DLL不能包含0x00,因为除零无效。因此,U0DLM:U0DLL组合的最小值是0x00:0x01。为了访问除数锁存寄存器,必须将UART0线控制寄存器(U0LCR)中的除数锁存访问位(DLAB)设置为1。
分数除数寄存器(U0FDR):分数除数寄存器包含控制波特率发生器的预刻度的位。U0FDR包含用于预缩放的除数和乘数值。除数(DIVADDVAL)和乘数(MULVAL)的值存储为4位的值。U0FDR中的第0位到第3位包含波特率生成的预标量除数值。如果波特率发生器对UART的波特率有影响,除数值不能为0。U0FDR中的第4位到第7位包含了前标量乘法器值。为了UART0的正常工作,乘数中的值必须大于或等于1。即使不使用波特率生成器,这也适用。
中断使能寄存器(U0IER):中断启用寄存器用于启用或禁用UART0对应的中断。第0位为RBR中断,第1位为THRE中断,第2位为RX线状态中断,第8位为自动波特中断结束,第9位为自动波特超时中断。当位为0时,中断被禁用,当位为1时,中断被启用。
中断识别寄存器(U0IIR)中断标识寄存器用于提供暂挂中断的优先级和状态的代码。
先进先出控制寄存器(U0FCR): FIFO控制寄存器控制UART0中RX和TX FIFO的操作。位0用于启用或禁用FIFO。第1位用于重置RX FIFO。比特2用于重置TX FIFO。第6位和第7位用于控制中断必须发生的时间,即在多少个接收字符之后。
线路控制寄存器(U0LCR):线路控制寄存器用于设置传输或接收数据的格式。
位 | 的名字 | 价值 | 描述 |
1:0 | 字长 | 00 | 5位数据长度 |
01 | 6位数据长度 | ||
10 | 7位数据长度 | ||
11 | 8位数据长度 | ||
2 | 停止位 | 0 | 1停止位 |
1 | 2停止位 | ||
3. | 奇偶性使 | 0 | 禁用平价 |
1 | 使奇偶校验 | ||
5:4 | 奇偶性选择 | 00 | 奇校验 |
01 | 偶同位 | ||
10 | 迫使1平价 | ||
11 | 迫使0平价 | ||
6 | 中断控制 | 0 | 禁用中断传输 |
1 | 使打破传播 | ||
7 | 除数锁存存取位(DLAB) | 0 | 禁用对除数锁存的访问 |
1 | 启用对除数锁存的访问 |
线路状态寄存器(U0LSR):行状态寄存器给我们关于UART0中的RX和TX块的信息。
位 | 象征 | 价值 | 描述 |
0 | 接收数据 准备好了 |
0 | U0RBR是空的 |
1 | U0RBR包含有效数据 | ||
1 | 溢出错误 | 0 | 溢出错误状态是不活动的 |
1 | 溢出错误状态是活动的 | ||
2 | 奇偶校验错误 | 0 | 奇偶校验错误状态不活跃 |
1 | 奇偶校验错误状态为活动 | ||
3. | 框架的错误 | 0 | 帧错误状态是不活动的 |
1 | 帧错误状态是活动的 | ||
4 | 打破中断 | 0 | 中断中断状态是不活动的 |
1 | 中断中断状态是活动的 | ||
5 | 发射机保持寄存器空 | 0 | U0THR包含有效数据 |
1 | U0THR是空的 | ||
6 | 发射机空 | 0 | U0THR和/或U0TSR包含有效数据 |
1 | U0THR和U0TSR为空 | ||
7 | RX FIFO错误 | 0 | U0RBR不包含UART0 RX错误 |
1 | U0RBR中至少有一个UART0 RX错误 |
发送使能寄存器(U0TER):传输启用寄存器用于启用数据传输,即用于启用软件流程控制的实现。U0TER寄存器中的位7,即TXEN是用户唯一可用的位。当这个位高时,UART0 TX将继续发送数据。当此位变为0时,数据传输将停止。
UART中的波特率生成
UART波特率的计算公式如下
波特率=
波特率的生成需要遵循以下规则。
MULVAL的最小值必须为1,即0 < MULVAL <= 15。
DIVADDVAL的值可以在0到15之间,包括两个极端值。
0 <= divaddval <= 15。
为了在外围时钟频率为60mhz时获得9600(这是最常见的波特率)的波特率,必须执行以下计算。
尝试DLM (U0DLM) = 0, DIVADDVAL = 0, MULVAL = 1。将这些值代入上式,则DLL (U0DLL)为390.625。因为U0DLL是一个8位寄存器,这个值超出了范围。
通过继续这种试错方法,我们最终得到以下设置,以便获得9600(大约)的波特率,PCLK为60 MHz。
U0DLM = 1
U0DLL = 110
DIVADDVAL = 1
MULVAL = 15
LPC2148中的UART编程
我们将在下面的例子中看到UART0块的配置和初始化,在这个例子中我们向计算机发送一些数据。
# include < lpc214x.h >
#定义New_Line 0 xa
空白UARTWrite (char数据);
int主要(空白)
{
char味精[]={‘E’,‘l’,‘E’,‘c’,‘t’,‘r’,‘o’,‘n’,‘我’,' c ', ' s ', ' ', ' H ', ' u ', ' b ', ' \ 0};
int c = 0;/ /计数器
/*配置锁相环生成60mhzCCLK和PCLK* /
PLL0CON = 0 x01;
PLL0CFG = 0 x23;
PLL0FEED = 0 xaa;
PLL0FEED = 0 x55;
而(!(PLL0STAT & 0 x00000400));
PLL0CON = 0 x03;
PLL0FEED = 0 xaa;
PLL0FEED = 0 x55;
VPBDIV = 0 x01;
/*配置和初始化UART */
PINSEL0= 0 x5;/* P0.0选择TxD, P0.1选择RxD */
U0LCR = 0 x43;/*8位数据位,无奇偶校验,1位停止位| DLAB设置为1*/
U0DLL = 0 x6e;/* DLL设置为110*/
U0DLM = 0 x01;/* DLM设置为1*/
U0FDR = 0 xf1;/* MULVAL bits - 7:4)设置为15,DIVADDVAL (bits - 3:0)设置为1*/
U0LCR & = 0 x0f;//设置DLAB=0锁定MULVAL和DIVADDVAL
而(1)
{
而(味精[c] != ' \ 0 ')
{
UARTWrite(味精[c]);
c++;
}
UARTWrite (New_Line);
c = 0;
}
}
空白UARTWrite (char数据)
{
while ((U0LSR & 0x02));//等待THR为空
U0THR =数据;
}
2反应
你好管理员!我在本教程中发现了两个错误(//www.des-roubi.com/lpc2148-uart-tutorial/).他们是谁,
1)U0LCR不应该是0x43来设置DLAB。它必须是0x83
2)在(!(U0LCR & 0x02))检查THR状态实际上是错误的,它是while(!(U0LCR & 0 x20))。
这只是让你意识到错误,这样就不会有人被误导了。谢谢你!
你好,谢谢你指出来。我们会检查并做出必要的改变。