Search code examples
assemblymicrocontrolleravrproteus

Atmega8515 avr usart, avr memory, avr cpu loop simulation logs


I have such code for 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                  

I run this code in proteus and get the following errors cycled

PC=0x0030. [AVR USART] RX Parity Error. [U1]

PC=0x0024. [AVR MEMORY] External Memory Read while interface is not enabled (SRE=0): [0x0260]. [U1]

PC=0x0000. [AVR MEMORY] External Memory Read while interface is not enabled (SRE=0): [0x0261]. [U1]

PC=0x0000. [AVR CPU] RET address = 0x0000 [U1]

PC=0x0002. [AVR MEMORY] External Memory Write while interface is not enabled (SRE=0): [0x0261]=01. [U1]

PC=0x0002. [AVR MEMORY] External Memory Write while interface is not enabled (SRE=0): [0x0260]=00. [U1]**

PC=0x0024. [AVR MEMORY] External Memory Read while interface is not enabled (SRE=0): [0x0260]. [U1]**

PC=0x0002. [AVR MEMORY] External Memory Read while interface is not enabled (SRE=0): [0x0261]. [U1]**

I also include proteus schema for better understanding Proteus_schema


Solution

  • Looks like the problem is in uninitialized stack pointer.

    After the reset, SPH:SPL is initialized to 0x0000, therefore any writing to the stack (by push, rcall etc.) will write to address 0x0000 (which is mapped to register r0) after which the stack pointer will be decreased and become 0xFFFF. In ATmega8515 RAM locations at 0x0260 and above are mapped to the external memory, which is obviously is not connected in your schematics.

    Add stack pointer initialization as the first action in your program, e.g.:

    ldi r16, high(RAMEND)
    out SPH, r16
    ldi r16, low(RAMEND)
    out SPL, r16
    

    Also, there is no loop in your program, and after rcall USART_send it will go beyond init_USART: label.

    Probably you want to add rjmp main at that point.

    And why you need to write the program in assembler? Isn't it simpler to write it in C?