Beste,

Ik probeer voor school een programmaatje te schrijven die een interrupt afhandeld dmv RX.

Nu hebben we al voorbeeld code gekregen alleen deze werkt zonder interrupt. De voorbeeld code heb ik werkende en ik wou vanuit deze opstelling verder werken.
De code heb ik dus aangepast en een interrupt in geplaatst alleen krijg ik deze niet werkende. Zie ik iets over het hoofd?

Het bordje is een STK500 i.c.m een ATmega32.

In de m32def.inc staat het volgende:


; ***** INTERRUPT VECTORS***********************************************
.equ	URXCaddr	= 0x001a	; USART, Rx Complete
.equ	UDREaddr	= 0x001c	; USART Data Register Empty
.equ	UTXCaddr	= 0x001e	; USART, Tx Complete


/*
 * echo.asm
 *
 *  Created: 4/5/2013 10:32:22
 *   Author: Marc
 */ 


; verbind LEDs met port B en verbind D0, D1 met spare port RX, TX !!
; set RS232 terminal op met 19200 en stuur "0xAA" en "0x55" bijvoorbeeld
; echo : verstuur wat je ontvangt, de LEDs laten zien wat je ontvangt
.include "m32def.inc"
.def tmp = r18
.def inbyte = r19

.org 0x0000 
	rjmp init
	
.org URXCaddr ; zet rjmp op adres URXCaddr
	rjmp writeToLeds ; adres ISR

init:
	; set the baud rate, see datahseet p.167
	; F_OSC = 11.0592 MHz & baud rate = 19200
	; to do a 16-bit write, the high byte must be written before the low byte !
	; for a 16-bit read, the low byte must be read before the high byte !
	clr tmp;
	out UBRRH, tmp
	ldi tmp, 35 ; 19200 baud
	out UBRRL, tmp
	; set frame format : asynchronous, parity disabled, 8 data bits, 1 stop bit
	ldi tmp, (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0)
	out UCSRC, tmp
	; enable receiver & transmitter
	ldi tmp, (1 << RXEN) | (1 << TXEN)
	out UCSRB, tmp

	; init port
	ser tmp ; tmp = oxff
	out DDRB, tmp ; Port B is output port
	out PORTB, tmp ; LEDs uit
	sei

loop:
	; wait for data to receive
	;sbis UCSRA, RXC ; if bit RXC is set skip next instruction
	rjmp loop

writeToLeds:
	in inbyte, UDR ; read UDR
	mov tmp, inbyte ; copy byte to tmp
	com tmp ; inverteer alle bits
	out PORTB, tmp ; toon ontvangen byte in LEDs
	;rjmp loop
	reti



/*
origineel:
.include "m32def.inc"
.def tmp = r18
.def inbyte = r19

init:
	; set the baud rate, see datahseet p.167
	; F_OSC = 11.0592 MHz & baud rate = 19200
	; to do a 16-bit write, the high byte must be written before the low byte !
	; for a 16-bit read, the low byte must be read before the high byte !
	clr tmp;
	out UBRRH, tmp
	ldi tmp, 35 ; 19200 baud
	out UBRRL, tmp
	; set frame format : asynchronous, parity disabled, 8 data bits, 1 stop bit
	ldi tmp, (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0)
	out UCSRC, tmp
	; enable receiver & transmitter
	ldi tmp, (1 << RXEN) | (1 << TXEN)
	out UCSRB, tmp
	; init port
	ser tmp ; tmp = oxff
	out DDRB, tmp ; Port B is output port
	out PORTB, tmp ; LEDs uit
loop:
	; wait for data to receive
	sbis UCSRA, RXC ; if bit RXC is set skip next instruction
	rjmp loop
	in inbyte, UDR ; read UDR
	mov tmp, inbyte ; copy byte to tmp
	com tmp ; inverteer alle bits
	out PORTB, tmp ; toon ontvangen byte in LEDs
	rjmp loop


*/
	ldi tmp, (1 << RXEN) | (1 << TXEN)

Je moet ook het RXCIE bit setten, als je interrupts wil bij binnenkomende RS232-data.

Oke, hij werkt nu inderdaad.
Alleen knipperen de leds maar heel even en gaan ze dan weer uit. Hoe kan dat? Is het misschien omdat je na de reti weer het init label ingaat?

Ook snap ik niet echt hoe dit werkt:


(1 << TXEN)

Is dit een shift left en maakt hij van een 0(disable) een 1?

Dat is idd. een shift. Je verschuift 0x01 evenveel plaatsen naar links als de waarde van TXEN. Bij een ATmega32 komt TXEN overeen met 3. Dat wordt dus:


(1 << 0) = 0x01
(1 << 1) = 0x02
(1 << 2) = 0x04
(1 << TXEN) = 0x08
Enz...

Oke duidelijk :)

Iemand nog een idee hoe hij nouw kan knipperen ipv dat de waarde op de leds blijft staan?