所以我正在读关于编程一个Atmel 328p,我想能够编程串行输入和输出,但我看到了一些我没有完全得到的东西:
UBRR0H在此程序集代码中称为UBRRnH:

USART_Init:
    ; Set baud rate
    out UBRRnH, r17
    out UBRRnL, r16
    ; Enable receiver and transmitter
    ldi r16, (1<<RXENn)|(1<<TXENn)
    out UCSRnB,r16
    ; Set frame format: 8data, 2stop bit
    ldi r16, (1<<USBSn)|(3<<UCSZn0)
    out UCSRnC,r16
    ret

当它在C代码中保留为名称UBRR0H时:
#define FOSC 1843200 // Clock Speed
#define BAUD 9600
#define MYUBRR FOSC/16/BAUD-1
void main( void ) {
    ...
    USART_Init(MYUBRR)
    ...
}

void USART_Init( unsigned int ubrr) {
    /*Set baud rate */
    UBRR0H = (unsigned char)(ubrr>>8);
    UBRR0L = (unsigned char)ubrr;
    Enable receiver and transmitter */
    UCSR0B = (1<<RXEN0)|(1<<TXEN0);
    /* Set frame format: 8data, 2stop bit */
    UCSR0C = (1<<USBS0)|(3<<UCSZ00);
}

根据制造CPU的Atmel的说法,这段代码的功能完全相同,那么为什么它可以被称为两个不同的东西呢?
谢谢)

最佳答案

根据Atmel documentationUBRRnL和UBRRnH是USART波特率寄存器。
UBRRnH包含四个最高有效位,UBRRnL包含USART波特率的八个最低有效位。
如我所见,如果您的设备有多个usart,例如USART0和USART1,您可以通过修改UBRRnLUBRRnH(可能还有其他寄存器)来选择所需的usart。将n(在UBRRnL和UBRRnH中)更改为所需的USART id号,并将其分配给UBRRnLUBRRnH
例如在程序集中:

.equ USART = 1
.if USART == 0
    .equ UBRRnH = UBRR0H
    .equ UBRRnL = UBRR0L
 .else
    .equ UBRRnH = UBRR1H
    .equ UBRRnL = UBRR1L
 .endif

因此,当从C源代码生成汇编代码时,编译器可能会将UBRR0Hs和UBRR0Ls编译为UBRRnLUBRRnL,并将它们定义为UBRR0HUBRR0L,如Robert Harvey所述。

07-24 19:22