Assembler Problem mit Schieberegister für Ein- und Ausgänge

Daniel Baumann

Neues Mitglied
03. Mai 2011
24
0
0
34
Dortmund, Germany, Germany
Sprachen
  1. Assembler
Hallo liebes Forum,

da ich mir einen Aquariencontroller bauen möchte und ich diesen auch schon aufgebaut habe in der ersten Version bin ich nun dabei diesen zu testen ob die Hardware funktioniert. Der Uart funktioniert so weit nur die Schieberegister 74hc165 funktionieren nicht die 595 funktionieren jetzt wollte ich die sechs zustände von Tastern einlesen und diese über die 595 ausgeben. Schon beim Assemblieren die fehlermeldung "Invalid register" kommt. Ich hab jetzt schon geschlagene 2 tage danach gesucht was es sein könnte ich finde es nicht. Ich muss zugeben es sind zwei Codeschnippsel die ich einfach nur zusammen kopiert habe um halt zugucken ob die Hardware funktioniert. Ich hoffe das ist nicht schlimm für euch im Anhang findet ihr denn code.


Mit freundlichen grüßen

Daniel
 

Anhänge

  • test.txt
    5,7 KB · Aufrufe: 11
Hallo Daniel,

alles in Assembler. Da will es aber einer wissen ;)
Der Uart funktioniert so weit nur die Schieberegister 74hc165 funktionieren nicht die 595 funktionieren jetzt wollte ich die sechs zustände von Tastern einlesen und diese über die 595 ausgeben.
Also UART funktioniert.
74165 läuft nicht.
74595 funktionieren anscheinend ?

Schon beim Assemblieren die fehlermeldung "Invalid register" kommt. Ich hab jetzt schon geschlagene 2 tage danach gesucht was es sein könnte ich finde es nicht.
Die Registerdefinitionen sind in der Include-Datei verborgen (.include "m32def.inc").
Dort steht, welche Registeradresse mit welchem Registernamen benannt werden soll.
Wenn da ein Name nicht drinnsteht, den du aber verwendest, dann motzt er. An der
Datei solltest du aber nichts drehen, weil die wohl stimmen werden. Hier wäre ne
genauere Angabe interessant wo er genau motzt (Zeilennummer, usw)

Ich muss zugeben es sind zwei Codeschnippsel die ich einfach nur zusammen kopiert habe um halt zugucken ob die Hardware funktioniert.
Da wirst du wohl einen Codeschnipsel für nen anderen Prozessor erwischt haben. Die
haben gemeinerweise manchmal ein wenig unterschiedliche Registernamen :p :rolleyes:

Ich hoffe das ist nicht schlimm für euch im Anhang findet ihr denn code.
Ich pack den Code mal hier direkt rein. Dann geht die Fehlersuche einfacher ...
Code:
.include "m32def.inc"

.def temp1    = r16
.def temp2    = r17
.def temp3    = r18


; Die Definitionen müssen an den jeweiligen AVR angepasst werden

.equ F_CPU = 4000000
.equ BAUD = 9600 
.equ SCHIEBE_DDR  = DDRB
.equ SCHIEBE_PORT = PORTB
.equ RCK          = PB4     ; SS
.equ SCK          = PB7     ; SCK
.equ SIN          = PB5     ; MOSI
.equ PL           = PB3
.equ CLK          = PB7     ; SCK
.equ DIN          = PB6     ; MISO
;Berechnungen

.equ UBRR_VAL   = ((F_CPU+BAUD*8)/(BAUD*16)-1)
.equ BAUD_REAL  = (F_CPU/(16*(UBRR_VAL+1)))
.equ BAUD_ERROR = ((BAUD_REAL*1000)/BAUD-1000)

.if ((BAUD_ERROR>10) || (BAUD_ERROR<-10))       ; max. +/-10 Promille Fehler
  .error "Systematischer Fehler der Baudrate grösser 1 Prozent und damit zu hoch!"
.endif

.dseg
.org 0x60
Daten:      .byte 2             ; Speicherplatz für Eingangsdaten
 
;-----------------------------------------------------------------------------
;
; Programmsegment im FLASH
;
;-----------------------------------------------------------------------------
.cseg
    ldi     temp1, LOW(RAMEND)  ; Stackpointer initialisieren
    out     SPL, temp1
    ldi     temp1, HIGH(RAMEND)
    out     SPH, temp1
 
; CLK und PL als Ausgänge schalten
 
    ldi     temp1,(1<<CLK) | (1<<PL)
    out     SCHIEBE_DDR,temp1   

; SCK, MOSI, SS als Ausgänge schalten
;
    in    temp1, SCHIEBE_DDR
    ori   temp1, (1<<SIN) | (1<<SCK) | (1<<RCK) 
    out   SCHIEBE_DDR,temp1     

receive_loop:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;EINGABE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; SPI Modul konfigurieren
;
    ldi     temp1, 0b01011000
    out     SPCR, temp1         ; keine Interrupts, MSB first, Master
                                ; CPOL = 1, CPHA =0
                                ; SCK Takt = 1/2 XTAL
    ldi     temp1,1
    out     SPSR,temp1          ; double speed aktivieren
    out     SPDR,temp1          ; Dummy Daten, um SPIF zu setzen

;-----------------------------------------------------------------------------
; Zwei Bytes einlesen
 
    ldi     ZL,low(Daten)
    ldi     ZH,high(Daten)
    ldi     temp1,2
    rcall   schiebe_eingang



;-----------------------------------------------------------------------------
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;Verarbeitung;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

  

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;Ausgabe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    ldi   temp1, (1<<SPE) | (1<<MSTR)
    out   SPCR, temp1           ; keine Interrupts, MSB first, Master
                                ; CPOL = 0, CPHA =0
                                ; SCK Takt = 1/2 XTAL
    ldi   temp1, (1<<SPI2X)
    out   SPSR, temp1           ; double speed aktivieren
    out   SPDR, temp1           ; Dummy Daten, um SPIF zu setzen
    ldi   temp1, ZL
    rcall schiebe
    rcall schiebeout
	rjmp  receive_loop

;
; Die Daten im Schieberegister in das Ausgaberegister übernehmen
;
; Dazu am RCK Eingang am Schieberegister einen 0-1-0 Puls erzeugen
;
SchiebeOut:
    sbis  SPSR, SPIF            ; prüfe ob eine alte Übertragung beendet ist
    rjmp  SchiebeOut
    sbi   SCHIEBE_PORT, RCK
    cbi   SCHIEBE_PORT, RCK
    ret
 
;-----------------------------------------------------------------------------
;
; 8 Bits aus temp1 an das Schieberegister ausgeben
;
Schiebe:
    sbis    SPSR, SPIF      ; prüfe ob eine alte Übertragung beendet ist
    rjmp    Schiebe
    out     SPDR, Ausgang     ; Daten ins SPI Modul schreiben, Übertragung beginnt automatisch
    ret

int_rxc:
    

Ruck:    
    rjmp    receive_loop

;-----------------------------------------------------------------------------
;
; N Bytes seriell einlesen
;
; temp1 : N, Anzahl der Bytes
; Z     : Zeiger auf einen Datenbereich im SRAM
;-----------------------------------------------------------------------------
schiebe_eingang:
    push    temp2               ; Register sichern
 
    ; CLK ist im Ruhezustand schon auf HIGH, CPOL=1
 
    cbi     schiebe_port, pl    ; Daten parallel laden
    sbi     schiebe_port, pl
 
schiebe_eingang_1:
    sbis    SPSR,7              ; prüfe ob eine alte Übertragung beendet ist
    rjmp    schiebe_eingang_1
 
schiebe_eingang_byte_schleife:
    out     SPDR,temp1          ; beliebige Daten ins SPI Modul schreiben
                                ; um die Übertragung zu starten
schiebe_eingang_2:
    sbis    SPSR,7              ; auf das Ende der Übertragung warten
    rjmp    schiebe_eingang_2
 
    in      temp2, spdr         ; Daten lesen
    st      z+,temp2            ; Datenbyte speichern
    dec     temp1               ; Anzahl Bytes um eins verringern
    brne    schiebe_eingang_byte_schleife   ; wenn noch mehr Bytes zu lesen sind
 
    pop     temp2
    ret
Also erstmal die genauen Stellen angeben wo er motzt. Evtl findest du es durch die
kleinen Infos jetzt schon selber. Nimm dir mal parallel dazu das Datenblatt vom Mega32
vor. Da sind hinten alle Registernamen drin. Die mußt du in deinen Codeschnipseln evtl
etwas anpassen damit sie mit dem Prozessor übereinstimmen.

So ... und nun endlich ... :sleep: :vollkommenauf:

Gruß
Dino
 
Hallo Dino,

danke für die schnelle antwort. Also er meckert an der stelle von ich Low byte des Z-Pointers in temp 1 laden will also LDI temp1,ZL. Also ich hab jetzt mal nachgeschaut und finde vom Mega8 wo die Codeschnippseln herkommen zum Mega32 keine großen register unterschiede in dem Code. Für mehr Hilfe oder für ne Erklärung wieso ich denn Z-pointer nicht in Temp1 laden kann wäre ich sehr dankbar.


Mit freundlichen grüßen

Daniel
 
Hallo Daniel,


da es sich sowohl bei dem Z-Pointer (zl ist r30, zh ist r31), wie auch bei temp1 (ist r16) um Register handelt, musst du hier "mov temp1, zl" verwenden. "ldi" erwartet eine Konstante, die in temp1 kopiert werden soll, also zum Besipiel "ldi temp1, 123".

Gruß,
Dirk
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)