www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik AVR Assembler Probleme/Fragen Interrupt


Important announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: Quantum (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Hallo Community,

ich bin gerade am Verzweifeln. Meine Erfahrung mit Assembler 
Programmierung ist ziemlich dürftig. Deshalb drehe ich mich wohl seit 
knapp 3 Std im Kreis.
Als Hardware wird ein Atmega644P verwendet. Hier der Code:
(Fragen stehen danach)
;
;Includes
.include "PFAD/m644Pdef.inc"


;LEDs
.EQU LED_1 = 6
.EQU LED_2 = 5
.EQU LED_3 = 4

;Registernamen
.def temp1 = r16
.def zeichen = r17

;Berechnen der UBRR_VAL anhand der Baud und der CPU Frequenz
.equ BAUD = 9600
.equ F_CPU = 19660800
.equ UBRR_VAL = ((F_CPU+BAUD*8)/(BAUD*16)-1)


;Interrupts
.org 0x0000    ;Beginn des Programms (Bei Reset oder Power-Down)
  jmp MAIN
.org 0x0004
  jmp ISR_INT1


;;;;;;
;MAIN;
;;;;;;
MAIN:  
  call INIT
  ldi zeichen, "b"
  call UARTOUT
  
LOOP:
  ldi temp1, (1 << LED_1) | (1 << LED_2) | (1 << LED_3)
  out PORTD, temp1
  jmp LOOP

;;;;;;;;;;;
;Interrupt;
;;;;;;;;;;;
ISR_INT1:
LOOP1:
  ldi temp1, (0 << LED_1) | (0 << LED_2) | (0 << LED_3)
  out PORTD, temp1
  jmp LOOP1
  reti

UARTOUT:
  lds temp1, UCSR0A
  sbrs temp1, UDRE0
  jmp UARTOUT
  sts UDR0, zeichen
  ret

;;;;;;;;;;;;;;;;;
;INITIALISIERUNG;
;;;;;;;;;;;;;;;;;

INIT:

;PORT D
  ldi temp1, (1 << LED_1) | (1 << LED_2) | (1 << LED_3)
  out DDRD, temp1
  out PORTD, temp1

;UART Initiaisierung
  ldi temp1, (1 << RXEN0) | (1 << TXEN0)
  sts UCSR0B, temp1
  ldi temp1, (1 << UCSZ00) | (1 << UCSZ01)
  sts UCSR0C, temp1

;Baudrate festlegen
  ldi temp1, HIGH(UBRR_VAL)
  sts UBRR0H, temp1
  ldi temp1, LOW(UBRR_VAL)
  sts UBRR0L, temp1

;Pin Change Interrupt
  ldi temp1, 1 << PCIE2
  sts PCICR, temp1
  ldi temp1, (1 << PCINT16) | (1 << PCINT20)
  sts PCMSK2, temp1

;Externe Interrupts
  ldi temp1, 1 << ISC11
  sts EICRA, temp1
  ldi temp1, 1 << INT1
  sts EIMSK, temp1

;Stack Initialisieren
  ldi temp1, LOW(RAMEND)
  out SPL, temp1
  ldi temp1, HIGH(RAMEND)
  out SPH, temp1

  sei ;Interrupts aktivieren

  ret

1. Der Interrupt wird nicht ausgelöst. Mir ist wohl klar, dass es nicht 
sinnvoll ist den Controller in der ISR "gefangen" zu halten. Die 
Intention ist einfach die, dass die LEDs sichtbar angehen. Ich hab 
allerdings keine Erklärung dafür, die Interruptsregister sind gesetzt, 
die Globalen Interrupts aktiviert und die Einsprungadressen definiert.

2. Des Weiteren ist zu sehen, dass ein Zeichen ausgegeben wird, nachdem 
die Initiaisierung aufgerufen wurde. Dieses Zeichen gibt er aber nur 
dann aus, wenn Controller

a) Programmiert wurde
b) Aus/Eingeschalten wurde

NICHT aber wenn der RESET Knopf betätigt wurde. Warum ?

Alls Assembler wurde der gavrasm unter Linux verwendet. Der code wird 
fehlerfrei assembliert.

Freue mich auf eure Hilfe

Hochachtungsvoll
Quantum

Autor: Thomas P. (topla)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Einen Call init zu machen und erst danach den Stack zu initialisieren 
ist keine gute Idee.

Thomas

Autor: spess53 (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Hi

>ISR_INT1:
>LOOP1:
>  ldi temp1, (0 << LED_1) | (0 << LED_2) | (0 << LED_3)
>  out PORTD, temp1
>  jmp LOOP1
>  reti

Und wie soll der Controller hier wieder rauskommen?

MfG Spess

Autor: Quantum (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Thomas P. schrieb:
> Einen Call init zu machen und erst danach den Stack zu initialisieren
> ist keine gute Idee.
>
> Thomas

Danke, dass löst schonmal das Problem mit dem Resettaster.


spess53 schrieb:
> Hi
>
>>ISR_INT1:
>>LOOP1:
>>  ldi temp1, (0 << LED_1) | (0 << LED_2) | (0 << LED_3)
>>  out PORTD, temp1
>>  jmp LOOP1
>>  reti
>
> Und wie soll der Controller hier wieder rauskommen?
>
> MfG Spess
Das ist rein zum Testen. Will erstmal dass er überhaupt reinspringt. 
Wenn er das dann tun sollte wird das mit sinnvollem Code belegt.

Grüße

Autor: Sascha Weber (sascha-w)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
wie hast du INT1 am Contoller beschaltet?

es ist keine gute Idee den PCINT einzuschalten, aber keine entsprechende 
ISR zu haben - dann springt er dir u.U. irgendwo ins Programm rein.
Am besten immer die komplette Interrupttabelle ins Program einbauen, und 
alle nicht benötigten ISR's mit RETI 'kurzschließen'!

Sascha

Autor: Quantum (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Sascha Weber schrieb:
> wie hast du INT1 am Contoller beschaltet?
>
> es ist keine gute Idee den PCINT einzuschalten, aber keine entsprechende
> ISR zu haben - dann springt er dir u.U. irgendwo ins Programm rein.
> Am besten immer die komplette Interrupttabelle ins Program einbauen, und
> alle nicht benötigten ISR's mit RETI 'kurzschließen'!
>
> Sascha

Danke für deine Antwort

Die ISR, die den PCINT2 abarbeitet ist implementiert. Übersichshalber 
hab ich den Code etwas gekürzt. Nach weiterem experimentieren ist mir 
aufgefallen, dass der PCINT16 Pin auf einen Interrupt anspricht. Der 
PCINT20 jedoch nicht. Bei beim INT1 Interrupt hat sich immer noch nichts 
getan.

Der INT1 Pin ist mit nem PullUp und nem Taster beschalten, der den Pin 
dann auf Masse zieht.

Gruß

Autor: Mark Leyer (m2k10) Benutzerseite
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Quantum schrieb:
> Der
> PCINT20 jedoch nicht.

JTAG aktiviert??

Autor: Uwe (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
> UARTOUT:
>   lds temp1, UCSR0A
>   sbrs temp1, UDRE0
>   jmp UARTOUT
>   sts UDR0, zeichen
>   ret

sbrs templ,UDRE0

hmm hieß sbrs nicht "skip if bits in Register are set" und als operand 
dahinter eine Bitmaske ?
also : sbrs templ,1<<UDRE0

Autor: spess53 (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Hi

>hmm hieß sbrs nicht "skip if bits in Register are set" und als operand
>dahinter eine Bitmaske ?
>also : sbrs templ,1<<UDRE0

Nein.

MfG Spess

Autor: Quantum (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Mark L. schrieb:
> Quantum schrieb:
>> Der
>> PCINT20 jedoch nicht.
>
> JTAG aktiviert??

JTAG hab ich mithilfe den Fuses deaktiviert

Uwe schrieb:
>> UARTOUT:
>>   lds temp1, UCSR0A
>>   sbrs temp1, UDRE0
>>   jmp UARTOUT
>>   sts UDR0, zeichen
>>   ret
>
> sbrs templ,UDRE0
>
> hmm hieß sbrs nicht "skip if bits in Register are set" und als operand
> dahinter eine Bitmaske ?
> also : sbrs templ,1<<UDRE0

Wenn ich das so mache bringt mir der Assembler einen Fehler. Die Ausgabe 
funktioniert ja auch.

Danke für die Hilfe

Gruß

Autor: Quantum (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Hab jetzt kurz ne kleine C Routine geschrieben, da funktionieren beide 
Interrupts tadellos. An dem Prozessor kann es also nicht liegen.

Grüße

Autor: Mark Leyer (m2k10) Benutzerseite
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Bist du sicher, dass kein Kurzschluss zwischen PD3 und PD4 ist? Du 
könntest auch mal einfach in der Hauptschleife den Taster abfragen und 
die LEDs ohne INT1 schalten.

Ha, nochmal in's Datenblatt geschaut: Hab den Fehler! (glaub ich)
sts EIMSK ist falsch, muss out EIMSK sein!

Mark

Autor: Quantum (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Mark L. schrieb:
> Bist du sicher, dass kein Kurzschluss zwischen PD3 und PD4 ist? Du
> könntest auch mal einfach in der Hauptschleife den Taster abfragen und
> die LEDs ohne INT1 schalten.
>
> Ha, nochmal in's Datenblatt geschaut: Hab den Fehler! (glaub ich)
> sts EIMSK ist falsch, muss out EIMSK sein!
>
> Mark

Danke !!
Es funktioniert :)

Darf ich erfahren wie du das herausgefunden hast, bzw wo das steht. Was 
hat dieses Register mit den I/O Registern zu tun ? Oder hab ich das mit 
dem out falsch verstanden ?

Das Problem mit dem Pin Chang Interrupt auf PCINT20 bleibt allerdings. 
PCINT16 funktioniert. Obwohl ich beide eingeschalten habe.

Autor: spess53 (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Hi

>Das Problem mit dem Pin Chang Interrupt auf PCINT20 bleibt allerdings.
>PCINT16 funktioniert. Obwohl ich beide eingeschalten habe.

Hast du die Frage

Beitrag "Re: AVR Assembler Probleme/Fragen Interrupt"

beachtet?

MfG Spess

Autor: Quantum (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
spess53 schrieb:
> Hi
>
>>Das Problem mit dem Pin Chang Interrupt auf PCINT20 bleibt allerdings.
>>PCINT16 funktioniert. Obwohl ich beide eingeschalten habe.
>
> Hast du die Frage
>
> Beitrag "Re: AVR Assembler Probleme/Fragen Interrupt"
>
> beachtet?
>
> MfG Spess

Wie ich schon geschrieben habe, ist JTAG abgeschaltet. Die ISR wird mit 
einem entsperechendem C Programm problemlos, an beiden Pins, aufgerufen

Autor: spess53 (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Hi

Außer deinem, jetzt unbekanntem, Programm und dem JTAG-Interface gibt es 
nichts, was den Interrupt verhindern könnte.

MfG Spess

Autor: Mark Leyer (m2k10) Benutzerseite
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Quantum schrieb:
> Darf ich erfahren wie du das herausgefunden hast, bzw wo das steht. Was
> hat dieses Register mit den I/O Registern zu tun ? Oder hab ich das mit
> dem out falsch verstanden ?

Das out geht für alle Register bis 0x5F Die Adresse ist bei out aber um 
0x20 versetzt. Alles was mit out erreichbar ist, steht auch mit der 
out-Adresse in der *def.inc, daher führt sts zum Beschreiben eines 
falschen IO-Registers. Ist manchmal etwas nervig bei den Atmels, gibt 
immer wieder Unterschiede. Steht einmal in der *def.inc und im 
Datenblatt die IO-Register mit den doppelten Adressen.

In kurzen Programmen sind das und die sbr/sbrs-Geschichte so 
Fehlerquellen, die man einfach nicht direkt sieht und die die 
Fehlersuche selbst in einem 20-Zeiler zur nervenaufreibenden Sache 
werden lassen.

Mark

Autor: Jobst M. (jobstens-de)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Mark L. schrieb:
> Das out geht für alle Register bis 0x5F Die Adresse ist bei out aber um
> 0x20 versetzt. Alles was mit out erreichbar ist, steht auch mit der
> out-Adresse in der *def.inc, daher führt sts zum Beschreiben eines
> falschen IO-Registers. Ist manchmal etwas nervig bei den Atmels, gibt
> immer wieder Unterschiede.


IN, LD, LDI, LDD, LDS, MOV, OUT, ST, STD, STS

... und dann auch noch mit unterschiedlichen Adressen, je nach Befehl 
...
Manchmal habe ich den Eindruck, daß hier völlige Anfänger den 
Befehlssatz entworfen haben. Man könnte meinen, daß sie nicht mal den 
8051 kannten. Dort gibt es einen Befehl für alle diese (und noch 
weitere) Aktionen: MOV
Um den Rest kümmert sich der Kompiler. Und genau von dem erwarte ich 
diese Leistung!

Wenn man ein Programm von einem AVR in einen anderen überträgt, kann es 
bei SFRs die dort an anderer Stelle hocken, passieren, daß man IN und 
OUT gegen LDS und STS tauschen muß. Es gibt nicht mal eine Meckermeldung 
vom Kompiler. Also muß ich von Hand heraussuchen, welches SFR nun in 
welchem Bereich sitzt. Da kann ich die Adresse auch gleich von Hand 
eintragen!

*kopfschüttel** - Die Dinger sind eigentlich völliger Murks!


Gruß

Jobst

Autor: Thomas P. (topla)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Jobst M. schrieb:
> Manchmal habe ich den Eindruck, daß hier völlige Anfänger den
> Befehlssatz entworfen haben. Man könnte meinen, daß sie nicht mal den
> 8051 kannten.

Den gleichen Eindruck habe ich auch seit dem Umstieg an die AVRs. Im 
Gegensatz zum 51er ist der Befehlssatz aus Sicht eines 
Assemblerprogrammierers einfach Schrott.

Thomas

Autor: spess53 (Gast)
Datum:
Angehängte Dateien:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Hi

>Den gleichen Eindruck habe ich auch seit dem Umstieg an die AVRs. Im
>Gegensatz zum 51er ist der Befehlssatz aus Sicht eines
>Assemblerprogrammierers einfach Schrott.

Dann macht doch einen eigenen Thread dazu auf. Dort könnt ihr euren 
Frust in aller Ruhe ausdiskutieren.

@Quantum (Gast)

Im Anhang ein kurzer Test. Funktioniert problemlos.

MfG Spess

Autor: Quantum (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Mark L. schrieb:
> Quantum schrieb:
>> Darf ich erfahren wie du das herausgefunden hast, bzw wo das steht. Was
>> hat dieses Register mit den I/O Registern zu tun ? Oder hab ich das mit
>> dem out falsch verstanden ?
>
> Das out geht für alle Register bis 0x5F Die Adresse ist bei out aber um
> 0x20 versetzt. Alles was mit out erreichbar ist, steht auch mit der
> out-Adresse in der *def.inc, daher führt sts zum Beschreiben eines
> falschen IO-Registers. Ist manchmal etwas nervig bei den Atmels, gibt
> immer wieder Unterschiede. Steht einmal in der *def.inc und im
> Datenblatt die IO-Register mit den doppelten Adressen.
>
> In kurzen Programmen sind das und die sbr/sbrs-Geschichte so
> Fehlerquellen, die man einfach nicht direkt sieht und die die
> Fehlersuche selbst in einem 20-Zeiler zur nervenaufreibenden Sache
> werden lassen.
>
> Mark

Danke, hab´s nun verstanden. In der *def.inc ist das sehr übersichtlich 
dargestellt.

spess53 schrieb:
> Hi
>
>>Den gleichen Eindruck habe ich auch seit dem Umstieg an die AVRs. Im
>>Gegensatz zum 51er ist der Befehlssatz aus Sicht eines
>>Assemblerprogrammierers einfach Schrott.
>
> Dann macht doch einen eigenen Thread dazu auf. Dort könnt ihr euren
> Frust in aller Ruhe ausdiskutieren.
>
> @Quantum (Gast)
>
> Im Anhang ein kurzer Test. Funktioniert problemlos.
>
> MfG Spess

Es funktioniert nun auch, lag an der externen Beschaltung.
Ich bedanke mich bei allen Problemlösern. Habt mir wirklich sehr 
geholfen.

Grüße

Autor: Sascha Weber (sascha-w)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
man kann sich das Leben mit ein paar Macros einfacher machen z.B. für 
out
.macro  out_
.if (@0 <= 63)
  out  @0,@1
.else
  sts  @0,@1
.endif
.endmacro
im Program dann einfach immer 'out_' schreiben, das Macro beutzt dann 
den richtigen Befehl.

Sascha

Autor: Jobst M. (jobstens-de)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Ach was, die Macros werden erst nach der Adressumsetzung aufgerufen?
So genau habe ich mich damit noch nie befasst ...

Danke für den Hinweis.
Ich glaube, ich werde mal einen kleinen Pre-Compiler schreiben und 
diesen dann hier veröffentlichen ...

MOV, ich komme :-D


Gruß

Jobst

Autor: spess53 (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Hi

>Ich glaube, ich werde mal einen kleinen Pre-Compiler schreiben und
>diesen dann hier veröffentlichen ...

Meine Codegenerierung macht das schon seit Jahren richtig.

MfG Spess

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel




Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder GIF-Format hochladen.
Siehe Bildformate
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken erkennst du die Nutzungsbedingungen an.

webmaster@mikrocontroller.netImpressumNutzungsbedingungenWerbung auf Mikrocontroller.net