logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Jak aktywować wewnętrzny RAM 2kB w ADuC842 w Keilu?

mototest 01 Wrz 2006 08:27 2517 21
REKLAMA
  • #1 2975644
    mototest
    Poziom 19  
    Posty: 440
    Ocena: 4
    Witam kolegów

    chcę stosować większą tablicę w programie, piszę w Keilu, i przy kompilacji wyskakuje błąd że przepełniona pamięć w procku, a widze że procek ma 2kB RAMU wewnętrznego oprócz standardowego 256 bajtów i jeśli mieszczę się w tych 256 bajtach to jest ok, natomiast powyżej sie nie da, jak z kolei tablicę umieszczę w XDATA gdzie niby powinien być ten dodatkowy RAM to niczego tam nie ma po odczytaniu tablicy, czyli chyba jest nie załączony, jak to zrobić ? ma ktoś doświadczenia w tym temacie ?

    znalazłem rejestr CFG842 w którym załącza się internal RAM CFG842=1, coś sie zmieniło w danych ale nie są to jeszcze właściwe dane, w Keilu również w opcjach załączyłem wewnętrzny RAM

    a może do wewnętrznego XRAMU da sie wejść tylko przez wskaźniki ??

    dzięki
    Bogdan
  • REKLAMA
  • #2 2976320
    piti___
    Poziom 23  
    Posty: 623
    Pomógł: 67
    Ocena: 9
    hej

    definiujesz zmienne tak:
    xdata volatile unsigned char TX_buffer[30]; ?

    pod DS89C4XX chodzi i nie korzystam z zadnych wskaznikow przy zmiennych w dodatkowym ramie (cala zabawa spada na keila), pamietam ze mialem jakies problemy z tym ale kombinowalem z Memory model i jakos to odpalilem (nie wiem dokladnie co i jak ;) ).
  • #3 2976484
    mototest
    Poziom 19  
    Posty: 440
    Ocena: 4
    niestety nie działa...

    mam taki kod :

    #include <ADuC842.h>
    #include <stdio.h> 
    sbit led = 0x0B4;
    int k;
    int j;
    xdata volatile unsigned char Test[]=
    {
    1,20,30,40,50,60,70,80,90,100,110,120,130,140,150,160,170,180,190,200,210,220,230,240,250	
    };
    
    void main (void)
    {
    SCON   = 0x52;
    T3FD = 0x2D;
    T3CON = 0x86;
    TCON=0x33;
    
    CFG842 = 1;// internal 2kB RAM ON
    //-=======================
    
    while (1)
    {
    for (k=0;k<33;k++)
    printf ("k=%u wsk=%d \n",k,Test[k]);
    for(j=0;j<2500;j++)led=!led;
    printf("\n");
    }
    }



    a wyniki takie :

    Cytat:
    k=0 wsk=4352
    k=1 wsk=-2560
    k=2 wsk=12288
    k=3 wsk=-26368
    k=4 wsk=-768
    k=5 wsk=-15872
    k=6 wsk=-26368
    k=7 wsk=-2816
    k=8 wsk=-26368
    k=9 wsk=8704
    k=10 wsk=22784
    k=11 wsk=0
    k=12 wsk=0
    k=13 wsk=256
    k=14 wsk=5120
    k=15 wsk=7680
    k=16 wsk=10240
    k=17 wsk=12800
    k=18 wsk=15360
    k=19 wsk=17920
    k=20 wsk=20480
    k=21 wsk=23040
    k=22 wsk=25600
    k=23 wsk=28160


    same bzdury...
  • #4 2976611
    piti___
    Poziom 23  
    Posty: 623
    Pomógł: 67
    Ocena: 9
    Sprobuj wypelnic tablice w main() ale po wlaczeniu wewnetrznego ramu i dopiero odczytaj.
  • #5 2977359
    mototest
    Poziom 19  
    Posty: 440
    Ocena: 4
    wiesz co nic nie zmieniałem, pokazywało głupoty bo printf był źle napisany, teraz jest lepiej, ale tablice mam od 0 - 24 a moje właściwe elementy wyświetla dopiero gdy k osiąga wartość 13-38 czyli wszystko jest przesunięte o 13, skąd to sie bierze ???

    jak dam tablicę do main to jest gorzej, znowu wyświetla głupoty.

    to jest obecny wynik :

    k=0 wsk=17
    k=1 wsk=246
    k=2 wsk=48
    k=3 wsk=153
    k=4 wsk=253
    k=5 wsk=194
    k=6 wsk=153
    k=7 wsk=245
    k=8 wsk=153
    k=9 wsk=34
    k=10 wsk=89
    k=11 wsk=0
    k=12 wsk=0
    k=13 wsk=1
    k=14 wsk=20
    k=15 wsk=30
    k=16 wsk=40
    k=17 wsk=50
    k=18 wsk=60
    k=19 wsk=70
    k=20 wsk=80
    k=21 wsk=90
    k=22 wsk=100
    k=23 wsk=110
    k=24 wsk=120
    k=25 wsk=130
    k=26 wsk=140
    k=27 wsk=150
    k=28 wsk=160
    k=29 wsk=170
    k=30 wsk=180
    k=31 wsk=190
    k=32 wsk=200
    k=33 wsk=210
    k=34 wsk=220
    k=35 wsk=230
    k=36 wsk=240
    k=37 wsk=250
  • REKLAMA
  • #6 2977411
    Fajfer2
    Poziom 20  
    Posty: 507
    Pomógł: 18
    Ocena: 14
    Może troszkę nie na temat, ale np. w T89C51AC2 (też ma dodatkowe 2kB
    RAM-u) jest to załączone od razu po resecie - można ew. zmniejszyć
    w nim rozmiar dodatkowego RAM-u
  • #7 2977415
    mototest
    Poziom 19  
    Posty: 440
    Ocena: 4
    zrobiłem jeszcze inny test i jakby tego było mało to są następne problemy,
    otóż dołożyłem następną tablicę którą ładuję z pętli i okazuje się że od k=25 zamiast wskazywać elementy z tablict test[] to wskazuje elementy z tes[], do tego tablica ładowana z pętli umieszcza się w XDATA bez problemu i pod właściwymi numerami tablicy ,procek widzi ją jak należy w całości, ale jakby przykrywa poprzednią tablicę

    drugi listing z dwoma tablicami :
    include# <ADuC842.h>
    #include <stdio.h> 
    sbit led = 0x0B4;
    unsigned int k;
    int j;
    
    xdata unsigned char tes[256];
    xdata unsigned char test[26]=
    {1,20,30,40,50,60,70,80,90,100,110,120,130,140,150,160,
    170,180,190,200,210,220,230,240,250};
    
    void main (void)
    {
    SCON   = 0x52;
    T3FD = 0x2D;
    T3CON = 0x86;
    TCON=0x33;
    CFG842 = 1;// internal 2kB RAM ON
    //-=======================
    for (k=0;k<255;k++) tes[k]=k+1;
    while (1)
    {
    for (k=0;k<30;k++)
    printf ("k=%u wsk=%u \n",k,(unsigned int)test[k]);
    printf("\n");
    }
    }


    Dodano po 2 [minuty]:

    tutaj RAM trzeba niestety załączać osobno dlatego że jest w obszrze XDATA gdzie się podłącza zewnętrzny RAM więc trzeba wybrać ten ,albo tamten i nie reguluje się jego wielkości

    Mam wrażenie że dane do XDATA trzeba chyba specjalnie adresować (skoro tabele sie nakładają) , ale potrzeba fachowca który ma doświadczenie w tym temacie,
  • REKLAMA
  • #8 2977709
    zumek
    Poziom 39  
    Posty: 3352
    Pomógł: 695
    Ocena: 52
    mototest napisał:
    ...Mam wrażenie że dane do XDATA trzeba chyba specjalnie adresować (skoro tabele sie nakładają) , ale potrzeba fachowca który ma doświadczenie w tym temacie,

    To masz złe wrażenie :D
    Czy korzystasz z "rozbiegówki" START_AD.A51 :?:
    Jeśli tak , to znajdź ten fragment ...
    
    ;<h> Setup Extended Data RAM
    ;
    ; <q> XRAMEN: Enable on-chip XDATA RAM
    ;     <i> When disabled, off-chip XDATA space is accessed
    XRAMEN EQU 0  ; 0 = Disable on-chip XDATA RAM
                  ; 1 = Enable  on-chip XDATA RAM
    

    ... i zrób co trzeba.
    Jeśli nie korzystasz , to najpierw włącz wewnętrzny XRAM(CFG842|=0x01) , a dopiero po tym zadeklaruj tablicę.Niestety , będzie to tablica lokalna.
    
    void main (void)
    {
    SCON   = 0x52;
    T3FD = 0x2D;
    T3CON = 0x86;
    TCON=0x33;
    CFG842 = 1;// internal 2kB RAM ON
    //-=======================
       {
       xdata volatile unsigned char Test[]=
       {
     1,20,30,40,50,60,70,80,90,100,110,120,130,140,150,160,170,180,190,200,210,220,230,240,250   
       };
       while (1)
       	{
    	for (k=0;k<33;k++)
    	printf ("k=%u wsk=%d \n",k,(int)Test[k]);
    	for(j=0;j<2500;j++)led=!led;
    	printf("\n");
    	}
       }
    }
    


    Piotrek

    PS
    Zaznaczenie opcji Use on-chip XRAM ... , coś nie chce działać :(
  • #9 2977816
    mototest
    Poziom 19  
    Posty: 440
    Ocena: 4
    w rozbiegówce Xram była wyłączona, więc załączyłem, jutro sprawdzę jak to się ma do tablicy, czy zadziałało, widze że źle robiłem CFG842=1 zamiast CFG842|=0x01

    czy nie ma możliwości w Xdata umieścić globalnej tablicy ??
    ja w zasadzie potrzebuje tablicę umieszczoną w "code" przepisać po przeliczeniu do xdata i potem z niej korzystać

    ps.

    tak jak umieściłeś tabelę wywala sytax error, tablica musi być przed poniższym :
    SCON   = 0x52;
    T3FD = 0x2D;
    T3CON = 0x86;
    TCON=0x33;
    CFG842|=0x01; 
  • Pomocny post
    #10 2977871
    zumek
    Poziom 39  
    Posty: 3352
    Pomógł: 695
    Ocena: 52
    mototest napisał:
    ...czy nie ma możliwości w Xdata umieścić globalnej tablicy ??...

    Jeśli w startupie włączysz wewnętrzny XRAM , to zmienne mogą być zarówno globalne jak i lokalne. Ba , nawet stos można tam wsadzić :D

    Piotrek

    PS
    A co do błędu kompilacji , to ... popatrz(policz) dokładnie na klamry w moim przykładzie :D
  • #11 2978048
    mototest
    Poziom 19  
    Posty: 440
    Ocena: 4
    o sorry :) rzeczywiście klamra zadziałała , jutro będę testował
    na razie dzięki
  • #12 2979291
    Fajfer2
    Poziom 20  
    Posty: 507
    Pomógł: 18
    Ocena: 14
    rozróżnianie do jakiego RAM-u ("zewnętrznego" lub wewnętrznego) jest
    przecież wykonywane za pomocą rodzajów rozkazów (MOVX) -
    dlatego obszary 0-128 RAM i 0-1023 mogą się bez kolizji pokrywać.
    (u mnie też nie da się zainicjować tego ramu własnymi wartościami - piszę w SDCC)
    Jak jest włączony obszar "zewnętrznego" RAM-u, to zmienne (niektóre)
    są ładowane porzez MOVX - tak jak by ten ram był poza uP -
    tylko nie są wysyłane na porty sygnały obsługujące tą (nieobecną przecież) pamięć.
  • #13 2979828
    mototest
    Poziom 19  
    Posty: 440
    Ocena: 4
    OK ,wszystko działa, spozób Zumka by dobry

    dzięki
  • #14 2980091
    zumek
    Poziom 39  
    Posty: 3352
    Pomógł: 695
    Ocena: 52
    Fajfer2 napisał:
    ...(u mnie też nie da się zainicjować tego ramu własnymi wartościami - piszę w SDCC)

    Da się ;)
    Nie chce mi się juz pisać , że dokumentacja, własna inwencja ... itd.
    Wkleję gotowy przykład dla SDCC i już :D
    
    //...
    #define CFG842 0xAF
    //lub sfr at 0xAF CFG842;
    
    data char iram[2]={0x01,0x02};
    xdata char xram[2]={0x10,0x20};
    
    void main()
    {
    P0=iram[0];
    P1=xram[0];
    while(1);
    }
    //ponizsza funkcja , zostanie wywolana zaraz po zainicjowaniu stosu,
    //a przed zainicjowaniem zmiennych
    //Polozenie tej funkcji w kodzie jest dowolne
    char _sdcc_external_startup()
    {
    _asm;
    orl CFG842,#0x01 //zalaczamy wewnetrzny XRAM
    _endasm;
    
    //lub CFG842|=0x01;
    
    return 0;//zwrocenie wartosci<>0,spowoduje pominiecie
    		 //inicjacji zmiennych i zerowania RAM
    }
    
    


    Piotrek
  • #15 2980661
    Fajfer2
    Poziom 20  
    Posty: 507
    Pomógł: 18
    Ocena: 14
    chodziło mi o xdata static volatile .... jak nie zerowałem w pętli,
    albo inaczej ustawiałem to zawsze pozostawały śmieci albo wartości
    z przed resetu.Może coś źle robiłem.
  • #16 2980863
    starob
    Poziom 29  
    Posty: 1088
    Pomógł: 128
    Ocena: 137
    xdata unsigned char test[26]=
    {1,20,30,40,50,60,70,80,90,100,110,120,130,140,150,160,
    170,180,190,200,210,220,230,240,250};

    deklarujesz tablice w pamięci XRAM i oczekujesz że kompilator ją za ciebie inicjuje.
    po resecie XRAM ma wartość nieokreśloną trzeba do niej coś wpisać.
    powinno być np.
    xram unsigned char test[26];
    code unsigned char test1[26]=
    {1,20,30,40,50,60,70,80,90,100,110,120,130,140,150,160,
    170,180,190,200,210,220,230,240,250};

    a pierwsza instrukcja powinna przepisać
    test1->test

    Dardzo ciekawa lektura
  • REKLAMA
  • #17 2980906
    mototest
    Poziom 19  
    Posty: 440
    Ocena: 4
    to było tylko teoretyzowanie z mojej strony, oczywiście że przepisuję z code do ramu :) nawet chyba gdzieś wcześniej o tym pisałem że chcę wpisać do xramu wyniki obliczeń na tablicy, chodziło tylko o wydedukowanie jak działa ten wewnętrzny xram
  • #18 2981033
    starob
    Poziom 29  
    Posty: 1088
    Pomógł: 128
    Ocena: 137
    to ja nic nie rozumie.
    zamieszczasz listing i wyniki działania- pytasz czemu nie działa.
    konstrukcja typu:xram unsigned char test1[26]={..} nie zadziała na żadnym kompilatorze (chyba).Zmienne w ramie trzeba inicjować na piechotę
  • #19 2981134
    mototest
    Poziom 19  
    Posty: 440
    Ocena: 4
    no już pisałem że wszystko działa, to co Zumek mi napisał zadziałało, po prostu xram był nie załączony
  • #20 2981633
    zumek
    Poziom 39  
    Posty: 3352
    Pomógł: 695
    Ocena: 52
    starob napisał:
    to ja nic nie rozumie.
    zamieszczasz listing i wyniki działania- pytasz czemu nie działa.
    konstrukcja typu:xram unsigned char test1[26]={..} nie zadziała na żadnym kompilatorze (chyba).Zmienne w ramie trzeba inicjować na piechotę

    Powiem tak: "bajki opowiadasz" :)
    Kompilator generuje kod(startup) , który robi to , co ty chcesz robić "ręcznie".I nie ważne czy to Keil, czy SDCC.Natomiast napewno tego nie robi , kompilator ... assemblera ;)
    Dowody w załączniku :D

    Piotrek
    Załączniki:
    • Text1.c (119 Bajtów) Musisz być zalogowany, aby pobrać ten załącznik.
    • text1.A51.txt (4.25 KB) Musisz być zalogowany, aby pobrać ten załącznik.
  • #21 2982316
    starob
    Poziom 29  
    Posty: 1088
    Pomógł: 128
    Ocena: 137
    faktycznie!
    Keilu decydujesz czy chcesz startup.
    Nigdy nie dołączałem startap-u wydawało mi się, że robi niepotrzebne fikołki i nie starałem się go zrozumieć. Całe zycie sie czegoś uczysz.
    Wielkie dzięki!
  • #22 3182020
    damig
    Poziom 11  
    Posty: 14
    Ocena: 1
    Mam pytanie... jak użyć Startup Code czyli w wtym przypadku "Start_ad.a51"? Gdy dodaje ten plik do projektu do Source Group to program mi się ładnie kompiluje, ale po wgraniu do procka wszystko głupieje, tak jak gdyby na wejściach uC były podane zera.

    Program działa mi bez problemu, klawiszami zmieniam rózne parametry, włączam podświetlenie lcd, ale po dodaniu "Start_ad.a51" wszystko mruga i piszczy :] !

    Czegoś tu nie rozumiem pewnie...

    Chce użyć "Start_ad.a51" po to aby odpalić XRAM przy starcie uC (zgodnie z tym co zamieścił Zumek).

Podsumowanie tematu

✨ Dyskusja dotyczy aktywacji i wykorzystania wewnętrznego 2kB RAM (XRAM) w mikrokontrolerze ADuC842 podczas programowania w Keilu. Problemem było przepełnienie standardowej pamięci 256 bajtów oraz brak poprawnego dostępu do dodatkowego RAM-u umieszczonego w segmencie XDATA. Kluczowym rozwiązaniem okazało się włączenie wewnętrznego XRAM poprzez ustawienie bitu XRAMEN w pliku startowym (np. Start_ad.a51) lub bezpośrednio w rejestrze CFG842 za pomocą instrukcji ORL CFG842, #0x01. Po włączeniu XRAM zmienne i tablice mogą być deklarowane zarówno jako globalne, jak i lokalne w segmencie xdata, a kompilator Keil odpowiednio zarządza dostępem do pamięci. Inicjalizacja tablic w XRAM wymaga ręcznego kopiowania danych z pamięci programu (code) do XRAM, gdyż pamięć XRAM po resecie zawiera nieokreślone wartości. Wskazano również, że błędy w wyświetlaniu danych mogły wynikać z błędów w printf oraz nieprawidłowego ustawienia startowego kodu inicjalizującego XRAM. Podsumowując, poprawne działanie wymaga: włączenia XRAM w startupie lub rejestrze CFG842, deklaracji zmiennych w segmencie xdata, oraz ręcznego kopiowania danych inicjalizacyjnych z pamięci programu do XRAM. Dodatkowo omówiono różnice w obsłudze pamięci wewnętrznej i zewnętrznej oraz wpływ modelu pamięci na kompilację i działanie programu.
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA