Hallo Leute,
da ich ja neu bin bei der Controller programmierung bin habe ich mir
folgende Aufgabe ausgedacht, einfach zur Übung . Eine Led soll blinken
wärend eine andere LED über einen Taster geschaltet werden kann.
Die Taster Abfrage soll aber unbedingt über eine Interrupt-Routine
gehen.
Ist ja der Sinn und zweck der Übung.
Der Teil mir dem blinken der LED funktioniert alleine. Da liegt also
kein Fehler. Sobald ich aber die Interrupt-Routine dazumache geht nix
mehr, kann das Programm nicht Assemblieren . Komme einfach nicht
dahinter wo mein Fehler liegt.
Der Assembler MPLAB bringt folgende Fehler :
C:\USERS\Q\DESKTOP\LED_BLINKEN_INTERRUPT\LED_BLINKT_INTERRUPT.ASM 67 :
Overwriting previous address contents (0004)
Error[118]
C:\USERS\Q\DESKTOP\LED_BLINKEN_INTERRUPT\LED_BLINKT_INTERRUPT.ASM 67 :
Overwriting previous address contents (0004)
Error[118]
Und das geht immer weiter bis (0010)
Kann mir bitte einer auf die Sprünge helfen???
Danke im voraus .
Gruss Caine
Hi
>Die Taster Abfrage soll aber unbedingt über eine Interrupt-Routine>gehen.
Du weisst aber, das ein Taster prellt und mehrere Interrupts auslöst.
MfG Spess
bei Adresse 0 beginnen soll (Beachte das org 0x00 am Anfang), dann wird
sich das hier
1
ORG 0x004 ; interrupt vector location
2
movwf w_copy ; save off current W register contents
3
movf STATUS,w ; move status register into W register
4
movwf s_copy ; save off contents of STATUS register
5
....
wohl nicht so ausgehen, dass die entsprechenden Anweisung auf 0x004
beginnen können, denn durch den ersten Abschnitt liegen da ja schon
Instruktionen!
Du versuchst da gerade die selben Speicherzellen, für 2 verschiedene
Instruktionen zu benutzen.
Halte ein bischen mehr Ordnung in deinem Code! Das du in dem Kraut und
Rüben Salat an unterschiedlichen Schreibweisen und Einrückungen den
Überblick verlierst, wundert mich persönlich überhaupt nicht. Auch ist
die ORG Direktive kein Allheilmittel! Ordne deine Codeteile von vorne
herein am Besten gleich so an, dass sie so auch im Code stehen, wie sie
auch im Speicher stehen und benutze ORG nicht dazu den Code NACH VORNE
zu verschieben, sondern dazu um ev. Lücken im Code auf bestimmte
Endaddressen festzunageln.
1
ORG 0x00
2
goto init
3
4
ORG 0x04
5
movwf w_copy ; save off current W register contents
6
... hier dann die Interrupt Routine
7
8
init
9
bsf STATUS, RP0 ;Bank 1 setzen
10
movlw B'00000000' ;Port D alle out
11
.....
Ordnung im Code zu halten ist in allen Programmiersprachen wichtig. Aber
nirgends ist es wohl so wichtig wie in Assembler.
Karl Heinz Buchegger schrieb:> Halte ein bischen mehr Ordnung in deinem Code! Das du in dem Kraut und> Rüben Salat an unterschiedlichen Schreibweisen und Einrückungen den> Überblick verlierst, wundert mich persönlich überhaupt nicht.
Das was Karl Heinz Buchegger sagt.
Und definier deine Variablen am Anfang vom Programm, nicht mittendrin.
1
; Variablen festlegen
2
xxx EQU xxx
3
cblock ... endc
4
#define ...
5
6
org 0x0000
7
goto init
8
9
org 0x0004
10
; Interrupt-Routine
11
12
init
13
; Initialisierung
14
15
main
16
; Hauptprogramm
17
18
end
Das hier ist Teil von init
1
; RB0-Interrupt einstellen
2
bsf STATUS, RP0 ; auf Bank 1 umschalten
3
bsf OPTION_REG, INTEDG ; 0-1-Flanke an RB0
4
bcf STATUS, RP0 ; auf Bank 0 zurückschalten
5
6
bsf INTCON, INTE ; RB0-interrupt erlauben
7
bsf INTCON, GIE ; Interrupt generell erlauben
das solltest Du auch dorthin verschieben: nach dem Label "init".
Das ist nicht Bestandteil der ISR:
1
clrf PCLATH ; ensure page bits are cleared
2
goto main ; go to beginning of program
Hast Du wohl aus versehen mit kopiert und kann, an der Stelle, ersatzlos
gestrichen werden.
Gruß
John
nedim muratovic schrieb:> Die Taster Abfrage soll aber unbedingt über eine Interrupt-Routine> gehen.
Aber natürlich über den Timerinterrupt.
Macht jeder so, der kein Anfänger ist.
Peter
So Leute hab eure Ratschläge befolgt, ein wenig den Code aufgeräumt.
Zuerst die Config-Bits dan Variablen vergeben, Interrupt-Routine,
Hauptprogramm.
Nun habe ich keinen Error mehr. Das Prog. lässt sich assemblieren und
laden.
Nur Es funktioniert nicht so wie es sein soll.
Denn die eine LED blinkt zwar aber nach dem ich den Taster betätige geht
die andere LED an aber die erste blinkt nicht mehr. :-)
Es sieht so aus als hängt der controller im Interrupt fest.
Wie geht das dass der wieder aus dem Interrupt rauskommt ?
Gruss Caine
nedim muratovic schrieb:> Peter, bin aber Anfänger :-)
Ja, ich habe mich ungenau ausgedrückt.
Ich meinte, wer nicht ein Anfänger ist, der unbedingt auf die harte Tour
lernen will, wie man es nicht macht.
Ich will Dich aber nicht daran hindern, sattsam bekannte Fehler nochmal
selber zu machen. Solange Du das nicht auf Arbeit machst, d.h. für die
unnütze Zeit von anderen bezahlt wirst, ist das ja egal.
Peter
Dave Jones (eevblog) wünscht den Anfängern ja, dass ihre Schaltungen
nicht funktionieren. Weil man dann den Fehler suchen muss, und dabei
lernt man mehr, als wenn alles gleich funktionieren würde.
John
Du musst in der ISR einmal Port B auslesen und dann das RBIF-Bit im
INTCON-Register löschen. Sonst wird nach verlassen der ISR sofort wieder
ein Interrupt ausgelöst.
John
Hallo d_caine
habe gerade mal im Forum nachgeschaut und gesehen, dass Du doch bereits
ein einwandfreies, übersichtliches Muster
[Beitrag "Einfaches Assemblerprogramm"]
zum Aufbau eines Assemblerprogramms erhalten hast. Halt Dich doch an die
bisher entwickelte Systematik, dann hast es Du, aber auch Deine Helfer
erheblich einfacher!
Wenn Du gute Ratschläge nicht beachtest, brauchst Du Dich nicht zu
wundern, wenn die Helfer allmählich keine Lust mehr an der Hilfe für
Dich haben!
Grüße
GroberKlotz
Hallo John ,
Mein Taster liegt ja an RB4, habe das jetzt in der Initialisierung
geändert ,
jetzt passiert das was ich auch wollte, nämlich das RB4 den Interrupt
auslöst und nicht auch noch RB0.
; RB-Interrupt einstellen
bsf STATUS, RP0 ; auf Bank 1 umschalten
bsf OPTION_REG, INTEDG ; 0-1-Flanke an RB0
bcf STATUS, RP0 ; auf Bank 0 zurückschalten
bsf INTCON, RBIE ; RB0-interrupt erlauben
bsf INTCON, GIE ; Interrupt generell erlauben
Habe noch in der ISR das Port B ausgelesen und das RBIF Bit gelöscht
so wie Du es vorgeschlagen hast
movf PORTE
bcf INTCON, RBIF
Und das funktioniert RB4 macht die 2-te LED an die erste blinkt immer
noch.So wie ich das haben wollte.
Nur kann ich die LED nicht mehr ausschalten. Aber bin ziemlich weit
gekommen mit euren Vorschlägen .
Danke Jungs .
meinte PORT E ausgelesen ...so wie es im Code auch steht...sorry
...tippfehler.
Aber John, danke für die Tippst ...hat einiges geholfen .., muss nur
noch die ISR-Routine richtig machen. Wenn das abgeschlossen ist plane
ich eine zweite test Platine zu machen an der ich Temperatursensoren
anschließen kann und noch ein Display. Vor dem Hintergrund das ich plane
so oder so irgendwann mit den grafischen Displays zu arbeiten da sie
nicht mehr viel kosten aber gut aussehen, wäre es sinnvoll sofort ein
solchen zu holen und damit anzufangen oder wäre es besser erst mal mit
einem 2x14 Display zu starten ?
Caine