1

因此,我正在阅读有关 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 的说法,这段代码完全一样,那为什么它可以被称为两个不同的东西呢?

谢谢 :)

4

3 回答 3

4

根据Atmel 文档,UBRRnL 和 UBRRnH 是 USART 波特率寄存器。

UBRRnH 包含 4 个最高有效位,而 UBRRnL 包含 8 个最低有效位的 USART 波特率。

USART 波特率寄存器

正如我所看到的,如果您的设备有多个 USART,例如 USART0 和 USART1,您可以通过修改UBRRnLUBRRnH(也可能还有其他寄存器)来选择您需要的一个。将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

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

于 2013-08-02T01:21:49.397 回答
3

In Nut/OS, I see this #define:

#define     UBRRnH   UBRR0H

It's entirely possible that they are equivalent.

于 2013-08-02T01:00:10.927 回答
0

在数据表中(使用 ATmega164P/324P/644P 数据表),Atmel 解释了命名中“n”的使用。这是因为 MCU 有 2 个 USART,USART0 和 USART1,因此您可以根据您使用的 USART 将“n”替换为“0”或“1”。
使用#define可以解决这个问题,

#define UBRRnH UBRR0H
于 2015-11-12T06:55:59.520 回答