Ich versuche schon seit heute morgen mein Programm zum laufen zu bringen
und mir sind mittlerweile die Möglichkeiten ausgegangen.
Ich möchte lediglich eine Led mit einem Taster ansteuern und dass über
einen Interrupt (Ich weiß dass es eigentlich Sinnlos ist mit dem
Interrupt).
Ich habe bereits viele Seiten abgeklettert, aber keins der Beiträge
konnte mein Problem lösen.
Nicht einmal dieser hier:
Beitrag "Externer Interrupt - ATmega328P - Assembler"
Dass es nicht funktioniert hat nichts mit meinem uC zu tun, denn ich
teste die Programme immer zu erst mit dem AVR Simulator und auch da wird
der INT0 nicht einmal angesprungen.
Vielleicht kann mir ja jemand helfen ^^
Peter schrieb:> Vielleicht versuchst du es erstmal in c und dann in Assembler
Wie oft muss ich das den noch gesagt bekommen.
C löst meine Probleme auch nicht!
Ich bringe mir bewusst Assembler bei, da ich die internen Abläufe einer
MCU verstehen möchte.
MerryXmas schrieb:>>ldi temp1, (1 << ISC01)|(1 << ISC01)>> Wahrscheinlich meinst Du:>> ldi temp1, (1 << ISC01)|(1 << ISC00)>> Solche Schludereien krass nix gut beim Proggen.
Das ist schon besser, genau.
Aber es klappt dennoch nicht :/
Hier noch mal ein Anhang.
Darauf ist zu erkennen, dass der PIN_2 von PORT_D (von mir) auf HIGH
geschaltet wurde und dennoch wird kein Interrupt ausgelöst.
> MerryXmas schrieb:>>> rjmp init>>> rjmp int_0>>>> Da sind zwei "r" zuviel.
Das habe ich jetzt auch korrigiert.
Noch irgendeine Idee?
Laie Jonas schrieb:> Peter schrieb:> Vielleicht versuchst du es erstmal in c und dann in Assembler>> Wie oft muss ich das den noch gesagt bekommen.> C löst meine Probleme auch nicht!> Ich bringe mir bewusst Assembler bei, da ich die internen Abläufe einer> MCU verstehen möchte.
Das ist lobenswert. Aber wie man sieht wohl einfach etwas viel für den
Anfang. Außerdem kannst du dir wenn du es in c machst ja parallel den
Assembler Code anschauen den der Compiler ausspuckt.
Hallo,
Laie Jonas schrieb:> ;ldi temp1, 0b00000001 ;Keine Ahnung welchen Zweck die ext. int.> Flag Register erfüllen> ;store EIFR, temp1
nur wegen der Frage: damit wird das Interrupt-Flag zurückgesetzt.
Das wird gesetzt, wenn der Interruot ausgelöst wird und vom Aufruf der
Interruptroutine autimatisch wieder gelöscht. Es gibt auch Interrupts,
wo das nicht automatisch passiert, das Datenbaltt weiß, welche.
Hir wird es gelöscht, um einfach sicherzustellen, daß es am Anfang
gelöscht ist. Es wird von der Hardwrae ja auch dann gesetzt, wenn die
Interrupts global noch gesperrt sind. Das kann dann ja nach Programm
durchuaus ungewollte Ergebinsse bringen.
Man kann ja auch den Interrupt global gesperrt haben und fragt z.B. das
Flag selber ab, ob ein Interrupt erzeugt wird.
Kann durchaus in einigen Fällen auch Sinn machen.
Programmanfang sah bei mir immer so aus:
reset: ldi TEMP_A,low(RAMEND) ; Stack an das interne Ram-Ende
26
out SPL,TEMP_A
27
ldi TEMP_A,high(RAMEND)
28
out SPH,TEMP_A
wenn man jetzt den Prozessor wechselt, muß man kaum was anpassen.
Die Reihenfolge, in der man die Vectoren einträgt, ist egal.
Man kann auch einfach RETI eintragen, um einen Aufruf abzufangen, der
noch nicht fertig ist. Oder auch rjmp statt jmp...
Definitionen.inc enthält bei generell die Beschreibungen der benutzten
Pins als Kommentar, dazu den ganzen .equ Kram meiner eigenen Pin-,
Register, Ram-Adressennamen usw.
So kann man das gut "recyclen" und ich kann es auch nach 10 Jahren noch
enträtseln, was uch da verzapft habe...
Gruß aus Berlin
Michael
Laie Jonas schrieb:> Vielleicht kann mir ja jemand helfen ^^
Und was genau soll deine INT-routine machen ?
1
lditemp1,(1<<LED)
2
outPORTD,temp1
Da wird, je nach Beschaltung, die LEDein einziges mal entweder
ein- oder ausgeschaltet und das wars dann.
Wenn die LED falschrum angeschlossen ist, wird sie nicht einmal
aufleuchten.
Laie Jonas schrieb:> ldi temp1, (1 << ISC01)|(1 << ISC01) ;INT0 bei steigender Flanke
Mit 2 mal ISC01 ist das = "fallender Flanke" - da kannst Du den Pin
setzten, bis es Ostern wird :-)
MerryXmas schrieb:> Da sind zwei "r" zuviel.
Bzw. anders gesagt, das rjmp wird auf dem falschen Interruptvektor
plaziert, da ein rjmp kürzer ist, als der Abstand der Vektoren.
Die saubere Lösung ist daher, mit der .org Anweisung immer die richtige
Adresse zu erzwingen. Dann wäre es auf dem ATmega88 und auf dem
ATmega328 lauffähig.
Mit Assembler muß man viel sorgfältiger und disziplinierter als mit C
programmieren.
Laie Jonas schrieb:> C löst meine Probleme auch nicht!
Das ist aber sehr weit aus dem Fenster gelehnt. Du hast ja keine C-Code
gepostet, den man reviewen könnte.
Peter schrieb:> Aber wie man sieht wohl einfach etwas viel für den> Anfang.
Den Eindruck habe ich auch. Man baut damit nur noch weitere Fehler ein,
anstatt sich besser auf das eigentliche Problem zu fokussieren.
Abgesehen davon, daß es hier mehr C-Experten gibt.
Dieter F. schrieb:> Ich bin jetzt kein Assembler-Freak - aber so sollte es funktionieren> (zumindest im Simulator, da prellt nichts ...):
Das ist genau der gleiche Code den ich bei mir verwende (Nach der
Korrektur natürlich).
Leider scheint auch das nicht bei mir zu funken.
Wenn es bei dir und @MerryXmas funktioniert, dann stimmt wohl etwa nicht
mit meiner AVR-Studio Version (Erst kürzlich heruntergeladen).
Laie Jonas schrieb:> Leider scheint auch das nicht bei mir zu funken.
Fällt mir schwer, das nachzuvollziehen.
Laie Jonas schrieb:> Wenn es bei dir und @MerryXmas funktioniert, dann stimmt wohl etwa nicht> mit meiner AVR-Studio Version (Erst kürzlich heruntergeladen).
Ich verwende die aktuelle Atmel Studio 7 Version (7.0.1931). Mit meiner
Version funktioniert es prima (im Simulator).
Mit deinem Studio wird schon alles stimmen. Das verhält sich
grundsätzlich seltsam bei Interrupts.
Setz mal in die ISR einen Breakpoint, um setze den Eingang per
Stimuli-File.
Oder probier es gleich auf der echten Hardware. Wenn die led leuchtet,
hat es geklappt.
Oliver
Oliver S. schrieb:> Oder probier es gleich auf der echten Hardware. Wenn die led leuchtet,> hat es geklappt.
Es hat geklappt.
Nach mehrmaliger Fehlkorrektur hatte ich es einfach sein gelassen es auf
echter Hardware zu testen und habe einfach den Simulator benutzt.
Also ich probiere es immer auf der echten Hardware. Den Simulator
benutze ich nur, wenn ich wissen möchte, was intern mit den Registern
passiert, bzw. wenn irgendwelche Stringfunktionen baue oder der berühmte
Dauerbrenner Umwandlung von Zahlen oder "irgendwas von und nach ASCII".
Ich finde auch nicht, daß das zu schwer oder zuviel für den Anfang ist.
Eine LED leuchten lassen ist irgendwann geschafft, ein "Hallo Welt!" auf
einem Display ist irgendwann geschafft - und dann gibt es immer was
neues, was sich auszuprobieren und zu lernen lohnt. Dabei gibts
natürlich auch neue Fehler zu machen, neue Probleme und neue Fragen.
Finde ich völlig normal so.
Muss aber dazu sagen, daß ich schon Erfahrung mit Assembler vom x86
hatte. Und der hat die deutlich besseren Debugger, was die Bedienung
angeht. Der muss aber keine extra Hardware beherrschen, vielleicht
liegt's daran.
Lass Dich von den C-Fanboys hier nicht unterkriegen. Assembler auf dem
AVR ist cool und macht Spaß. Beim PIC könnte ich verstehen wenn man sagt
C ist besser. Der bietet nur sehr wenige Befehle und keinen großen
Registersatz wie der AVR, das braucht man aber, um mit Assembler Spaß
dran zu haben. Ich programmiere gerade meine AlarmSau in Assmbler, das
sind derzeit etwa 120kb Quellcode, um die 4300 Befehle... da fängt's
erst an, so richtig Spaß zu machen.
Ben B. schrieb:> Finde ich völlig normal so.
danke
Ben B. schrieb:> Ich programmiere gerade meine AlarmSau in Assmbler, das> sind derzeit etwa 120kb Quellcode, um die 4300 Befehle...
Mit welchen uC?
>Wahnsinn, auch hier wird bei mir im AVR Simulator nicht in die Int.>Vektor Tabelle gesprungen.>Die Endlosschleife läuft einfach weiter.
Hm... very komische Sache.
Stimmt die Controller-Einstellung im Simulator? Nicht, dass von Dir
unbemerkt ein ATmega48 simuliert wird oder so (alles schon dagewesen...)
Menüpunkt Debug, Untermenü "Check platform and device"
Normalerweise müsste im Simulator sofort (einen Maschinentakt später)
das Bit INTF0 im EIFR gesetzt werden, wenn Du PIND2 von 0 auf 1 änderst.
Passiert das?
Und was ist, wenn Du PIND in Ruhe lässt, aber INTF0 von Hand setzt? Wird
dann der Interruptvektor int_0 angesprungen?
Kannst Du beides noch testen, bitte?
MerryXmas schrieb:> Stimmt die Controller-Einstellung im Simulator? Nicht, dass von Dir> unbemerkt ein ATmega48 simuliert wird oder so (alles schon dagewesen...)> Menüpunkt Debug, Untermenü "Check platform and device">> Normalerweise müsste im Simulator sofort (einen Maschinentakt später)> das Bit INTF0 im EIFR gesetzt werden, wenn Du PIND2 von 0 auf 1 änderst.> Passiert das?>> Und was ist, wenn Du PIND in Ruhe lässt, aber INTF0 von Hand setzt? Wird> dann der Interruptvektor int_0 angesprungen?
Hatte ich bereits alles getestet und der das Bit INTF0 im EIFR wird auch
richtig gesetzt, wenn es zum Interrupt kommt.
Aber angesprungen wird die Int. Tabelle dennoch nicht :/
Ben B. schrieb:>>> Ich programmiere gerade meine AlarmSau in Assmbler>> Mit welchen uC?>> ATMega1284P. (und ATMega88 für's Terminal).
Sieht sehr interessant aus.
Wusste gar nicht, dass es so große Elkos gibt :D
Hab auch deinen Beitrag dazu entdeckt:
Beitrag "ambitioniertestes Lochraster-Projekt (und meine AlarmSau)"
Gibt noch viel größere Elkos... :) Der größte den ich hier habe, hat
6800µF bei 400 oder 450V, der passt aber nicht so gut auf die Platine.
Gibt auch welche im Stahlblechgehäuse für industrielle Anwendungen, da
sind der Größe keine Grenzen gesetzt.