1

您好我一直在尝试使用 Atmel studio 6.1 和 ATMEGA32 单片机实现串行通信。我阅读了数据表和帖子: ATMEGA32 UART Communication

我想我或多或少地知道它应该如何设置,但我无法做到。我将 URSEL 的值设置为 1 以便写入它,但是当我运行模拟时,它似乎没有写入它,当我向它写入 0 并写入 UBRRH 时,我可以看到 UCSRC 和UBRRH 写入相同的值。

这是代码的副本...

 jmp RESET

 RESET:

    ldi r16, $12
    out UCSRA, r16
    ldi r17, $00
    ldi r16, $47

    out UBRRL,  r16
    out UBRRH,  r17
    ; Enable receiver and transmitter
    ldi r16,    (1<<RXEN) | (1<<TXEN)
    out UCSRB, r16

    ; Set frame format: 8 data, 1 stop bit
    ldi r16, (1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1)
    out UCSRC, r16
    ldi r16, $80
    ldi r17, (0<<URSEL)
    out UBRRH,  r17
loop:
    ldi r16, $41
    jmp TX

TX:
    sbis UCSRA, UDRE
    rjmp TX
    ;move data to the buffer
    out UDR, r16
    jmp loop

谢谢您的帮助!

4

1 回答 1

0

我可以在您的代码中看到一些不一致之处。您是否认真阅读了 Atmega32 数据表,尤其是有关 USART 模块 SFR 的部分?

ldi r16, $12
out UCSRA, r16

为什么要在 UCSRA 中设置 FE 位(位 4)?这是只读位,数据表显示:“写入 UCSRA 时始终将此位设置为零。” UCSRA 的初始值为 0x20,只有位 0、1 和 6 是 R/W,因此将 0x22 写入 UCSRA 以设置 U2X 位(我认为这是您的意图)。

ldi r16, $80
ldi r17, (0<<URSEL)
out UBRRH,  r17

我不完全理解以上几行。你在 r16 中写了一些东西,但从不使用它(你在下一行写了另一个 char 到 r16)。接下来将 0 写入 r17(0<<URSEL给出 r17=0x00)并将其存储在 UBRRH 中。为什么?您在上面的某些行中将 0x00 写入 UBRRH。仅当您想在 UBRRH 或 UBRSC 中存储某些内容时才需要更改 URSEL。所以这3行没有意义。

init USART 和在循环中发送 char 的代码应如下所示:

INIT:
    ldi r16, $22
    out UCSRA, r16
    ldi r17, $00
    ldi r16, $47
    out UBRRL, r16
    out UBRRH, r17
    ldi r16, (1<<RXEN) | (1<<TXEN)
    out UCSRB, r16
    ldi r16, (1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1)
    out UCSRC, r16
LOOP:
    ldi r16, $41
TX:
    sbis UCSRA, UDRE
    rjmp TX
    out UDR, r16
    rjmp LOOP

如果您正在使用模拟工具,请注意 - 它们有时会显示毫无意义的结果,如果您真的不了解处理器内部发生的事情,请不要相信。

于 2015-01-10T19:00:39.510 回答