Archiv verlassen und diese Seite im Standarddesign anzeigen : IRQ Programmieren in Assembler
Hi,
ich habe schon wieder ein Paa Fragen.
Und zwar, ich habe früher auf dem C64 in Assembler Programmiert, also eine Ganz dau bin ich nicht aber ich bekomme keinen IRQ hin.
Auf dem C64 hat man das früher so gemacht.
SEI
LDA #>einsprung ;Untere Adresse für den IRQ
STA $0314
LDA #<einsprung ;Obere Adresse für den IRQ
STA $0315
CLI
RTS
einsprung:
jsr ihrgendwo hin
cli
jmpe $EA44 (ob die jetzt noch stimmt weis ich nicht mehr)
Wie schreibt man einen Gescheiten IRQ bei einem Atmega 8515 in Assembler so das ich wie oben in dem Beispiel mit rcall in meine unterroutine Spingen kann und wieder zurück.
Danke schon mal für die Info.
Das Prinzip ist recht einfach.
Als erstes definiert man die Sprungadressen für die Interupts am Anfang des Programms.
rjmp reset ; Reset Handler
rjmp irq0 ; IRQ0 Handler <- definierte Sprungadresse
reti ; IRQ1 Handler
reti ; Timer1 Capture Handler
reti ; Timer1 Compare A Handler
reti ; Timer1 Compare B Handler
reti ; Timer1 Overflow Handler
reti ; Timer0 Overflow Handler
reti ; SPI Transfer Complete Handler
reti ; USART RX Complete Handler
reti ; UDR0 Empty Handler
reti ; USART TX Complete Handler
reti ; Analog Comparator Handler
reti ; IRQ2 Handler
reti ; Timer0 Compare Handler
reti ; EEPROM Ready Handler
reti ; Store Program memory Ready
Als nächstes an der Adresse des Reset Handlers zunächst einmal der Stack initialisiert.
reset:
ldi ZH, high(RAMEND)
ldi ZL low(RAMEND)
out SPH, ZH
out SPL, ZL
Anschließend initialisiert man die Peripherie und aktiviert glabal die Interupts.
Zum Schluss kommt dann noch das eigentliche Programm sowie die einzelnen Interupt Routinen.
Aber mehr dazu findest du hier im Wiki, auf www.mikrocontroller.net und auch im Datenblatt (das gibts auf www.atmel.com)
Ich hoffe dir trotzdem soweit geholfen zu haben.
Grüße,
Hanni
Ok danke werde ich mal morgen oder am WE testen wenn ich nicht weiter komme wende ich mich noch mal an dich wenn ich darf !
Nur zu. Ich schau aber nicht täglich hier rein.
Grüße,
Hanni
Hi cmc,
ich hab noch ein paar C64er hier rumstehen... muss die bei gelegenheit mal wieder anschliessen. Aber zu deinem Problem:
Ich konnte deinem Codebeispiel nicht ganz folgen... warum aktivierst du die Interrupt, schreibst die ISR-Adresse in den IRQ-Vektor und deaktivierst dann die Interrupts wieder?
Na egal. Du möchtest wahrscheinlich, wie es beim C64 üblich war, den IRQ-Vektor während der Programmausführung ändern.... das ist beim AVR aber leider nicht vorgesehen, da die Vektoren im FLASH stehen.
Du kannst aber hingehen und die Vektoren im SRAM ablegen... dann musst du nur den Vektor ins Z-Register laden und ein IJMP ausführen.
Gruß,
SIGINT
Also auf dem C64 war es ja so du hast zb deine Music Routine Laufen lassen und der Cursor hat weiter geblinkt, dafür haben wir den IRQ genommen. Im Prinzip hat man den Internen IRQ mit dem SEI unterborchen ihn auf seine Routine umgebogen und dann mit cli wieder frei gegeben, so das die Internen sachen weiter liefen. Ok ich werde mich am WE mal drann machen, ich denke ich werde das auch lehrnen ist halt nur ne umstellung.
Was hast du denn fürher mit deinen C64 gemacht also ich habe zb Intros Programmiert und kleiner Demos.
Stimmt,
das war beim C64 ja andersrum... SEI um Interrupts abzuschalten und CLI zu einschalten...
lange ist es her ;-)
Ich hab sowieso nur CrossAssembliert... früher hab ich nur mit BASIC rumgespielt. Aber wenn ich mich richtig erinnere, dann wurde immer der Raster-Interrupt für Sound-Routinen genommen, oder?
Aber zu deinem Prob:
.org 0x0000
rjmp start
...
rjmp ISR
...
.org irgendwas
ISR:
push ZL
in ZL,SREG
push ZL
push ZH
lds ZL,ISR_LOW_ADDRESS
lds ZH,ISR_HIGH_ADDRESS
icall
pop ZH
pop ZL
out SREG,ZL
pop ZL
reti
So sollte das eigentlich Funktionieren... ist aber relativ langsam. Vielleicht kann man noch einiges optimieren... aber mir fällt jetzt nicht direkt ein was.
Gruß,
SIGINT
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.