Trying using USART on Atmega328P (Arduino)

Go To Last Post
4 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,

 

I am trying desperatly to establish an UART communication between an Arduino Uno and the PC using interruptions, without success.

Language: assembler, compiler: AVR Studio 6.

 

The Arduino is connected through the USB port to the PC and I am using the Arduino IDE monitor on the PC to send a character and monitor the output.

 

What the program is supposed to do is: when I send a character from the monitor, the character should be immediately echoed back to the monitor.

 

I assume that the setting of the frame is ok (number of bits, parity, stop bits) as I have sent and decoded successfully characters in polling mode.

Interruptions seem a bit more 'tricky'. Basically I cannot get anything echoed to the monitor after sending a character.

 

I ran the debugger (simulator) but debugging interruptions without hardware is quite of a challenge!

 

I guess that the order in which interruptions are enabled/disabled is at the source of the problem but I tried all combinations.

I am only using RXC and UDRE interruptions and not TXC.

 

Thank you in advance for your help.

 

Here is the code:

 



.def rx_ready = r17

.DSEG
rx_byte:	.byte	1


.CSEG
.ORG 0x0000
	jmp Main ; 1  Reset Vector
	reti ; 2  External Interrupt Request 0
	reti ; 3  External Interrupt Request 1
	reti ; 4  Pin change Interrupt Request 0
	reti ; 5  Pin change Interrupt Request 1
	reti ; 6  Pin change Interrupt Request 2
	reti ; 7  Watchdog Timeout Interrupt
	reti ; 8  Timer/Counter2 Compare Match A
	reti ; 9  Timer/Counter2 Compare Match B
	reti ; 10 Timer/Counter2 Overflow
	reti ; 11 Timer/Counter1 Capture Event
	reti ; 12 Timer/Counter1 Compare Match A
	reti ; 13 Timer/Counter1 Compare Match B
	reti ; 14 Timer/Counter1 Overflow
	reti ; 15 Timer/Counter0 Compare Match A
	reti ; 16 Timer/Counter0 Compare Match B
	reti ; 17 Timer/Counter0 Overflow
	reti ; 18 SPI Serial Transfer Complete
	jmp USART_RXC_ISR ; 19 USART Rx Complete
	jmp USART_DRE_ISR ; 20 USART Data Register Empty
	reti ; jmp USART_TXC_ISR ; 21 USART Tx Complete
	reti ; 22 ADC Conversion Complete
	reti ; 23 EEPROM Ready
	reti ; 24 Analog Comparator
	reti ; 25 2-wire Serial Interface
	reti ; 26 Store Program Memory Ready


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

	ldi r16,0b10011000	;only reception interrupt enabled
	sts UCSR0B,r16

	ldi r16,103			;set baud rate (9600bds / 16MHz)
	sts UBRR0L,r16
	ldi r16,0
	sts UBRR0H,r16

	;keep default 8bits, 1 stop and no parity
	; as it works with Arduino IDE monitor.

	clr rx_ready		;no data ready to send in buffer rx_byte

	sei					;enable all interrupts


Loop:
	tst rx_ready		;byte stored?
	breq Loop			;no (Z=1). Loop

	clr rx_ready		;indicate no more byte

	lds r16,UCSR0B		;enable int UDRE
	sbr r16,(1<<UDRIE0)
	sts UCSR0B,r16

	lds r16,rx_byte		;get the byte
	sts UDR0,r16		;send it

	jmp Loop



;
;
; ============================================
;     I N T E R R U P T   S E R V I C E S
; ============================================
;


USART_RXC_ISR:
	push r16			;save r16 in stack
	in r16,SREG
	push r16			;save SREG in stack

	tst rx_ready		;byte already received?
	breq rx_store		;not received (0x00, Z=1). store this one
	
	pop r16				;retrieve SREG from stack
	out SREG,r16
	pop r16				;retrieve r16 from stack
	reti

rx_store:				;store received byte
	lds r16,UDR0		;read byte
	sts rx_byte,r16		;store it
	ser rx_ready		;indicate rx received

	pop r16				;retrieve SREG from stack
	out SREG,r16
	pop r16				;retrieve r16 from stack
	reti



USART_DRE_ISR:
	push r16			;save r16 in stack
	in r16,SREG
	push r16			;save SREG in stack

	lds r16,UCSR0B		;and disable int UDRE
	cbr r16,(1<<UDRIE0)	;variante: resend again and again
	sts UCSR0B,r16

	pop r16				;retrieve SREG from stack
	out SREG,r16
	pop r16				;retrieve r16 from stack
	reti

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Start simpler.

Just make a loop and send a character every second to the PC.

Once you get that working add the receive code.

 

I have no idea why you would use assembler.... and I don't wanna know

Keith Vasilakes

Firmware engineer

Minnesota

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

For the Mega328 reti is NOT correct in the ISR vectors as they are 4 bytes whilst reti is only 2 bytes therefore you vectors are wrong.

Add a nop after each reti or simply use the .org statement for each vector you want to use.

John Samperi

Ampertronics Pty. Ltd.

https://www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That was effectively the point!

 

I have no idea why you would use assembler.... and I don't wanna know

 I have coded in assembler on 8051 for almost 10 years and I have to say that I love coding in assembler! Naturally, moving to a different core needs a bit of starter (I started a couple of weeks ago on Arduino).

 

A great thank to you both for your support!