Toon posts:

[ASM][8052] Data schrijven intern geheugen

Pagina: 1
Acties:

Verwijderd

Topicstarter
Platform:
Atmel 89c52 (8052 familie)

Bedoeling:
De bedoeling is om een tabel te laden met default waarden (die staan in de code geladen). Via de UART (RS232) wil ik dus karakters inlezen en de waarden in de tabel overschrijven.

Maar het overschrijven lukt niet. De karakters worden op de "juiste" locatie opgeslagen.


Met een simulator heb ik het probleem gevonden, maar vind geen oplossing :(

Het adres van #tabel (0xAE) staat in DPTR en R1. Maar zodra ik iets wil schrijven naar de locatie aangegeven in R1 (adres in R1), wordt de waarde niet geschreven in het code geheugen, maar in RAM geheugen (op adres 0xAE)

Reden: Ik wil dus terugschrijven naar het code geheugen 8)7 (64K) wat dus onmogelijk is. Mijn tabel zou in het RAM geheugen moeten staan en niet in het code geheugen.

Vraag:

Hoe kan ik de tabel laten starten in het RAM geheugen? hoe zoiets declareren?

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
start1:     .....   
        mov dptr,#tabel ;adres van TABEL in dptr zetten
        mov R1,#tabel

lus:        

            JNB RI,$
        MOV A,SBUF         
        MOV @R1,A    ;Data A verzenden naar Adres op R1
        MOV R5,A
        clr RI
        .....   ;
                                SJMP        LUS

tabel:
    db 00000000b     
    db 00000000b

    db 00000000b
    db 00000000b

    db 11111001b
    db 11111111b

  • D4Skunk
  • Registratie: Juni 2003
  • Laatst online: 20-10-2025

D4Skunk

Kind of Blue

Ik ken niks van assembly voor dit type processor, maar in 80x86 had je een .org statement en .data etc...

FF googlen leverde me het volgende op :

uit http://web51.hw-server.com/x51_mem.html :

The internal data memory is partially overlapped by the Special Function Registers (SFR). The first micros of the MCS-51 series had only 128 bytes of internal data memory, so the SFR's were placed into the remaining 128 bytes addressable by the 8-bit address. For example, the data register of port 0 is located at address 0x80. Unlike the internal data memory, SFR's cannot be addressed indirectly. That is, it is not possible to access them while having the address in register R0 (mov a,@r0)(mov @r0,a) or R1 (mov a,@r1)(mov @r1,a); the only allowed method is direct access (e.g. mov a,0x80)(mov a,p0)(anl p0,#0b10101010). The entire internal memory area is accessible using indirect addressing only. Looking for errors caused by direct addressing of the internal memory in its upper range is a common nightmare of many programmers. Unfortunately, the assembler can't provide many warnings.

Er staat denk ik nog meer interssants in de link

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 22-05 16:53
ik denk dat je variabele in flash staat ( gedeclareerd als const ? ), als je daar naar toe wilt schrijven moet je flash routines gebruiken. ( Overigens gaat dit per bank van 128k )

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • Icelus
  • Registratie: Januari 2004
  • Niet online
De 8051 maakt (standaard) gebruik van een Harvard geheugenstructuur. Hierbij zijn code en data geheugen gescheiden.
Het code geheugen is normaal ook niet te beschijven.
Het adres van #tabel (0xAE) staat in DPTR en R1. Maar zodra ik iets wil schrijven naar de locatie aangegeven in R1 (adres in R1), wordt de waarde niet geschreven in het code geheugen, maar in RAM geheugen (op adres 0xAE)
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
start1:        .....    
        mov    dptr,#tabel    ;adres van TABEL in dptr zetten
        mov    R1,#tabel

tabel:
    db 00000000b     
    db 00000000b

    db 00000000b
    db 00000000b

    db 11111001b
    db 11111111b
tabel is een label in het code geheugen. Zowel de waarde van de label als DPTR zijn beide 16-bits breed zodat dit geen probleem oplevert. R1 is echter een 8-bits breed register zodat de waarde (adres) van de label tabel nooit in R1 past.

Je kunt het beste ruimte in het (intern) data geheugen voor de tabel reserven.
code:
1
2
3
        dseg
        org    50h
tabel:  ds     32
Bovenstaande code 'reserveert' ruimte voor de tabel met een grootte van 32 bytes.
De label tabel is gelijk aan 50h. (Directives zijn uiteraard afhankelijk van de gebruikte assembler).
code:
1
2
mov   r1,#tabel
mov   @r1,a
In regel 1 is r1 gelijk aan 50h; in de tweede regel wordt de inhoud van register a naar het geheugenadres waar r1 naar wijst geschreven (50h dus).

Wil je een tabel met default waarden gebruiken dan dien je deze van code naar data geheugen te kopiëren aan het begin van je programma (of routine?).
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
        dseg
        org     50h
tabel:  ds      32


        cseg
        org     100h

        mov     dptr, #tabel_default  ; DPTR = begin default tabel
        mov     r1, #tabel            ; R1 = begin tabel in data geheugen
        mov     r0, #32               ; 32 bytes kopiëren

kopieer_default:
        clr     a                     ; A = 0
        movc    a, @dptr+a            ; Laadt A uit code tabel
        mov     @r1, a                ; Schrijf A naar data geheugen
        inc     r1                    ; Verhoog R1
        inc     dptr                  ; Verhoog DPTR
        dec     r0
        cjne    r0, #0, kopieer_default

tabel_default:
        db 00000000b     
        db 00000000b

        db 00000000b
        db 00000000b

        db 11111001b
        db 11111111b

Let ook op de stack pointer. Deze loopt bij de 8051 naar hogere adressen toe.
Plaats daarom de stack pointer na de variabelen in het data geheugen:
code:
1
2
3
4
5
6
7
8
9
10
11
12
        dseg
        org    30h
tabel:  ds     32
var_a:  db     1
var_b:  ds     8
sp_init:

[...]

        cseg
        org     100h
        mov     sp, #sp_init

Developer Accused Of Unreadable Code Refuses To Comment


Verwijderd

Topicstarter
Bedankt voor je reply :) Alles werkt zoals het zou moeten zijn :)