ATMEGA32 usart 设置程序集



嗨,我一直在尝试使用 Atmel studio 6.1 实现串行通信和一个ATMEGA32 MCU。我阅读了数据表和帖子:ATMEGA32 UART通信

我想我或多或少得到了它应该如何设置,但我无法做到。我将 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

感谢您的帮助!

我可以看到您的代码中存在一些不一致之处。您是否认真阅读了 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 中写一些东西,但从不使用它(你在下一行为 r16 写另一个字符)。接下来,您将 0 写入 r17(0<<URSEL给出 r17=0x00),并将其存储在 UBRRH 中。为什么?你写0x00给UBRRH上面的几行。只有当您想在UBRRH或UBRSC中存储某些内容时,您才需要更改URSEL。所以这3行毫无意义。

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

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

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

最新更新