UART 和寄存器
UARTs & Registers
所以我是新手,正在尝试了解寄存器和 UART,并已获得以下代码进行研究。
#include <stdint.h>
typedef volatile struct {
uint32_t DR;
uint32_t RSR_ECR;
uint8_t reserved1[0x10];
const uint32_t FR;
uint8_t reserved2[0x4];
uint32_t LPR;
uint32_t IBRD;
uint32_t FBRD;
uint32_t LCR_H;
uint32_t CR;
uint32_t IFLS;
uint32_t IMSC;
const uint32_t RIS;
const uint32_t MIS;
uint32_t ICR;
uint32_t DMACR;
} pl011_T;
enum {
RXFE = 0x10,
TXFF = 0x20,
};
pl011_T * const UART0 = (pl011_T *)0x101f1000;
pl011_T * const UART1 = (pl011_T *)0x101f2000;
pl011_T * const UART2 = (pl011_T *)0x101f3000;
static inline char upperchar(char c) {
if((c >= 'a') && (c <= 'z')) {
return c - 'a' + 'A';
} else {
return c;
}
}
static void uart_echo(pl011_T *uart) {
if ((uart->FR & RXFE) == 0) {
while(uart->FR & TXFF);
uart->DR = upperchar(uart->DR);
}
}
void c_entry() {
for(;;) {
uart_echo(UART0);
uart_echo(UART1);
uart_echo(UART2);
}
}
我只是想知道是否有人可以解释 pl011
DR
和 FR
寄存器如何通过关联的 UART 外围设备传输和接收数据。
任何帮助都将不胜感激。
这里有一些关于此 UART 的不错的文档 - http://infocenter.arm.com/help/topic/com.arm.doc.ddi0183g/DDI0183G_uart_pl011_r1p5_trm.pdf
此程序的工作方式受 UART 是否处于 FIFO
模式的影响。我没有阅读足够多的 doco 来知道默认状态是什么。根据此模式,Tx 和 Rx 的操作略有不同。看起来该代码仅适用于单个单词,因此可能它不处于 FIFO 模式(或者对于此代码无关紧要)。
FR
是 UART 标志寄存器(又称 UARTFR
)。这包含一堆位,可以查询这些位以查看 UART 的状态。这个问题的两个重要问题是:
TXFF
是FR
中的一个位,发送缓冲区满时变为1
。
RXFE
是FR
中的一个位,接收缓冲区为空时变成1
DR
是 UART 数据寄存器(又称 UARTDR
)。这包含要传输的数据和已接收的数据。
所以看看代码的主要工作部分~
static void uart_echo( pl011_T *uart )
{
if ( ( uart->FR & RXFE ) == 0 ) // While the receive buffer is NOT empty
{
while( uart->FR & TXFF ); // Do <nothing> while the Tx buffer is full
// Read the content of the Data Register, converting it to uppercase(),
// then make a write to the DR, which initiates a transmit
uart->DR = upperchar(uart->DR);
}
}
所以这个函数正在回显它读取的任何内容,但是是大写的。该程序依次为三个 UART 中的每一个调用它。
所以我是新手,正在尝试了解寄存器和 UART,并已获得以下代码进行研究。
#include <stdint.h>
typedef volatile struct {
uint32_t DR;
uint32_t RSR_ECR;
uint8_t reserved1[0x10];
const uint32_t FR;
uint8_t reserved2[0x4];
uint32_t LPR;
uint32_t IBRD;
uint32_t FBRD;
uint32_t LCR_H;
uint32_t CR;
uint32_t IFLS;
uint32_t IMSC;
const uint32_t RIS;
const uint32_t MIS;
uint32_t ICR;
uint32_t DMACR;
} pl011_T;
enum {
RXFE = 0x10,
TXFF = 0x20,
};
pl011_T * const UART0 = (pl011_T *)0x101f1000;
pl011_T * const UART1 = (pl011_T *)0x101f2000;
pl011_T * const UART2 = (pl011_T *)0x101f3000;
static inline char upperchar(char c) {
if((c >= 'a') && (c <= 'z')) {
return c - 'a' + 'A';
} else {
return c;
}
}
static void uart_echo(pl011_T *uart) {
if ((uart->FR & RXFE) == 0) {
while(uart->FR & TXFF);
uart->DR = upperchar(uart->DR);
}
}
void c_entry() {
for(;;) {
uart_echo(UART0);
uart_echo(UART1);
uart_echo(UART2);
}
}
我只是想知道是否有人可以解释 pl011
DR
和 FR
寄存器如何通过关联的 UART 外围设备传输和接收数据。
任何帮助都将不胜感激。
这里有一些关于此 UART 的不错的文档 - http://infocenter.arm.com/help/topic/com.arm.doc.ddi0183g/DDI0183G_uart_pl011_r1p5_trm.pdf
此程序的工作方式受 UART 是否处于 FIFO
模式的影响。我没有阅读足够多的 doco 来知道默认状态是什么。根据此模式,Tx 和 Rx 的操作略有不同。看起来该代码仅适用于单个单词,因此可能它不处于 FIFO 模式(或者对于此代码无关紧要)。
FR
是 UART 标志寄存器(又称UARTFR
)。这包含一堆位,可以查询这些位以查看 UART 的状态。这个问题的两个重要问题是:TXFF
是FR
中的一个位,发送缓冲区满时变为1
。RXFE
是FR
中的一个位,接收缓冲区为空时变成1
DR
是 UART 数据寄存器(又称UARTDR
)。这包含要传输的数据和已接收的数据。
所以看看代码的主要工作部分~
static void uart_echo( pl011_T *uart )
{
if ( ( uart->FR & RXFE ) == 0 ) // While the receive buffer is NOT empty
{
while( uart->FR & TXFF ); // Do <nothing> while the Tx buffer is full
// Read the content of the Data Register, converting it to uppercase(),
// then make a write to the DR, which initiates a transmit
uart->DR = upperchar(uart->DR);
}
}
所以这个函数正在回显它读取的任何内容,但是是大写的。该程序依次为三个 UART 中的每一个调用它。