assembly AVR汇编代码,用于串口发送两个字符?

yizd12fk  于 2023-10-19  发布在  其他
关注(0)|答案(1)|浏览(156)

我只是想从我的ATMEGA32A发送一个字符到串行。这是代码,但它不工作。我不知道为什么,因为我认为我做的一切都是对的。有人能帮我修吗?
(BAUD费率:9600)

.cseg
.org 0x00 

main:
ldi r16,0x80
ldi r17,0x25
call USART_Init

loop:
ldi r20, 0x86
call USART_Transmit
ldi r20, 0xFF
call USART_Transmit
rjmp loop

USART_Init:
; Set baud rate
out UBRRH, r17
out UBRRL, r16
; Enable receiver and transmitter
ldi r16, (1<<RXEN)|(1<<TXEN)
out UCSRB,r16
; Set frame format: 8data, 2stop bit
ldi r16, (1<<URSEL)|(1<<USBS)|(3<<UCSZ0)
out UCSRC,r16
ret

USART_Transmit:
; Wait for empty transmit buffer
sbis UCSRA,UDRE
rjmp USART_Transmit
; Put data (r16) into buffer, sends the data
out UDR,r20
ret

我在串行终端上什么都没看到。我确信接线没问题。同时在串行终端设置中正确设置8位数据和2位停止位。

o2rvlv0m

o2rvlv0m1#

ldi r16,0x80
ldi r17,0x25
call USART_Init

它是0x2580 = 9600,但是这不是你初始化USART的方式。相反,它类似于初始化一个计时器:波特率越高,UBRR越小。
例如,当AVR以1 MHz运行时,您需要9600,则需要U2X = 1和UBRR = 0xc = 12。

U2X = 0不适用于1 MHz,因为产生的时钟将有7%的误差,这对于可靠的时钟操作来说太大了。
如果你使用一个合理的汇编器(如GNU),那么你可以让汇编器计算UBRR值,只要它在汇编时是已知的。在C语言中,你可以这样写:

void uart_init (void)
{
    unsigned short ubrr = -.6 + F_CPU / ((16L - 8*U2X_BIT) * BAUDRATE);

    UBRRH = ubrr >> 8;
    UBRRL = ubrr;

    UCSRA = (U2X_BIT << U2X) | ...

其中U2X_BIT01BAUDRATE是所需波特率,F_CPU是控制器的时钟频率(Hz)。
所以最好再次阅读ATmega32手册。

相关问题