Forum: Mikrocontroller und Digitale Elektronik Pic Assembler Pseudo-Befehl DA?


von M. J. (manfred-64)


Lesenswert?

Hallo,

ich steh Heut mal wieder völlig auf'm Schlauch,
peils nicht mit dem Pseudo-Befehl DA

Sprut erklärt das so:

DA   Ablage von 14-Bit-Zahlen/Text im Programmspeicher
Syntax:   DA <string>
DA <zahlenwert>
Beschreibung   Der DA-Befehl erzeugt 14-Bit Zahlen, und fügt sie an der 
aktuellen Stelle im Programmcode ein. Er ist vor allem zur Speicherung 
von Text gedacht. Wird der DA-Befehl von einem String gefolgt, so werden 
immer 2 Zeichen des Strings in den 7-Bit ASCII-Code gewandelt, und zu 
einer 14-Bit-Zahl zusammengefasst. Wird der DA-Befehl dagegen von einem 
Zahlenwert gefolgt, so wird dieser 14-bittig im Programmspeicher 
abgelegt. Was die Originalzahl größer als 14 Bit, so wird sie 
abgeschnitten.

Beispiel:
DA  "abcdef"  ; erzeugter Code: 0x30E2 0x31E4 0x32E6 0x3380

Kann das Beispiel schon mal nicht nachvollziehen :´(
sehe keinen Zusammenhang mit dem ASCII-Code ???

Mir ist auch nicht klar wie ich dann damit im Programm arbeite bzw. wie 
bekomme ich diese Werte ins W-Register

Kann das einer mal für Dummys erklären Bitte :)


mfg
Manfred

von (prx) A. K. (prx)


Lesenswert?

Manfred John schrieb:

> DA  "abcdef"  ; erzeugter Code: 0x30E2 0x31E4 0x32E6 0x3380
1
0x30E2 = 0b11000011100010
2
           1100001         = 0x61 = a
3
                  1100010  = 0x62 = b

von (prx) A. K. (prx)


Lesenswert?

Manfred John schrieb:

> Mir ist auch nicht klar wie ich dann damit im Programm arbeite bzw. wie
> bekomme ich diese Werte ins W-Register

Bei alten PIC16 konnte man nur über ein angesprungenes RETLW Daten aus 
dem ROM laden, da geht das nicht. Neuere PIC16 haben Steuerregister 
dafür.

von M. J. (manfred-64)


Lesenswert?

A. K. schrieb:
> 0x30E2 = 0b11000011100010
>            1100001         = 0x61 = a
>                   1100010  = 0x62 = b

Autsch, hat ich selber sehen müssen (na ja hab höllisch Kopfschmerzen)


A. K. schrieb:
> Bei alten PIC16 konnte man nur über ein angesprungenes RETLW Daten aus
> dem ROM laden, da geht das nicht. Neuere PIC16 haben Steuerregister
> dafür.

ka ob das mein 16F727 kann, nach welchen Steuerregistern muss ich denn 
da Ausschau halten?

EDIT:
Ich kann nichts finden mit dem das "Auslesen" beim 16F727 möglich wäre.
Leider kenn ich auch nicht die Technik mit der das bei Pic's die diese 
Möglichkeit bieten funktioniert!

von Holger W. (holgerw)


Lesenswert?

Hier mal ein Auszug aus einer Routine für den 16F mit der ich Strings 
ausgebe, Achtung, für die Routine darf der Text keine 256Byte Grenze 
überschreiten.
Vielleicht hilft es dir ja.
1
MSG:   addwf PCL ,F 
2
        dt "Testtring",0
3
4
5
; NUllterminierten String ausgeben (evtl. 256 Byte Grenze beachten !)
6
LCD_WrtTXT:   
7
  MOVLW   0
8
LCD_WrtTXT_lp:   
9
  MOVWF   LCD_TXTPTR     ; aktuelle Stringposition
10
  CALL   MSG         ; <-- hier wird das Zeichen geholt
11
  ANDLW   0x0FF          ; Ende der Nachricht wenn NULL
12
  BTFSC   STATUS, Z
13
  GOTO   LCD_WrtTXT_END             
14
  call  OutLcdDaten    ; Zeichen ausgeben
15
  MOVF   LCD_TXTPTR,W
16
  ADDLW   1             ; und das nächste Zeichen
17
  GOTO   LCD_WrtTXT_lp
18
LCD_WrtTXT_END:

Holger

von (prx) A. K. (prx)


Lesenswert?

Manfred John schrieb:

> Ich kann nichts finden mit dem das "Auslesen" beim 16F727 möglich wäre.

Beispiel: PIC16LF1904: PMDATL/H PMADRL/H.

Bei 727 geht das möglicherweise nicht in der 7/7 Variante.

von (prx) A. K. (prx)


Lesenswert?

Holger W. schrieb:

> Hier mal ein Auszug aus einer Routine für den 16F mit der ich Strings
> ausgebe, Achtung, für die Routine darf der Text keine 256Byte Grenze
> überschreiten.

Das ist allerdings die klassische Variante mit Strings in 1x8 Bit pro 14 
Bit via RETLW.

von M. J. (manfred-64)


Lesenswert?

A. K. schrieb:
> Beispiel: PIC16LF1904: PMDATL/H PMADRL/H.
>
> Bei 727 geht das möglicherweise nicht in der 7/7 Variante.

Nein der hat das leider nich muss mich ich halt mit RETLW zufrieden 
geben :)

@Holger W.
Danke fürs Beispiel, so in etwa hatte ich das vor.


Danke euch
mfg
Manfred

von John B. (johnbauer)


Lesenswert?

Manfred John schrieb:
> ka ob das mein 16F727 kann, nach welchen Steuerregistern muss ich denn
> da Ausschau halten?
>
> EDIT:
> Ich kann nichts finden mit dem das "Auslesen" beim 16F727 möglich wäre.
> Leider kenn ich auch nicht die Technik mit der das bei Pic's die diese
> Möglichkeit bieten funktioniert!

Also lt. Datenblatt kann der PIC16F727 im Betrieb seinen Flash-Speicher 
auslesen.

Kapitel 18: PROGRAM MEMORY READ

Gruß
John

von M. J. (manfred-64)


Lesenswert?

John Bauer schrieb:
> Also lt. Datenblatt kann der PIC16F727 im Betrieb seinen Flash-Speicher
> auslesen.
>
> Kapitel 18: PROGRAM MEMORY READ

Danke!
hät ich nicht mehr da nach gesucht. (ka wie so ich da nix gefunden 
hatte)

Wenn auch a biserl umständlich für ASCII und ich nich wirklich 
Platzmangel habe, werd ich's damit machen.
Immerhin sind die Daten dann schön "aufgeräumt" und ich spar mir das 
aufpassen auf die 0xFF grenzen :)

Bin mir nur noch nicht ganz klar wie ich mir die Einsprungadressen 
"merke"
Ist es möglich die oberen Bits des PC auszulesen o. den Stack um sowas 
in der Art zu realisieren:
______________________________________
Pagesel
Call LABEL1
Pagesel
Call LABEL2
.
.

LABEL2
gemerkter PC + x
loop
programm-mem auslesen
.
.

LABEL1
PC auslesen
Return
DA "abcdef",0
_____________________________________

Sind die Adressen von Labels eventuell auch noch einfacher verwerten?
oder bin ich da völlig auf dem Holzweg :-/


mfg
Manfred

von John B. (johnbauer)


Lesenswert?

Hallo Manfred,
hier ist mal ein Beispiel das ich mal für den PIC16F74 programmiert 
habe.
Die Variable "Text" muss in Bank2 oder in den Bereich, der in Bank2 
gespiegelt wird.

Gruß
John
1
;###### Macros ######
2
3
Print macro Text_Label
4
   banksel PMADRH          ; Bank 2
5
   movlw   high Text_Label ; high-Adresse von Text (Program Memory)
6
   movwf   PMADRH
7
   movlw   low Text_Lebel  ; low-Adresse von Text (Program Memory)
8
   movwf   PMADR
9
   call    LCD_Text
10
   endm
11
12
Print_P macro Displ_pos, Text_Label
13
   Set_Cu  Displ_pos
14
   banksel PMADRH          ; Bank 2
15
   movlw   high Text_Label ; high-Adresse von Text (Program Memory)
16
   movwf   PMADRH
17
   movlw   low Text_Label  ; low-Adresse von Text (Program Memory)
18
   movwf   PMADR
19
   call    LCD_Text
20
   endm
21
22
Set_Cu macro Cursor_pos    ; Cursorposition setzten (Hex-Adresse von LCD)
23
   movlw   Cursor_pos
24
   iorlw   0x80
25
   call    LCD_C
26
   endm
27
28
29
;###### Aufruf im Programm ######
30
31
   Set_Cu  0x02            ; Cursorposition setzen (Hex-Adresse von LCD)
32
   Print   Text_1          ; Text 1 ab Cursorposition ausgeben
33
   Print_P 0x16, Text2     ; Text 2 ab Position 0x16 ausgeben
34
   banksel ...             ; Print und Set_Cu ändern die Speicherbank -> danach
35
                           ; auf die, für den weiteren Programmablauf erforderliche
36
                           ; Bank, umschalten
37
38
;###### Unterprogramme ######
39
40
LCD_Text  
41
   banksel PMCON1          ; Bank 3
42
   bsf     PMCON1, RD      ; lesen starten
43
   nop
44
   nop
45
   banksel PMDATH          ; Bank 2
46
   movfw   PMDATH          ; 6 Bit von high-byte in Text
47
   movwf   Text
48
   rlf     PMDATA, W       ; Bit 7 von low-byte in Carry
49
   rlf     Text, F         ; Bit 7 in Text als Bit 0
50
   movf    Text, W
51
   btfsc   STATUS, Z       ; ist Zeichen 'Null'?
52
   goto    Text_End        ;  - ja
53
   call    LCD_D           ;  - nein: Zeichen ausgeben
54
   banksel PMDATA          ; Bank 2
55
   movfw   PMDATA          ; 2. Zeichen laden
56
   andlw   0x7F            ; nur untere 7bit
57
   btfsc   STATUS, Z       ; ist Zeichen 'Null'?
58
   goto    Text_End        ;  - ja
59
   call    LCD_D           ;  - nein: Zeichen ausgeben
60
   banksel PMADR           ; Bank 2
61
   incf    PMADR, F        ; low-Byte um 1 erhöhen (Flash-Adresse +1)
62
   btfsc   STATUS, Z       ; Überlauf?
63
   incf    PMADRH, F       ;  - ja: high-Byte um 1 erhöhen
64
   goto    LCD_Text
65
Text_End
66
   return
67
68
69
LCD_D                      ; Unterprogramm um ein Zeichen an
70
                           ; Cursorposition auszugeben (RS=1)
71
72
LCD_C                      ; Unterprogramm um einen Befehl an
73
                           ; LCD zu senden (RS=0)
74
75
76
Text_1   da   "Temperatur\x00"  ; "Temperatur"
77
Text_2   da   "\x01C\x00"       ; "°C" (Benutzer def. Zeichen "°" in Adr. 0x01 von LCD)
78
Text_3   da   "          \x00"  ; Leerzeichen um einen Bereich vom LCD zu löschen
79
80
   END                     ; directive 'end of program'

von Peter D. (peda)


Lesenswert?

John Bauer schrieb:
> Hallo Manfred,
> hier ist mal ein Beispiel das ich mal für den PIC16F74 programmiert
> habe.

Ein wirklich sehr beeindruckendes Beispiel, wie kompliziert doch die 
PIC-Programmierung in Assembler ist.

Im Gegensatz dazu sieht die gleiche Aufgabe für den 8051 erheblich 
einfacher aus:
1
;       Demo: Textausgabe aus dem Flash des 8051
2
;       ========================================
3
;
4
main:
5
        mov     dptr, #text1            ; lade Datenpointer mit Textadresse
6
        call    lcd_text                ; Aufruf Ausgabefunktion
7
8
        mov     dptr, #text2            ; lade Datenpointer mit Textadresse
9
        call    lcd_text                ; Aufruf Ausgabefunktion
10
11
        jmp     $                       ; Endlos-Schleife
12
;--------------------------------------------------------------------------
13
text1:
14
        db      'Hallo Welt'
15
        db      0                       ; 0 = Endezeichen
16
text2:
17
        db      'Text zwei'
18
        db      0                       ; 0 = Endezeichen
19
;--------------------------------------------------------------------------
20
;       UP: Ausgabe des Textes im Flash, auf den DPTR zeigt
21
;       ===================================================
22
;
23
_lcdt1:
24
        call    lcd_data                ; Ausgabe eines Bytes ans LCD
25
        inc     dptr                    ; zeige auf naechstes Byte
26
lcd_text:
27
        clr     a                       ; kein Offest
28
        movc    a, @a+dptr              ; lese Byte aus Flash
29
        jnz     _lcdt1                  ; ungleich 0 -> Anzeigen
30
        ret                             ;   gleich 0 -> return
31
;--------------------------------------------------------------------------
32
lcd_data:                               ; hier LCD Ausgabe einfuegen
33
        ret
34
;--------------------------------------------------------------------------

LCD_Text: statt 25 Instruktionen nur 6.

Nicht persönlich nehmen, aber ich bin doch schon sehr froh, daß ich 
keinen PIC programmieren muß.


Peter

von M. J. (manfred-64)


Lesenswert?

Danke John,

auf die Idee, das mit einem Macro zu lösen wäre ich glaube nicht so 
schnell gekommen.
Mir ist nur nicht klar wie "movlw   high Text_Labe" funktioniert!
movlw mit 2 Operanden?????


g
Manfred

von M. J. (manfred-64)


Lesenswert?

Peter Dannegger schrieb:
> Ein wirklich sehr beeindruckendes Beispiel, wie kompliziert doch die
> PIC-Programmierung in Assembler ist.
>
> Im Gegensatz dazu sieht die gleiche Aufgabe für den 8051 erheblich
> einfacher aus:

wayne

von John B. (johnbauer)


Lesenswert?

Manfred John schrieb:
> Mir ist nur nicht klar wie "movlw   high Text_Labe" funktioniert!
> movlw mit 2 Operanden?????
1
Text_1   da   "Temperatur\x00"
Das Label 'Text_1' beinhaltet die Adresse des ersten Zeichen des Strings 
im Flash.
1
movlw   high Text_Label
2
movlw   low Text_Lebel
Das 'high' und das 'low' sind Assembler Direktiven. Beim Kompilieren 
wird das entsprechende low- bzw. high-Byte des Labels eingesetzt.

Um Daten aus dem Flash auszulesen, muss man in PMADRH das high-Byte, und 
in PMADRL das low-Byte der zu lesenden Adresse schreiben.
(Achtung: die Registernamen der Controller sind nicht gleich. In meinem 
Code vom PIC16F74: PMADR ist beim PIC16F727: PMADRL)


Peter Dannegger schrieb:
> die  PIC-Programmierung in Assembler

Immer diese Verallgemeinerungen.

von M. J. (manfred-64)


Lesenswert?

John Bauer schrieb:
> Das 'high' und das 'low' sind Assembler Direktiven.

Die hab ich wohl etwas vernachlässigt :)
Mal schauen was ich da noch alles für interessante Möglichkeiten 
übersehen habe.


Dank und Gruß
Manfred

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.