Forum: Mikrocontroller und Digitale Elektronik alle SFR auslesen, wie?


von Dirk (Gast)


Lesenswert?

Hallo!

Ich habe folgendes Problem, ich soll eine Monitorprogramm schreiben.
Dafür muss ich die SFR auslesen können. Das soll durch Eingabe der
SFR-Adresse erfolgen. Irgendwie bekomme ich da nicht hin.
Hat jemand eine Idee? Assembler oder besser in C.

von Michael (Gast)


Lesenswert?

Häh?
Das steht doch in jedem Datenblatt.
Nimm Dir also das von Deinem Controller und los geht es.

Wer zwingt Dich denn, so ein Programm zu schreiben?

von Dirk (Gast)


Lesenswert?

Genau das steht nicht so nicht drin.
Klar kann ich in Assembler folgendes machen:

mov SBUF, SP
oder
mov SBUF, 0x81

Nur wenn die Sache variabel werden soll wird schwierig. Also angenommen
ich will die SFR's von 0x81h bis 0xFEh ausgeben. Wie realisiert man
das?

von Michael (Gast)


Lesenswert?

Eine Schleife und dann jeweils um eins erhöhen?
Das Problem sehe ich immer noch nicht.

von Mathias (Gast)


Lesenswert?

ganz einfach: du schreibst ein programm bei dem du die start und die
endadresse eingeben musst.

dann initialisierst du einen byte pointer mit der startadresse und
lässt in einer schleife solange alle werte ausgeben bis der pointer auf
die endadresse zeigt (mit auto increment natürlich )

mfg, Mathias

von Peter Dannegger (Gast)


Lesenswert?

Die SFRs lassen sich nur direkt adressieren, d.h. Du brauchst für jede
Adresse einen eigenen Befehl, z.B.:
1
cjne r0, #80h, m80
2
mov a, 80h
3
m81:
4
cjne r0, #81h, m82
5
mov a, 81h
6
m82:
7
...
8
cjne r0, 0FFh, mend
9
mov a, 0FFh
10
mend:


Peter

von Niels H. (monarch77)


Lesenswert?

Das sich jedes SFR nur über direkte Adressierung auslesen lässt, wage
ich zu bezweifeln, zumal hier noch kein Ton über die verwendete
Plattform gefallen ist.

Vieleicht nochn kleiner Tipp:

Es gibt SFRs, die nur WriteOnly sind bzw bei Lesezugriffe andere Werte
ausgeben.

von Dirk (Gast)


Lesenswert?

Also das Ganze muss auf einem MSC1211 von TI laufen (8051 kompatibler
Kern).
Meine neue Idee wäre eine Tabelle:
   .
   .
 mov DPTR, #sfread_tab
 movc A, @A+DPTR
   .
   .
   .
.macro sfread    ; Erg. in R0
    mov A,@1
  ret
  .endmacro

sfread_tab:    ;(>=128)
  sfread $80  ; P0
  sfread $81  ; SP
  sfread $82  ; DPL
  sfread $83  ; DPH
        .
        .
        .

Also zuerst einmal Akku erhöhen und abschließend Akku über UART senden.
Habee ich nur noch nicht ausprobiert.

von Peter Dannegger (Gast)


Lesenswert?

@Niels

"Das sich jedes SFR nur über direkte Adressierung auslesen lässt,
wage
ich zu bezweifeln, zumal hier noch kein Ton über die verwendete
Plattform gefallen ist."


Nun, beim 8051 sind Deine Zweifel falsch, sonst hätte ich es ja nicht
geschrieben.

Und "SFR", "SBUF", "SP" legen einen 8051 nahe.


Daher geht es eben nicht so wie Dirk schreibt bzw. er liest damit immer
den indirekten SRAM.


Peter

von Thomas K. (thkais)


Lesenswert?

Von hinten durch die Brust ins Auge gehts doch. Voraussetzung: Ein RAM,
der sowohl als Daten- als auch als Codespeicher geschaltet ist (mache
ich der Bequemlichkeit halber eigentlich immer).
Dann kann man den entsprechenden Programmcode ins RAM schreiben und
entsprechend verändern. Ist zwar kein "sauberer" Programmierstil,
geht aber.

von Dirk (Gast)


Lesenswert?

Also ich habe erst einmal folgende Lösung in Assembler gefunden:

MAIN_PROG:

    mov R0, #0x00
Erh:
    mov A, R0
    mov DPTR, #Tabelle
    LCALL SFRREAD
    mov SBUF, A
    inc R0
    inc R0
    inc R0
    sjmp Erh
    jmp MAIN_PROG

SFRREAD:
    jmp @A+DPTR


  .segment tabelle, org $9A

  .macro ReadSFR
     mov A, @1
     ret
  .endmacro

Tabelle:
      ReadSFR 0x80    //Port 0
      ReadSFR 0x81    //SP
      ReadSFR 0x82
      ReadSFR 0x83
      ReadSFR 0x84


Vielleicht finde ich noch eine  kürzere Variante, die auch unter C zu
realisieren ist.

von Peter D. (peda)


Lesenswert?

@Dirk

Daher geht es eben nicht so wie Dirk schreibt bzw. er liest damit
immer
den indirekten SRAM.


@Thomas

also ehe ich da noch nen Haufen Hardware ranpappe, schreibe ich doch
lieber ein paar Zeilen Code. Mit einem Repeat-Macro ist das ruckzuck
erledigt.
Wem die 5 Byte pro SFR zuviel sind, man kanns auch auf 3 Byte ("mov a,
sfr" + "ret") reduzieren und indiziert anspringen.


Peter

von Peter D. (peda)


Lesenswert?

@Dirk,

jetzt sehe ich es erst, Du machst es schon so.

Du hast bloß nen völlig anderen Assembler, deshalb habe ich es nicht
erkannt.

Ein Fehler ist aber doch noch drin:

Wenn Du alle 128 SFRs lesen willst, dann ergibt 3* "inc R0" einen
Überlauf. Dann mußt Du noch DPH erhöhen.



Peter

von Thomas (Gast)


Lesenswert?

Es gibt nur die Möglichkeit beim 8051 für jedes SFR einen Befehl zu
schreiben. Der Ansatz von Dirk ist bestens. Nur noch die 16 Bit
Korrektur, dann sollte das tun. @Thomas meinem Namensvetter: Die
"von-Neumann" Umbauerei von 8051 geht nur bei externem
Programmspeicher. Intern gibt das ein Problem und bei einem
"universellen" Monitor sollte das auch dann funktionieren.

Gruß THomas

von Peter D. (peda)


Lesenswert?

So, hier mal, wie ich das mit dem Keil-Assembler machen würde:
1
; input: a = index (0 = sfr 80h ... 7fh = sfr 0FFh)
2
; output: r7
3
getsfr:
4
        mov     dptr, #sfrtab
5
        mov     b, #3
6
        mul     ab
7
        jnb     ov, _gsf1       ; > 255 ?
8
        inc     dph             ; + 256
9
_gsf1:  jmp     @a+dptr
10
11
sfrtab:
12
        sfrnum  set 80h
13
        rept    128
14
        mov     r7, sfrnum
15
        ret
16
        sfrnum  set sfrnum + 1
17
        endm
18
19
end

Je nach Derivat sind natürlich nicht alle SFRs belegt, dann kommt
meistens 0 oder FFh zurück.

"mov a, acc" ist keine gültige Instruktion, deshalb habe ich R7
genommen.


Peter

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.