Atmel单片机:UBRR0H与UBRRnH的区别

时间:2021-09-12 13:54:10

So I am reading up on programming an Atmel 328p and I want to be able to program serial input and output but I saw something I didn't completely get:

所以我正在读Atmel 328p编程我想要能够编程串行输入和输出但是我看到了一些我没有完全理解的东西:

  • UBRR0H is called UBRRnH in this assembly code:

    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
    
  • While it stays as the name UBRR0H in this C code:

    当它在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);
    }
    

This code does the completely same according to Atmel who makes the CPU, so why can it be called two different things?

这段代码完全相同,根据Atmel的CPU,为什么它可以被称为两个不同的东西?

Thanks :)

谢谢:)

3 个解决方案

#1


4  

According to Atmel documentation UBRRnL and UBRRnH are USART Baud Rate Registers.

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

The UBRRnH contains the four most significant bits, and the UBRRnL contains the eight least significant bits of the USART baud rate.

UBRRnH包含四个最重要的位,UBRRnL包含USART波特率中最不重要的八个位。

Atmel单片机:UBRR0H与UBRRnH的区别

As I see if your device has multiple USARTs for example USART0 and USART1 you can choose the one you need by modifying UBRRnL and UBRRnH (and maybe other registers too). Change the n (in UBRRnL and UBRRnH) to the required USART id number and assign it to UBRRnL and UBRRnH.

正如我所看到的,如果你的设备有多个USARTs,例如USART0和USART1,你可以通过修改UBRRnL和UBRRnH(也许还有其他寄存器)来选择你需要的。将n (UBRRnL和UBRRnH)更改为所需的USART id号,并将其分配给UBRRnL和UBRRnH。

For example in Assembly:

例如在组装:

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

So when Assembly code is generated from the C source, the compiler might compile the UBRR0Hs and UBRR0Ls to UBRRnL and UBRRnL and define them as UBRR0H and UBRR0L, as Robert Harvey stated.

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

#2


3  

In Nut/OS, I see this #define:

在Nut/OS中,我看到#define:

#define     UBRRnH   UBRR0H

It's entirely possible that they are equivalent.

它们完全有可能是等价的。

#3


0  

In the datasheet (using the The ATmega164P/324P/644P datasheet), Atmel explains the use of 'n' in the naming. It is because the MCU has 2 USARTs, USART0 and USART1 so it is upon you to replace 'n' with '0' or '1' depending on the USART you are using.
Use of #define can solve this,

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

#define UBRRnH UBRR0H

#1


4  

According to Atmel documentation UBRRnL and UBRRnH are USART Baud Rate Registers.

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

The UBRRnH contains the four most significant bits, and the UBRRnL contains the eight least significant bits of the USART baud rate.

UBRRnH包含四个最重要的位,UBRRnL包含USART波特率中最不重要的八个位。

Atmel单片机:UBRR0H与UBRRnH的区别

As I see if your device has multiple USARTs for example USART0 and USART1 you can choose the one you need by modifying UBRRnL and UBRRnH (and maybe other registers too). Change the n (in UBRRnL and UBRRnH) to the required USART id number and assign it to UBRRnL and UBRRnH.

正如我所看到的,如果你的设备有多个USARTs,例如USART0和USART1,你可以通过修改UBRRnL和UBRRnH(也许还有其他寄存器)来选择你需要的。将n (UBRRnL和UBRRnH)更改为所需的USART id号,并将其分配给UBRRnL和UBRRnH。

For example in Assembly:

例如在组装:

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

So when Assembly code is generated from the C source, the compiler might compile the UBRR0Hs and UBRR0Ls to UBRRnL and UBRRnL and define them as UBRR0H and UBRR0L, as Robert Harvey stated.

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

#2


3  

In Nut/OS, I see this #define:

在Nut/OS中,我看到#define:

#define     UBRRnH   UBRR0H

It's entirely possible that they are equivalent.

它们完全有可能是等价的。

#3


0  

In the datasheet (using the The ATmega164P/324P/644P datasheet), Atmel explains the use of 'n' in the naming. It is because the MCU has 2 USARTs, USART0 and USART1 so it is upon you to replace 'n' with '0' or '1' depending on the USART you are using.
Use of #define can solve this,

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

#define UBRRnH UBRR0H