Hallo,
Ik zit wat te prutsen met een ATtiny2313...
Als ik een knopje die op PB0(INT0) zit indruk moet een ledje op PD5 gaan branden.
Ik heb nu deze code geschreven in ASM:
.include "tn2313def.inc"
.def temp = R16
.org 0x0000
rjmp Init
.org INT0addr
rjmp ledje
Init:
ser temp
out DDRD, temp ;port D is output
LDI temp, LOW(RAMEND) ;Initiate Stackpointer
OUT SPL, temp
ldi temp, (1<<INT0)+(1<<INT1) ;Int masks 0 and 1 set
out GIMSK,temp
rjmp loopje
loopje:
rjmp loopje
ledje:
sbi PORTD, 5
rjmp loopjeDe code is wat bij elkaar geraapt uit andere voorbeelden.
Weet iemand wat ik fout doe?
pros
Prosper, yop la boum, c'est le roi du macadam (aldus Maurice Chevalier)
Fout = assembly gebruiken ipv C 
Je moet wel global interrupts activeren, anders reageert de AVR op geen enkele interrupt. SEI, dus.
Bekijk ook het MCUCR-register eens. Daar kan je instellen op welke toestand INT0 en INT1 moeten reageren.
Dat kan een laag niveau zijn. Af te raden IMHO, omdat er dan --zolang de pin laag is-- telkens opnieuw naar de ISR gesprongen wordt.
Een interrupt bij hoog-naar-laag of bij laag-naar-hoog lijkt me beter. Ook een interrupt bij elke niveau-wisseling is bruikbaar - 't hangt er van af, wat de toepassing is.
Verder zou ik bij zoiets geen plusteken maar een or-teken gebruiken:
ldi temp, (1<<INT0)+(1<<INT1)Het maakt in dit geval geen verschil, maar als je een boel bits in een register wil setten, en je tikt uit verstrooidheid tweemaal hetzelfde bit, dan gaat de assembler daar iets van maken dat je niet wil.
Voorbeeldjes, die een verschillend resultaat opleveren:
ldi temp, (1<<INT0)+(1<<INT1)+(1<<INT0)
ldi temp, (1<<INT0)|(1<<INT1)|(1<<INT0)
Enkel de tweede regel geeft het gewenste resultaat, ook al plaats je er nog 88 maal "|(1<<INT0)" bij.
[Bericht gewijzigd door pros op (22%)]
Op 23 december 2008 19:30:06 schreef pros:
Fout = assembly gebruiken ipv C
Dat is de volgende stap op mn lijstje;)
Bekijk ook het MCUCR-register eens.
Welke waarde moet ik in het MCUCR register schrijven om de interrupt te laten reageren op een negatieve flank?
pros
Prosper, yop la boum, c'est le roi du macadam (aldus Maurice Chevalier)
In C: 
MCUCR = (1 << ISC01) | (1 << ISC11);
Bedenk wel, dat een gewone drukknop contactdender zal veroorzaken, waardoor de ISR meermaals wordt aangeroepen, met onvoorspelbaar resultaat tot gevolg. Een software-vertraging maakt daar korte metten mee. Je moet dan wel --net voor het verlaten van de ISR-- de interrupt-flag wissen uit voorzorg.
EIFR |= (1 << INTF0); // Of (1 << INTF1)
Volgens mij loopt ook uw interupt routine vast.
Je moet terug keren uit je routine met "RETI" ipv "RJMP loopje".
Met RETI gaat hij terug naar daar waar hij bezig was voor de cpu in de interupt routine kwam
Nu gaat de interupt routine nooit afgewerkt zijn.
Op 23 december 2008 20:38:31 schreef pros:
In C:MCUCR = (1 << ISC01) | (1 << ISC11);
Ik kan het niet opmaken uit de datasheet... wat moet het zijn in ASM?
pros
Prosper, yop la boum, c'est le roi du macadam (aldus Maurice Chevalier)
Je moet terug keren uit je routine met "RETI" ipv "RJMP loopje".
Een reden te meer om C te gebruiken. 
Nou, niet echt, hoor. Ik ben allesbehalve afkerig van assembly. Daarmee heb je alles in de hand. Maar je moet voor iedere microprocessor/microcontroller telkens weer andere instructies gebruiken, en daar wordt een mens niet blij van...
@JOK:
ldi temp, (1 << ISC01) | (1 << ISC11)
out MCUCR,temp
Denk ik (hoop ik) toch...
Op 23 december 2008 21:23:14 schreef pros:
Nou, niet echt, hoor. Ik ben allesbehalve afkerig van assembly. Daarmee heb je alles in de hand. Maar je moet voor iedere microprocessor/microcontroller telkens weer andere instructies gebruiken, en daar wordt een mens niet blij van...
Off-topic: Eens. Ik heb een aantal dingetjes in assembler gedaan, maar in C ontwikkel je veel sneller, plus dat overstappen op een andere uC relatief pijnloos is. Wil natuurlijk niet zeggen dat je geen traditionele 'gotcha's' hebt (poorten die op een ATmega8 wel werken, en op een atmega32 net even anders werken; JTAG-interface wat in de weg zit, dat soort dingen)
Daarnaast: je eindigt al snel met het idee 'ja, laat ik allerlei hulproutines gaan maken en die in een library gooien... hrm, heet zoiets niet libc?'
Erelce
**** De beschikbare ruimte van een werkplek is omgekeerd evenredig met de grootte van deze werkplek **** AVR-Oefeningen op Electronics 4 Fun
Op 23 december 2008 21:13:29 schreef JOK:
[...]Ik kan het niet opmaken uit de datasheet... wat moet het zijn in ASM?
Ik heb verschillende oefeningen staan met interrupts in assembly...misschien leer je daar iets van?
dit zie ik bij jou niet staan
sei ; set interrupt
de 'sei' is ook zeer belangrijk!
en wil je in een bepaald gedeelte van jou pros prog geen interrupt dan zet je cli ; clear interrupt
Bedankt allemaal tot zover!
Ik heb nu deze code:
.include "tn2313def.inc"
.def temp = R16
.org 0x0000
rjmp Init
.org INT0addr
rjmp ledje
Init:
SEI
ser temp
out DDRD, temp ;port D is output
LDI temp, LOW(RAMEND) ;Initiate Stackpointer
OUT SPL, temp
ldi temp, (1<<INT0)|(1<<INT1) ;Int masks 0 and 1 set
out GIMSK,temp
ldi temp, (1 << ISC01) | (1 << ISC11)
out MCUCR,temp
sei
rjmp loopje
loopje:
rjmp loopje ; never ending loop (wait for interrupt)
ledje:
sbi PORTD, 5
retiHet ledje brand nu vanaf het begin en de drukknop heeft geen invloed meer:(
Wat zie ik over het hoofd?
pros
Prosper, yop la boum, c'est le roi du macadam (aldus Maurice Chevalier)
Hoe is die drukknop aangesloten? Tussen INT-pin en GND, samen met een pull-up weerstandje? Als dat laatste ontbreekt, kan je ook de interne pull-up inschakelen.
Verder blijft PD5 hoog, zodra er 1 enkele interrupt heeft plaatsgevonden.
Er is in je code nergens een instructie die de pin terug laag maakt.
die knop is met een pullup en een RC-netwerkje aangesloten op PB0.
Ik snap wel dat de LED altijd aan zal blijven, maar dat mag toch niet gebeuren als ik de knop nog nooit ingedrukt heb?
pros
Prosper, yop la boum, c'est le roi du macadam (aldus Maurice Chevalier)
Nu is de led inderdaad uit. Echter blijft de led uit ook nadat ik op de knop druk.
Moet ik misschien nog iets in de code toevoegen wat de uC duidelijk maakt op welke poort de knop hangt? Of hoort de PB0,INT0 altijd bij de INT0 interrupt?
pros
Prosper, yop la boum, c'est le roi du macadam (aldus Maurice Chevalier)
Ow! Daar heb ik over gekeken:
Ik zit wat te prutsen met een ATtiny2313...
Als ik een knopje die op PB0(INT0) zit indruk moet een ledje op PD5 gaan branden.
INT0 zit bij de ATtiny2313 op PD2.
Nog steeds geen reactie van de led...
Raak ik nu niet in de knoei omdat Port D al als output gedeclareerd is?
Zoja.. hoe maak ik alleen pin PD5 output en PD2 input?
flipflop
"We cannot solve our problems with the same thinking we used when we created them" - Albert Einstein
Heb je geen simulator? Zit in AVRstudio standaard in. Even 5 minuten simuleren en je weet waarom de led gelijk aan gaat.
pros
Prosper, yop la boum, c'est le roi du macadam (aldus Maurice Chevalier)
hoe maak ik alleen pin PD5 output en PD2 input?
Je kan daarvoor de sbi en cbi instructies gebruiken. Die werken niet enkel op een I/O-pin, maar ook op het bijbehorende DDR-bit.
Om PD2 als ingang te schakelen hoef je --na een RESET-- niets te doen. Alle I/O-pinnen zijn dan immers als ingang geschakeld.
Erelce
**** De beschikbare ruimte van een werkplek is omgekeerd evenredig met de grootte van deze werkplek **** AVR-Oefeningen op Electronics 4 Fun
als je met PB0 wil werken is het PCINT0 die je moet instellen en niet INT0 dat is niet hetzelfde...
ook moet jou Interrupt vector veranderen in .org PCIaddr
kijk eens naar deze oefening dan zie je de instellingen die je nodig hebt...alleen de sleep mode hoef je niet in te stellen.
volgens mij heb je genoeg met deze extra instellingen
ldi temp,(1<<PCINT0) ; selecteer PCINT0
out PCMSK, temp
ldi temp,(1<<PCIE) ; PCIE, PCInterrupt enable
out GIMSK, temp
sei ; toelaten ( set enable interrupts ) interrupts