Atmega8515 avr usart, avr memory, avr cpu loop simulation logs
Atmega8515 avr usart, avr memory, avr cpu loop simulation logs
我有这样的atmega8515代码
.nolist
.include "m8515def.inc"
.list
.equ fCK = 8000000
.equ BAUD = 9600
.equ UBRR_value = (fCK/(BAUD*16))-1
.cseg
.org 0
main:
rcall init_USART
LDI R16, 0xFF
OUT DDRC, R16
rcall USART_recieve
OUT PORTC, R16
LDI R16, 0x00
OUT DDRA, R16
in R16, PINA
OUT PORTC, R16
rcall USART_send
init_USART:
ldi R16, high(UBRR_value)
out UBRRH, R16
ldi R16, low(UBRR_value)
out UBRRL, R16
ldi R16, (1<<RXEN)|(1<<TXEN)|(0<<RXCIE)|(0<<TXCIE)|(0<<UDRIE)
out UCSRB, R16
ldi R16, (1<< URSEL)|(1<<UPM1)|(1<<UPM0)|(1<< UCSZ1)|(1<< UCSZ0)
out UCSRC, R16
ret
USART_send:
out UDR, R16
sending:
sbis UCSRA, TXC
rjmp sending
ret
USART_recieve:
sbis UCSRA, RXC
rjmp USART_recieve
in R16, UDR
ret
我运行这段代码在proteus中
并循环出现以下错误
PC=0x0030。 [AVR USART] RX 奇偶错误。 [U1]
PC=0x0024。 [AVR MEMORY] 接口未启用时的外部存储器读取 (SRE=0):[0x0260]。 [U1]
PC=0x0000。 [AVR MEMORY] 接口未启用时的外部存储器读取 (SRE=0):[0x0261]。 [U1]
PC=0x0000。 [AVR CPU] RET 地址 = 0x0000 [U1]
PC=0x0002。 [AVR MEMORY] 接口未启用时的外部存储器写入 (SRE=0):[0x0261]=01。 [U1]
PC=0x0002。 [AVR MEMORY] 接口未启用时的外部存储器写入 (SRE=0):[0x0260]=00。 [U1]**
PC=0x0024。 [AVR MEMORY] 接口未启用时的外部存储器读取 (SRE=0):[0x0260]。 [U1]**
PC=0x0002。 [AVR MEMORY] 接口未启用时的外部存储器读取 (SRE=0):[0x0261]。 [U1]**
为了更好地理解,我还包括了 proteus 模式
看起来问题出在未初始化的堆栈指针上。
重置后,SPH:SPL 被初始化为 0x0000,因此任何写入堆栈(通过 push
、rcall
等)都将写入地址 0x0000(已映射到寄存器 r0) 之后堆栈指针将减少并变为 0xFFFF。在 ATmega8515 中,0x0260 及以上的 RAM 位置被映射到外部存储器,这显然在您的原理图中没有连接。
将堆栈指针初始化添加为程序中的第一个操作,例如:
ldi r16, high(RAMEND)
out SPH, r16
ldi r16, low(RAMEND)
out SPL, r16
另外,你的程序没有循环,rcall USART_send
之后会超出init_USART:
标签。
可能您想在那个时候添加 rjmp main
。
为什么要用汇编语言编写程序?用C写不是更简单吗?
我有这样的atmega8515代码
.nolist
.include "m8515def.inc"
.list
.equ fCK = 8000000
.equ BAUD = 9600
.equ UBRR_value = (fCK/(BAUD*16))-1
.cseg
.org 0
main:
rcall init_USART
LDI R16, 0xFF
OUT DDRC, R16
rcall USART_recieve
OUT PORTC, R16
LDI R16, 0x00
OUT DDRA, R16
in R16, PINA
OUT PORTC, R16
rcall USART_send
init_USART:
ldi R16, high(UBRR_value)
out UBRRH, R16
ldi R16, low(UBRR_value)
out UBRRL, R16
ldi R16, (1<<RXEN)|(1<<TXEN)|(0<<RXCIE)|(0<<TXCIE)|(0<<UDRIE)
out UCSRB, R16
ldi R16, (1<< URSEL)|(1<<UPM1)|(1<<UPM0)|(1<< UCSZ1)|(1<< UCSZ0)
out UCSRC, R16
ret
USART_send:
out UDR, R16
sending:
sbis UCSRA, TXC
rjmp sending
ret
USART_recieve:
sbis UCSRA, RXC
rjmp USART_recieve
in R16, UDR
ret
我运行这段代码在proteus中 并循环出现以下错误
PC=0x0030。 [AVR USART] RX 奇偶错误。 [U1]
PC=0x0024。 [AVR MEMORY] 接口未启用时的外部存储器读取 (SRE=0):[0x0260]。 [U1]
PC=0x0000。 [AVR MEMORY] 接口未启用时的外部存储器读取 (SRE=0):[0x0261]。 [U1]
PC=0x0000。 [AVR CPU] RET 地址 = 0x0000 [U1]
PC=0x0002。 [AVR MEMORY] 接口未启用时的外部存储器写入 (SRE=0):[0x0261]=01。 [U1]
PC=0x0002。 [AVR MEMORY] 接口未启用时的外部存储器写入 (SRE=0):[0x0260]=00。 [U1]**
PC=0x0024。 [AVR MEMORY] 接口未启用时的外部存储器读取 (SRE=0):[0x0260]。 [U1]**
PC=0x0002。 [AVR MEMORY] 接口未启用时的外部存储器读取 (SRE=0):[0x0261]。 [U1]**
为了更好地理解,我还包括了 proteus 模式
看起来问题出在未初始化的堆栈指针上。
重置后,SPH:SPL 被初始化为 0x0000,因此任何写入堆栈(通过 push
、rcall
等)都将写入地址 0x0000(已映射到寄存器 r0) 之后堆栈指针将减少并变为 0xFFFF。在 ATmega8515 中,0x0260 及以上的 RAM 位置被映射到外部存储器,这显然在您的原理图中没有连接。
将堆栈指针初始化添加为程序中的第一个操作,例如:
ldi r16, high(RAMEND)
out SPH, r16
ldi r16, low(RAMEND)
out SPL, r16
另外,你的程序没有循环,rcall USART_send
之后会超出init_USART:
标签。
可能您想在那个时候添加 rjmp main
。
为什么要用汇编语言编写程序?用C写不是更简单吗?