PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : AVR schreibt R26 bei In-Befehl



teslanikola
22.03.2006, 21:33
Hallo leute,
ich hab hier eine ganz komische sache bemerkt:
wenn ich in meinem Porgramm mit In den Inhalt von Portb in ein Register ( R16 ) schreibe wird auch das R26 beschrieben ( als XH verwendet ), woran leigt das, wie kann ich das vermeiden???

hier mal der Anomaliencode:


in temp2,portd ; Lese Portd aus
lsl temp2 ; Schiebe alle Bits eins nach links


Mein gesammter Code:


;************************************************* **********************************
;* Beschaltung: *
;* *
;* PB0 >----[200R]--A-[D]--[D]--[D]--[D]--[D] Die 5 Anoden einer LED-Reihe *
;* | | | | | sind miteinander verbunden und *
;* PB1 >----[200R]--A-[D]--[D]--[D]--[D]--[D] über einen Vorwiderstand an *
;* | | | | | einen Portpin angeschlossen. *
;* PB2 >----[200R]--A-[D]--[D]--[D]--[D]--[D] Die Kathoden der LEDs einer *
;* | | | | | Spalte sind ebenfalls mit- *
;* PB3 >----[200R]--A-[D]--[D]--[D]--[D]--[D] einander verbunden und über *
;* | | | | | einen Transitor nach GND ge- *
;* PB4 >----[200R]--A-[D]--[D]--[D]--[D]--[D] schalten. *
;* | | | | | *
;* PB5 >----[200R]--A-[D]--[D]--[D]--[D]--[D] LEDs: LED Rot *
;* | | | | | Transistoren: BC547 *
;* PB6 >----[200R]--A-[D]--[D]--[D]--[D]--[D] Widerstände: 1/4W Kohleschicht *
;* | | | | | *
;* K K K K K *
;* | | | | | *
;* |/ | | | | *
;* PD0 >----[10k]----| | | | | *
;* |> | | | | *
;* | | | | | *
;* | | | | | *
;* | |/ | | | *
;* PD1 >----[10k]---------| | | | *
;* | |> | | | *
;* | | | | | *
;* | | | | | *
;* | | |/ | | *
;* | | |> | | *
;* | | | | | *
;* | | | | | *
;* | | | |/ | *
;* PD2 >----[10k]-------------------| | *
;* | | | |> | *
;* | | | | | *
;* | | | | | *
;* | | | | |/ *
;* PD3 >----[10k]------------------------| *
;* | | | | |> *
;* | | | | | *
;* | | | | | *
;* GND >---------------o----o----o----o----o *
;* *
;* *
;************************************************* **********************************

;-------[ Assembler Einstellungen ]-------------------------------------------------

;Includedatei für AT90S2313 laden
.include "2313def.inc"

;Arbeitsregister definieren

.def temp1 = r16 ; Universalregister 1
.def temp2 = r17 ; Universalregister 2
.def temp3 = r18 ; Universalregister 3


;-------[ µC Einstellungen ]--------------------------------------------------------

;Interupt Config. I

.org 0000
rjmp start
reti
reti
reti
reti
rjmp t1int

Start:


;Interupt Config II
sei ; Interuptts freigeben

ldi temp1, (1<<TOIE1) ; Timer1 Interrupt
out timsk, temp1 ; aktivieren

clr temp1 ; TCCR1 High auf 0
out tccr1a,temp1

ldi temp1,(1<<ICNC1)|(1<<CS10) ; Noiscanceler deaktiv.
out tccr1b,temp1 ; Timer1 Clock = Clock

ldi temp1,0xE8 ; Timervorgabewerte:
out tcnt1h, temp1 ; Highbyte= 0xE8
ldi temp1,0x90 ; Lowbyte = 0x90
out tcnt1l, temp1 ; Wert = 0xE890 => 500Hz Interruptfreq.

;Stack einrichten
ldi temp1,low(ramend-0x05) ; 5 Bytes für Matrixdaten (VGA) im SRAM reservien
out spl,temp1


;I/O-Ports Config.
;PortB
ser temp1 ; PortB als Ausgang def.
out ddrb, temp1

;PortD
ser temp1 ; PortD als Ausgang def.
out ddrd, temp1

;Pointerregister def.
;X-Pointer für Multiplexer
ldi xl, low(RAMEND) ; Addresse vom Ramende
ldi xh, high(RAMEND)


;Z-Pointer für ASCII-Werteauslesen
ldi zl, low(ASCII*2) ; Addresse vom Beginn der ASCII-Tabelle
ldi zh, high(ASCII*2)

ldi temp1,16 ; Wenn PB.5=1, dann PortD = 1
out portd, temp1

;-------[ Hauptprogramm Beginn ]----------------------------------------------------
Main:

ldi temp1, 0b01010101
sts (ramend-0x00),temp1
ldi temp1, 0b01010101
sts (ramend-0x01),temp1
ldi temp1, 0b01010101
sts (ramend-0x02),temp1
ldi temp1, 0b01010101
sts (ramend-0x03),temp1
ldi temp1, 0b01010101
sts (ramend-0x05),temp1

call delay

rjmp Main
;-------[ Hauptprogramm Ende ]------------------------------------------------------




;-------[ Delay-Routine (1 Sekunde) ]-----------------------------------------------
Delay:
ldi R21, $1F
WGLOOP0: ldi R22, $FD
WGLOOP1: ldi R23, $FE
WGLOOP2: dec R23
brne WGLOOP2
dec R22
brne WGLOOP1
dec R21
brne WGLOOP0
nop
nop
ret


;-------[ Multiplex-Interrupt-Routine]----------------------------------------------

t1int:

ldi temp1,0xE8 ; Timervorgabewerte:
out tcnt1h, temp1 ; Highbyte= 0xE8
ldi temp1,0x90 ; Lowbyte = 0x90
out tcnt1l, temp1 ; Wert = 0xE890 => 500Hz Interruptfreq.

LD temp1,x ; Lese ein Matrix-Byte aus SRAM ; Lese ein Matrix-Byte aus SRAM
sbiw xl,1

cpi XL,Ramend-0x05
breq noreset
ldi XH,HIGH(RAMEND)
ldi XH,LOW(RAMEND)
noreset:

in temp2,portd ; Lese Portd aus
lsl temp2 ; Schiebe alle Bits eins nach links

out portb,temp1 ; Schreibe SRAM-Daten in den PortB
out portd, temp2 ; Schreibe PortD ( Shifted nach links)

sbis portd,5 ; Schauen ob PD.5 = 1
rjmp endmulti ; Wenn PB.5=0, dann springe nach endmulti

ldi temp1,1 ; Wenn PB.5=1, dann PortD = 1
out portd, temp1

endmulti:
reti


;-------[ ACII-HEX-Tabelle und Text ]-----------------------------------------------

;ASCII-HEX-Tabelle
ASCII:

;Text
Text:
.db "Hallo, ich bin ein AVR!",0


;=======[ Programm ENDE ]================================================== =========

bax
22.03.2006, 22:12
ich vermute Dein Problem mal hier:

ldi XH,HIGH(RAMEND)
ldi XH,LOW(RAMEND)

greetz Rajko

Bernhard.Erfurt
24.03.2006, 19:03
Du arbeitest gern mit "Ramend",
das ist gefährlich,

Du solltest wenigstes 20 Byte für den STACK freilassen.
bei sehr umfangreichen Programmen vielleicht noch mehr,
der Stack wird benötigt, um Daten und auch Rücksprungadressen zu speichern.
Und nicht vergessen, der Stack zählt rückwärts.

Wenn Du den Stack-Bereich mit anderen Daten beschreibst,
macht Dein µC sehr seltsame und wunderliche Sachen.

Bernhard

teslanikola
24.03.2006, 20:01
naja also der Stack hat bei m ir die Volle SRAM-Größe -0x05 platz, das 0x05 ist ein "5Byte Sramspeicher" für einen Multipexer

Bernhard.Erfurt
24.03.2006, 20:24
...das darf nicht gemacht werden

ldi temp1, 0b01010101
sts (ramend-0x00),temp1
ldi temp1, 0b01010101
sts (ramend-0x01),temp1
ldi temp1, 0b01010101
sts (ramend-0x02),temp1
ldi temp1, 0b01010101
sts (ramend-0x03),temp1
ldi temp1, 0b01010101
sts (ramend-0x05),temp1

Der Stackspeicher wird durch diese Befehle Komplett mit falschen Daten beschrieben.

Stell Dir vor, Du schreibst mit Deiner PC-Tastatur einen Text und ein wildfremder tippt auch fleißig sinnlose Zeichen auf Deiner Tastatur.
Das Ergebnis ist nicht sehr berauschend, gel?

teslanikola
24.03.2006, 20:30
Hallo!!!!!! Wenn du dir mal den Code ansiehst wirst du feststellen das ich den STACKPOINTER erst AB RAMEND-0x05 abwärts zählen lasse, mit dem Stack gabs bisher keine Probs, weder in der Simulation noch in der Praxis. und nach dem iuch das XH in Xl ungeschrieben hab funktioniert auch alles

Bernhard.Erfurt
24.03.2006, 20:52
>STACKPOINTER erst AB RAMEND-0x05 abwärts

...grins.... so gehts natürlich auch, ist nur etwas sehr ungewöhnlich, den STACK mitten in den SRAM zu plazieren

ABER: Der Stack ist nicht richtig initialisiert

ldi temp1,low(ramend-0x05)
out spl,temp1

es fehlt:
ldi temp1,high(ramend-0x05)
out sph,temp1

Kann sogar sein, dass dadurch Daten an eine sehr ungünstige Stelle geschrieben worden sind.

Hab hier so ein paar kleine Sachen veröffentlicht:

https://www.roboternetz.de/phpBB2/viewtopic.php?t=18336

Einfach mal schauen, wie manches initialisiert wird.

Noch was, bei einem Interrupt sollten durch push und pop,
verschiedene Register und Zustände gesichert werden

teslanikola
24.03.2006, 21:53
es fehlt:
ldi temp1,high(ramend-0x05)
out sph,temp1


Hrmm das darfst du bei einem 2313 nicht machen, da der kein Highbyte hat!!!! Da kommt sowieso gleich ne Fehlermeldung vom Assembler!

izaseba
24.03.2006, 22:10
teslanikola,
wo hast Du den Mißt mit dem Verschobenen Stack her ?
Fang an richtig zu Progen, dann gibt es auch kein "Anomaliencode",
Lass den Stack da wo er hingehört....

Gruß Sebastian

teslanikola
24.03.2006, 22:31
kk aber wenn ich den SRAM auch für anderes gedöns außer Stack brauche? Soll ich von hinten anfangen, also von anfang oder was?

Bernhard.Erfurt
25.03.2006, 00:29
>kk aber wenn ich den SRAM auch für anderes gedöns außer Stack >brauche? Soll ich von hinten anfangen, also von anfang oder was?

Du hast es vielleicht selber gemerkt, dass der Assembler-Code nicht leicht zu lesen ist.
Mir stehen immer die Haare zu Berge, wenn ich meine EIGENEN älteren Assembler-Programme lese, weil ich das Fahrrad neu erfinden wollte.

Erst später merkte ich, dass man sich doch besser an gewisse Spielregeln halten sollte, damit auch andere gut mit dem Progammcode umgehen können.

Stichwort Stack, wäre günstiger, wenn er bei RAMEND seinen Platz finden würde, ist aber kein muss.

>Hrmm das darfst du bei einem 2313 nicht machen, da der kein >Highbyte hat!!!!

Danke für den Tipp, das wusste ich nicht :)

izaseba
25.03.2006, 09:21
kk aber wenn ich den SRAM auch für anderes gedöns außer Stack >brauche? Soll ich von hinten anfangen, also von anfang oder was?

Und warum nicht ?
Dazu hab ich Dir schon was geschrieben.
Aber was Du machst bleibt Dir überlassen, nur wunder Dich hinterher nicht wenn der µC sich so komisch verhält...

Gruß Seabastian

teslanikola
26.03.2006, 10:37
Naja habs ja auch schomal geschrieben, aber wenn ich den STACK verschiebe, dann funktioniert er trotzdem noch wunderbar, das problem lag eindeutig daran, das ich das Highbyte 2mal beschrieben hab, das mag der AVR wohl nicht.
Muss euch recht geben, was die lesbarkeit von ASM-Coden angeht, ich hab mir jetzt angewöhnt in ASM jede Zeile zu Kommentieren, sonst peilt man da selbst nach 24h nichts mehr.

Bernhard.Erfurt
26.03.2006, 15:21
>das ich das Highbyte 2mal beschrieben hab, das mag der AVR wohl >nicht.

welches Highbyte meinst Du?

teslanikola
27.03.2006, 09:18
Das Highbyte:
ldi XH,HIGH(RAMEND)
ldi XH,LOW(RAMEND)