mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ASM Befehl gesucht


Autor: blutengel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi!

habe folgenden Code:
AVR-Assembler-Code
ldi aus,0b11111111

rcall spi_send

spi_send:
rjmp start
carry_zero:
cbi porta,0
sbi Porta, 2
cbi porta,2

start:
inc zaehler
BRCC carry_zero
sbi Porta,0
sbi Porta, 2
cbi porta,2
rjmp start
ret

Und zwar will ich damit ein 8BIT
Register seriell ausgeben(SPI Versuch)die Timings werden noch nicht 
stimmen.Mit Rotieren über Carry gebe ich das Register Bit für Bit 
aus.Bei der Einzelschritt Simulation ist mir aufgefallen das nach dem 8 
Bit das Carry 0 wird und nach einem weiteren Durchgang alles von vorne 
anfängt. Wie bekomme ich es hin das ch nach genau 8 Bit´s (Durchläufen) 
aus der Schleife raus springe. Ich hatte die Idee ein Weiteres Register 
mit einer 8 zu laden und dies mit meiner Variable zaehler zu vergleichrn 
und sobald es gleich ist zu springen. Mit welchem Befehl kann ich das 
machen oder gibt es eine andere Möglichkeit


MFG

blutengel

Autor: blutengel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry falscher Code es fehlte was
AVR-Assembler-Code
ldi aus,0b11111111

rcall spi_send

spi_send:
rjmp start
carry_zero:
cbi porta,0
sbi Porta, 2
cbi porta,2

start:
ror r17;Rotieren Links über Carry
inc zaehler
BRCC carry_zero
sbi Porta,0
sbi Porta, 2
cbi porta,2
rjmp start
ret

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
blutengel schrieb:

> aus der Schleife raus springe. Ich hatte die Idee ein Weiteres Register
> mit einer 8 zu laden und dies mit meiner Variable zaehler zu vergleichrn
> und sobald es gleich ist zu springen.

Ziemlich genau so wird es im AVR-Tutorial gemacht. NUr wird dort ein 
Register mit 8 geladen, nach jedem Schleifendurchlauf das Register um 1 
runtergezählt und wenn dann das Ergebnis 0 ist, dann sind 8 Durchläufe 
vorbei.

http://www.mikrocontroller.net/articles/AVR-Tutori...

Autor: blutengel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke hat schon gut weiter geholfen:

Habe es jetzt mal so gemacht:
AVR-Assembler-Code
.include"m32def.inc"

;SPIOUT Porta.0  (SI
;SPIIN  Porta.1  (A0)
;CLK    Porta.2  (SCL)
;CS    Porta.3  (CS1B)
;
;


.def temp = r16
.def aus = r17
.def zaehler = r18


 
         ldi temp, HIGH(RAMEND)            ; HIGH-Byte der obersten RAM-Adresse
         out SPH, temp
         ldi temp, LOW(RAMEND)             ; LOW-Byte der obersten RAM-Adresse
         out SPL, temp

ldi r16,0xff
out ddra,r16

ldi zaehler,8

haupt:
ldi aus,0b11000011

rcall spi_send

spi_send:
rjmp start
carry_zero:
cbi porta,0
sbi Porta, 2
cbi porta,2

start:
BReq end
ror r17;Rotieren Links über Carry

dec zaehler

BRCC carry_zero
sbi Porta,0
sbi Porta, 2
cbi porta,2
rjmp start
ret


end:
rjmp end


Ist jetzt nur ein Test um ein Register NUR EIN MAL auszugeben.Gibt es da 
noch was zu verbesser oder ist es so OK?

MFG

blutengel

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Für meinen Geschmack wird da zuviel hin und her gesprungen

Bei jedem BREQ oder BRNE oder anderem Sprung der auf dem Zustand von 
Flags basiert, solltest du dich unbedingt immer Fragen: Wenn eine 
Funktion betreten wird, wer garantiert man dann den Zustand der Flags

Wenn aus deinem (späteren) Programm heraus spi_send angesprungen wird, 
dann ist die Abarbeitung

  Aufruf von spi_send

  spi_send:
     rjmp start

ok weiter bei start

  start:
    BReq end

Ooops. Du selbst hast das Zero-Flag nie gelöscht. Wenn es der Aufrufer 
nicht tut und zufällig zuletzt ein 0-Ergebnis ausgerechnet hat, dann 
gehts hier sofort wieder aus der Funktion raus.

Je weniger Dinge beim Aufruf einer Funktion zu beachten sind, umso 
besser. Du willst einem Aufrufer nicht die Umsicht aufbürden, das 
Zero-Flag löschen zu müssen ehe er die Funktion aufruft. Das ist ein 
vermeidbarer Fehler.

zaehler wird ebenfalls innerhalb der Funktion nicht zuverlässig auf 8 
gesetzt. Deine Funktion funktioniert nur für 1 Aufruf und dann nie 
wieder.


(Und benutze das bitte nicht als Ausrede, dass noch nicht mehr gefordert 
ist. Einen Wert ausgeben kann ich auch mittels

  cbi porta,0
  sbi Porta, 2
  cbi porta,2

  cbi porta,0
  sbi Porta, 2
  cbi porta,2

  cbi porta,0
  sbi Porta, 2
  cbi porta,2

  cbi porta,0
  sbi Porta, 2
  cbi porta,2

  cbi porta,0
  sbi Porta, 2
  cbi porta,2

  cbi porta,0
  sbi Porta, 2
  cbi porta,2

  cbi porta,0
  sbi Porta, 2
  cbi porta,2

  cbi porta,0
  sbi Porta, 2
  cbi porta,2


das würde auch das gewünschte leisten und durch Austausch von ein paar 
cbi durch sbi kann ich das anpassen. Also dieses Argument gilt nicht. 
Programmieren fängt dort an, wo eine Funktion zuverlässig und ohne 
Vorbedingungen das Richtige tut. Und zwar wieder und immer wieder.

Autor: blutengel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mir ist erstmal wichtig das es vom Prinzip her richtig ist. Das ich 
Zähler Flags und sonstiges vor dem aufruf säuber bzw. rücksetzen muss 
ist mir klar.Meine Frage ist jetzt ob ich nach dem Prinzip Daten über 
SPI senden kann?

MFG

blutengel

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Vielleicht hilft dir das weiter:
spi_out:                push r16
                        push r18
                        ldi r16,8
spi_out10:              cbi lcdato,lc_dat
                        cbi lcdato,lc_clk
                        sbrc r18,7
                        sbi lcdato,lc_dat
                        lsl r18
                        nop
                        sbi lcdato,lc_clk
                        nop
                        dec r16
                        brne spi_out10
                        cbi lcdato,lc_clk
                        pop r18
                        pop r16
                        ret

Datenbyte wird in r18 übergeben. Port und Pins sind mit lcdato, lc_dat 
und
lc_clk frei wählbar.

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
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
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 bestätigst du, die Nutzungsbedingungen anzuerkennen.