因此,我对此并不陌生,尝试学习寄存器和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外设发送和接收数据。
任何帮助将不胜感激。
答案 0 :(得分:3)
此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标志寄存器(AKA UARTFR
)。它包含一堆位,可以查询这些位以查看UART的状态。这个问题有两个重要的问题:
TXFF
是FR
中的一位,当发送缓冲区已满时,它变为1
。RXFE
是FR
中的一位,当接收缓冲区为空时,它变为1
DR
是UART数据寄存器(AKA 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调用此函数。