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 DRFR 寄存器如何通过关联的 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 的状态。这个问题的两个重要问题是:

    • TXFFFR中的一个位,发送缓冲区满时变为1
    • RXFEFR中的一个位,接收缓冲区为空时变成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 中的每一个调用它。