1

我有 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 模式以便更好地理解 Proteus_schema

4

1 回答 1

1

看起来问题出在未初始化的堆栈指针中。

复位后,SPH:SPL 初始化为 0x0000,因此任何对堆栈的写入(通过pushrcall)都将写入地址 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写不是更简单吗?

于 2020-04-05T21:24:09.050 回答