Vítejte na Elektro Bastlírn?
Nuke - Elektro Bastlirna
  Vytvořit účet Hlavní · Fórum · DDump · Profil · Zprávy · Hledat na fóru · Příspěvky na provoz EB

Vlákno na téma KORONAVIRUS - nutná registrace


Nuke - Elektro Bastlirna: Diskuzní fórum

 FAQFAQ   HledatHledat   Uživatelské skupinyUživatelské skupiny   ProfilProfil   Soukromé zprávySoukromé zprávy   PřihlášeníPřihlášení 

textový string v XC8
Jdi na stránku 1, 2, 3  Další
 
Přidat nové téma   Zaslat odpověď       Obsah fóra Diskuzní fórum Elektro Bastlírny -> Programování PIC, ATMEL, EEPROM a dalších obvodů
Zobrazit předchozí téma :: Zobrazit následující téma  
Autor Zpráva
Ladin



Založen: Apr 07, 2015
Příspěvky: 32

PříspěvekZaslal: út duben 07 2015, 8:58    Předmět: textový string v XC8 Citovat

Ahoj, začínám s programováním PIC kontrolérů. Zkouším v MPLAB X v komp. XC8 napsat ovladač pro SPI display. Vše mi funguje do chvíle, kdy chci text uzavřený uvozovkami prohnat funkcí.
Pokud má kod tuto formu, vše funguje perfektně:
(uvádím pouze výsek kodu)

writetext (char text[])
{
...................
}
.
.
.
char text[];
text [0] = 'A';
text [1] = 'H';
text [2] = 'O';
text [3] = 'J';
text [4] = '/n';

writetext (text);

... ale jakmile to chci zjednodušit, abych nemusel jak trubka vypisovat každé písmenko takže takto:

writetext (char text[])
{
...................
}
.
.
.
char text[] = "AHOJ/n";

writetext (text);

tak mi kompilér nezahlásí žádnou chybu, ale po nahrátí hex do picu se pic kousne, tedy spíš vůbec nenastartuje...
Hledám už pár dní kde dělám chybu, ale marně.
Nemáte někdo zkušenost?

Díky moc...
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
MiloPS3



Založen: Aug 07, 2010
Příspěvky: 262

PříspěvekZaslal: út duben 07 2015, 11:00    Předmět: Citovat

cau, nevim jak je to presne v CX8 ale:
pokud chcces vypsat string tak takle writetext (text);
ale musis mit pres ne danou velikost treba char text[10]; nebo musis na konec zapsat 0
text [4] = '/n';
text [5] = 0;

a pak samozrejme zalezi co dela ta fce writetext ();
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Ladin



Založen: Apr 07, 2015
Příspěvky: 32

PříspěvekZaslal: út duben 07 2015, 11:45    Předmět: Citovat

Ahoj Milo, dik za odpověď...

Funkce writetxt rozebira na jednotliva pismena text, pismena prevadi na pixely a posila prez spi do displeje. Ono mi to funguje, ale pouze pokud to zadam polopatě. Tu nulu jsem zkoušel a nefunguje to, ani když zadam přesný počet znaků. Kompiler nehlasi žádnou chybu ani warning, přeloží to do souboru hex, ale ten když nahraju do picu tak se vubec nespusti ani inicializace displeje, která je před samotným příkazem writetxt na začátku main(); No asi mi nezbude než to zadávat po jednom písmenku Rolling Eyes
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
MiloPS3



Založen: Aug 07, 2010
Příspěvky: 262

PříspěvekZaslal: út duben 07 2015, 15:02    Předmět: Citovat

takze kdyz das do kodu writetext (text); tak se ani neinicializuje lcd ?

dej sem tu fci writetext ();

nebo radsi cely ..
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Ladin



Založen: Apr 07, 2015
Příspěvky: 32

PříspěvekZaslal: út duben 07 2015, 15:31    Předmět: Citovat

Jj, přesně tak, pokud použiju text "takhle" v jakykoli podobě tak to nefunguje a pokud ho rozeberu 't' 'a' 'k' 'h' 'l' 'e' postupně tak to funguje...

kód:

void writetxt (char text[],char size, unsigned int x1,unsigned int y1){
    colmod16();
    switch (size){
        case 1:
           frame(x1,319,y1,y1+7);
            break;
        case 2:
           frame(x1,319,y1,y1+15);
            break;
        case 3:
           frame(x1,319,y1,y1+23);
            break;
        case 4:
           frame(x1,319,y1,y1+31);
            break;
        case 10:
           frame(x1,319,y1,y1+79);
            break;
    }
    data();
    unsigned char byte1; // prvni byte ze znaku (u "_" je to 00000001)
    unsigned char byte2; // druhy byte ze znaku
    unsigned char byte3; // treti byte ze znaku
    unsigned char byte4; // ctvrty byte ze znaku
    unsigned char byte5; // paty byte ze znaku
    unsigned char b1;
    unsigned char bit0;
    unsigned char bit1;
    unsigned char bit2;
    unsigned char bit3;
    unsigned char bit4;
    unsigned char bit5;
    unsigned char bit6;
    unsigned char bit7;

    for (long i2=0;i2 < strlen(text);i2++){
        switch (text[i2]){
// CISLOVKY
            case '0':
                byte1 = 0x3E; byte2 = 0x51; byte3 = 0x49; byte4 = 0x45; byte5 = 0x3E;
                break;
            case '1':
                byte1 = 0x00; byte2 = 0x42; byte3 = 0x7F; byte4 = 0x40; byte5 = 0x00;   //0x00, 0x42, 0x7F, 0x40, 0x00
                break;
            case '2':
                byte1 = 0x42; byte2 = 0x61; byte3 = 0x51; byte4 = 0x49; byte5 = 0x46;   //0x42, 0x61, 0x51, 0x49, 0x46
                break;
            case '3':
                byte1 = 0x21; byte2 = 0x41; byte3 = 0x45; byte4 = 0x4B; byte5 = 0x31;   //0x21, 0x41, 0x45, 0x4B, 0x31
                break;
            case '4':
                byte1 = 0x18; byte2 = 0x14; byte3 = 0x12; byte4 = 0x7F; byte5 = 0x10;   //0x18, 0x14, 0x12, 0x7F, 0x10
                break;
            case '5':
                byte1 = 0x27; byte2 = 0x45; byte3 = 0x45; byte4 = 0x45; byte5 = 0x39;   //0x27, 0x45, 0x45, 0x45, 0x39
                break;
            case '6':
                byte1 = 0x3C; byte2 = 0x4A; byte3 = 0x49; byte4 = 0x49; byte5 = 0x30;   //0x3C, 0x4A, 0x49, 0x49, 0x30
                break;
            case '7':
                byte1 = 0x01; byte2 = 0x71; byte3 = 0x09; byte4 = 0x05; byte5 = 0x03;   //0x01, 0x71, 0x09, 0x05, 0x03
                break;
            case '8':
                byte1 = 0x36; byte2 = 0x49; byte3 = 0x49; byte4 = 0x49; byte5 = 0x36;   //0x36, 0x49, 0x49, 0x49, 0x36
                break;
            case '9':
                byte1 = 0x06; byte2 = 0x49; byte3 = 0x49; byte4 = 0x29; byte5 = 0x1E;   //0x06, 0x49, 0x49, 0x29, 0x1E
                break;
// VELKA PISMENA
            case 'A':
                byte1 = 0x7E; byte2 = 0x09; byte3 = 0x09; byte4 = 0x09; byte5 = 0x7E;   //0x7E, 0x09, 0x09, 0x09, 0x7E
                break;
            case 'B':
                byte1 = 0x7F; byte2 = 0x49; byte3 = 0x49; byte4 = 0x49; byte5 = 0x36;   //0x7F, 0x49, 0x49, 0x49, 0x36
                break;
            case 'C':
                byte1 = 0x3E; byte2 = 0x41; byte3 = 0x41; byte4 = 0x41; byte5 = 0x22;   //0x3E, 0x41, 0x41, 0x41, 0x22
                break;
            case 'D':
                byte1 = 0x7F; byte2 = 0x41; byte3 = 0x41; byte4 = 0x41; byte5 = 0x3E;   //0x7F, 0x41, 0x41, 0x41, 0x3E
                break;
            case 'E':
                byte1 = 0x7F; byte2 = 0x49; byte3 = 0x49; byte4 = 0x41; byte5 = 0x41;   //0x7F, 0x49, 0x49, 0x41, 0x41
                break;
            case 'F':
                byte1 = 0x7F; byte2 = 0x09; byte3 = 0x09; byte4 = 0x01; byte5 = 0x01;   //0x7F, 0x09, 0x09, 0x01, 0x01
                break;
            case 'G':
                byte1 = 0x3E; byte2 = 0x41; byte3 = 0x49; byte4 = 0x49; byte5 = 0x3A;   //0x3E, 0x41, 0x49, 0x49, 0x3A
                break;
            case 'H':
                byte1 = 0x7F; byte2 = 0x08; byte3 = 0x08; byte4 = 0x08; byte5 = 0x7F;   //0x7F, 0x08, 0x08, 0x08, 0x7F
                break;
            case 'I':
                byte1 = 0x00; byte2 = 0x41; byte3 = 0x7F; byte4 = 0x41; byte5 = 0x00;   //0x00, 0x41, 0x7F, 0x41, 0x00
                break;
            case 'J':
                byte1 = 0x31; byte2 = 0x41; byte3 = 0x41; byte4 = 0x41; byte5 = 0x3F;   //0x31, 0x41, 0x41, 0x41, 0x3F
                break;
            case 'K':
                byte1 = 0x7F; byte2 = 0x08; byte3 = 0x14; byte4 = 0x22; byte5 = 0x41;   //0x7F, 0x08, 0x14, 0x22, 0x41
                break;
            case 'L':
                byte1 = 0x7F; byte2 = 0x40; byte3 = 0x40; byte4 = 0x40; byte5 = 0x40;   //0x7F, 0x40, 0x40, 0x40, 0x40
                break;
            case 'M':
                byte1 = 0x7F; byte2 = 0x02; byte3 = 0x04; byte4 = 0x02; byte5 = 0x7F;   //0x7F, 0x02, 0x04, 0x02, 0x7F
                break;
            case 'N':
                byte1 = 0x7F; byte2 = 0x04; byte3 = 0x08; byte4 = 0x10; byte5 = 0x7F;   //0x7F, 0x04, 0x08, 0x10, 0x7F
                break;
            case 'O':
                byte1 = 0x3E; byte2 = 0x41; byte3 = 0x41; byte4 = 0x41; byte5 = 0x3E;   //0x3E, 0x41, 0x41, 0x41, 0x3E
                break;
            case 'P':
                byte1 = 0x7F; byte2 = 0x09; byte3 = 0x09; byte4 = 0x09; byte5 = 0x06;   //0x7F, 0x09, 0x09, 0x09, 0x06
                break;
            case 'Q':
                byte1 = 0x3E; byte2 = 0x41; byte3 = 0x51; byte4 = 0x21; byte5 = 0x5E;   //0x3E, 0x41, 0x51, 0x21, 0x5E
                break;
            case 'R':
                byte1 = 0x7F; byte2 = 0x09; byte3 = 0x19; byte4 = 0x29; byte5 = 0x46;   //0x7F, 0x09, 0x19, 0x29, 0x46
                break;
            case 'S':
                byte1 = 0x26; byte2 = 0x49; byte3 = 0x49; byte4 = 0x49; byte5 = 0x32;   //0x26, 0x49, 0x49, 0x49, 0x32
                break;
            case 'T':
                byte1 = 0x01; byte2 = 0x01; byte3 = 0x7F; byte4 = 0x01; byte5 = 0x01;   //0x01, 0x01, 0x7F, 0x01, 0x01
                break;
            case 'U':
                byte1 = 0x3F; byte2 = 0x40; byte3 = 0x40; byte4 = 0x40; byte5 = 0x3F;   //0x3F, 0x40, 0x40, 0x40, 0x3F
                break;
            case 'V':
               byte1 = 0x1F; byte2 = 0x20; byte3 = 0x40; byte4 = 0x20; byte5 = 0x1F;    //0x1F, 0x20, 0x40, 0x20, 0x1F
                break;
            case 'W':
                byte1 = 0x3F; byte2 = 0x40; byte3 = 0x30; byte4 = 0x40; byte5 = 0x3F;   //0x3F, 0x40, 0x30, 0x40, 0x3F
                break;
            case 'X':
                byte1 = 0x63; byte2 = 0x14; byte3 = 0x08; byte4 = 0x14; byte5 = 0x63;   //0x63, 0x14, 0x08, 0x14, 0x63
                break;
            case 'Y':
                byte1 = 0x03; byte2 = 0x04; byte3 = 0x78; byte4 = 0x04; byte5 = 0x03;   //0x03, 0x04, 0x78, 0x04, 0x03
                break;
            case 'Z':
                byte1 = 0x61; byte2 = 0x51; byte3 = 0x49; byte4 = 0x45; byte5 = 0x43;   //0x61, 0x51, 0x49, 0x45, 0x43
                break;
            case ' ':
                byte1 = 0x00; byte2 = 0x00; byte3 = 0x00; byte4 = 0x00; byte5 = 0x00;   //0x61, 0x51, 0x49, 0x45, 0x43
                break;
            case '°':
                byte1 = 0x00; byte2 = 0x07; byte3 = 0x05; byte4 = 0x07; byte5 = 0x00;   //0x61, 0x51, 0x49, 0x45, 0x43
                break;
        }
                     
    for (long i=0;i < 5;i++){
    //b1 = byte[i];
        switch (i){
            case 0:
                b1 = byte1;
                break;
            case 1:
                b1 = byte2;
                break;
            case 2:
                b1 = byte3;
                break;
            case 3:
                b1 = byte4;
                break;
            case 4:
                b1 = byte5;
                break;
        }

    bit0 = (b1 & 0b00000001)*255;       // & je AND .. 0 AND 1 = 0 a 1 AND 1 = 1
    bit1 = ((b1 & 0b00000010)>>1)*255;  // >>1 p?esune bity o 1 místo vpravo
    bit2 = ((b1 & 0b00000100)>>2)*255;
    bit3 = ((b1 & 0b00001000)>>3)*255;
    bit4 = ((b1 & 0b00010000)>>4)*255;
    bit5 = ((b1 & 0b00100000)>>5)*255;
    bit6 = ((b1 & 0b01000000)>>6)*255;
    bit7 = ((b1 & 0b10000000)>>7)*255;  // >>7 p?esune bity o 7 míst vpravo

    switch (size){
        case 1:
            putcSPI(bit0);    putcSPI(bit0);    putcSPI(bit1);    putcSPI(bit1);    putcSPI(bit2);    putcSPI(bit2);    putcSPI(bit3);    putcSPI(bit3);
            putcSPI(bit4);    putcSPI(bit4);    putcSPI(bit5);    putcSPI(bit5);    putcSPI(bit6);    putcSPI(bit6);    putcSPI(bit7);    putcSPI(bit7);
            break;
        case 2:
            for (char iii=0;iii<2;iii++){
            for (char ii=0;ii < 4;ii++){putcSPI(bit0);}
            for (char ii=0;ii < 4;ii++){putcSPI(bit1);}
            for (char ii=0;ii < 4;ii++){putcSPI(bit2);}
            for (char ii=0;ii < 4;ii++){putcSPI(bit3);}
            for (char ii=0;ii < 4;ii++){putcSPI(bit4);}
            for (char ii=0;ii < 4;ii++){putcSPI(bit5);}
            for (char ii=0;ii < 4;ii++){putcSPI(bit6);}
            for (char ii=0;ii < 4;ii++){putcSPI(bit7);}
            }
            break;
        case 3:
            for (char iii=0;iii<3;iii++){
            for (char ii=0;ii < 6;ii++){putcSPI(bit0);}
            for (char ii=0;ii < 6;ii++){putcSPI(bit1);}
            for (char ii=0;ii < 6;ii++){putcSPI(bit2);}
            for (char ii=0;ii < 6;ii++){putcSPI(bit3);}
            for (char ii=0;ii < 6;ii++){putcSPI(bit4);}
            for (char ii=0;ii < 6;ii++){putcSPI(bit5);}
            for (char ii=0;ii < 6;ii++){putcSPI(bit6);}
            for (char ii=0;ii < 6;ii++){putcSPI(bit7);}
            }
            break;
        case 4:
            for (char iii=0;iii<4;iii++){
            for (char ii=0;ii < 8;ii++){putcSPI(bit0);}
            for (char ii=0;ii < 8;ii++){putcSPI(bit1);}
            for (char ii=0;ii < 8;ii++){putcSPI(bit2);}
            for (char ii=0;ii < 8;ii++){putcSPI(bit3);}
            for (char ii=0;ii < 8;ii++){putcSPI(bit4);}
            for (char ii=0;ii < 8;ii++){putcSPI(bit5);}
            for (char ii=0;ii < 8;ii++){putcSPI(bit6);}
            for (char ii=0;ii < 8;ii++){putcSPI(bit7);}
            }
            break;
        case 10:
            for (char iii=0;iii<8;iii++){
            for (char ii=0;ii < 20;ii++){putcSPI(bit0);}
            for (char ii=0;ii < 20;ii++){putcSPI(bit1);}
            for (char ii=0;ii < 20;ii++){putcSPI(bit2);}
            for (char ii=0;ii < 20;ii++){putcSPI(bit3);}
            for (char ii=0;ii < 20;ii++){putcSPI(bit4);}
            for (char ii=0;ii < 20;ii++){putcSPI(bit5);}
            for (char ii=0;ii < 20;ii++){putcSPI(bit6);}
            for (char ii=0;ii < 20;ii++){putcSPI(bit7);}
            }
            break;
    }

    }
    for (int i4=0; i4 < size; i4++){
        for (int i3=0; i3 < 16*size; i3++){
        putcSPI(0);
    }
    }
    }
    CS = 1;
}


Naposledy upravil Ladin dne st duben 08 2015, 17:53, celkově upraveno 1 krát.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
MiloPS3



Založen: Aug 07, 2010
Příspěvky: 262

PříspěvekZaslal: út duben 07 2015, 15:47    Předmět: Citovat

docela ziiiram Shocked
to si napsal sam ? nebo nekde okopcil
to mas vlastni fonty?
nevidim tam nikde tu fci writetext (); , jen writetxt (char text[],char size, unsigned int x1,unsigned int y1), a pokud je to ona tak je divny ze ti to jde vubec prelozit protoze ti tam chybi pri volani velikost x1 a y1
pro jakej displej to je ?
a kod se dava do [ code ]

jinak se my nechce skoumat do detajlu co to vsechno dela ...[/code]
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Jeejda_teda_puvodne



Založen: Apr 08, 2012
Příspěvky: 142

PříspěvekZaslal: út duben 07 2015, 17:15    Předmět: Citovat



Naposledy upravil Jeejda_teda_puvodne dne út říjen 25 2016, 18:41, celkově upraveno 1 krát.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Ladin



Založen: Apr 07, 2015
Příspěvky: 32

PříspěvekZaslal: st duben 08 2015, 16:36    Předmět: Citovat

Very Happy Milo tak to buď rád, že jsem tam dal jenom kod te funkce writetxt a ne celej kod, to by si asi koukal víc... jo psal jsem to sám... Jsem tu novej a s picem začínám takže se omlouvám jesi jsem to zadal špatně. Je to pro displej s řadičem ILI9341, ale to není podstatný, ptže otázka se týkala spíš formy zadávání textových řetězců. Já když tu funkci napíšu prázdnou: writetxt (char text[]) {} a pošlu do ní ten text definovanej takto: char text[] = "AHOJ/n"; tak se pic kousne taky. Když text zadam takto: char text[];
text [0] = 'A';
text [1] = 'H';
text [2] = 'O';
text [3] = 'J';
text [4] = '/n';

tak to běží normálně ať je tam ten můj paskvil ve funkci nebo ne... x1 a y1 jsou myslim definované velikostně unsigned int takže pokud se nepletu 0x0000 až 0xFFFF... nebo sem uplně mimo? Embarassed
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
mtajovsky



Založen: Sep 19, 2007
Příspěvky: 3698
Bydliště: Praha

PříspěvekZaslal: st duben 08 2015, 18:48    Předmět: Citovat

Pár poznámek.

1) Stringový literál je obvyklejší takto:
kód:
char* text = "Ahoj\n";


2) Escape znak je \, nikoliv /

3) Prototyp funkce:
kód:
void writetxt(char* text, size_t size, unsigned int x1,unsigned int y1);


4) Všechny řetězcové literály bych umístil do kódové paměti. Když to uděláte tak, jak to máte teď, tak se na začátku programu vygeneruje kód, který tím stringem naplní RAM. S nebezpečím, že se RAM přeplní a bez valného významu, pokud ten string nechcete za běhu měnit.

5) Namísto toho šíleného switche pro číslovky a písmena bych použil dvourozměrné pole umístěné v kódové paměti.

6) Také další switch je zbytečný, pokud se byte1 až byte5 umístí do pole. navíc celý ten cyklus
kód:
 for (long i=0;i < 5;i++){
se mi zdá být nic nedělající, než že do bl umístí byte5.

7) Pokud je to možné, používejte ++x namísto x++, je to většinou rychlejší. Operátor x++ musí vytvářet kopii x, pak x inkrementuje a kopii odevzdá jako svoji výslednou hodnotu.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Odeslat e-mail
Ladin



Založen: Apr 07, 2015
Příspěvky: 32

PříspěvekZaslal: st duben 08 2015, 21:03    Předmět: Citovat

Pravdou je, že mi dělá celkem problém pochopit funkci ukazatele. Předtím jsem dělal v basicu picaxe a tam je to takové jasné... tohle je rom a takhle to zkopiruj do ram a takhle dlouho to tam nech a pak to zase použij.
Za poznámky mnohokrát díky, takhle na konkrétním a vlastním příkladu je to snazší pochopit.

K bodu 1: vyzkouším... (zatím nerozumím)

2: jj pravda, napsal jsem to blbě, originál mám dobře

3: vyzkouším Smile

4: pomohlo by mi pochopit pojem kodová paměť, to je zřejmě funkce ukazatele? já právě nevím jestli to vůbec chápu alespoň částečně, že hvězdička(ukazatel) ukazuje na místo v paměti programu, v paměti rom? je mi jasné, že to bude základ C, ale ať to čtu kde chci, jako uživatel basicu to nemůžu vstřebat... Embarassed
5: dvourozměrné pole v kodove pameti... takže např. takto?
kód:
char* ascii [5] [50];

a jak pozná kdy jaké písmeno použit v tu pravou chvíly?

6: myslím, že je to špatně vidět, zbytečné to není, funguje to, každé písmeno je složené z 5ti bajtů, display ho vykresluje odleva a ten for i dělá to, že proměnné b1 nejprve přiřadí bajt0 písmene potom vykreslí a dále v dalším cyklu b1 přiřadí bajt1 a vykreslí dokud nevykreslí celé písmeno, ať se to zdá šílené tak to funguje, věřím, že to jde napsat lépe, ale zatím neumím.. původně jsem to psal do pole byte[i], ale to mi nefungovalo, kreslilo to bludy tak sem to natvrdo rozdelil na bite1,2,3,4,5

7: dobrý tip, to mě nenapadlo! Smile

Ani jsem nepočítal s tím, že by to někdo takhle louskal takže za tu trpělivost díky, předpokládám, že tady bude trpělivost končit Laughing ale i tak a ještě jednou díky Embarassed
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
mtajovsky



Založen: Sep 19, 2007
Příspěvky: 3698
Bydliště: Praha

PříspěvekZaslal: st duben 08 2015, 21:55    Předmět: Citovat

Ad1) Je to obvyklejší, na řetězcový literál přímo ukazuje pointer typu char*.

Ad4) Tyhle mikrokontroléry mají Harwardskou architekturu, to znamená, že mají oddělenou paměť typu RAM pro data a paměť pro instrukce programu, bývá to FLASH, EEPROM, ROM. To neznamená, že by paměť na program nemohla obsahovat nic jiného, než instrukce. Může obsahovat cokoliv, co se považuje za konstantní, to znamená i nějaké pevné řetězce pro menu na LCD a podobně. Dotyčný překladač musí obsahovat příslušné rozšíření, které umožní říci, že se data mají nacházet v kódové paměti (jinak je bude alokovat do RAM). Mělo by to být v dokumentaci pro překladač. Jako příklad uvedu fragment zpracování AT povelů napsaný pro gcc pro AVR:
kód:

...
typedef s08 (*AT_SERVICE)(const char* prm);

...

static char cmdReset[]      PROGMEM = "Z";
static char cmdVersion[]    PROGMEM = "+GMM";
static char cmdFactory[]    PROGMEM = "&F";
static char cmdStoreCfg[]   PROGMEM = "&W";
static char cmdRestoreCfg[] PROGMEM = "&V";
static char cmdMode[]       PROGMEM = "\\N";
static char cmdFrequency[]  PROGMEM = "&G";
static char cmdModulation[] PROGMEM = "+MS";
static char cmdMarker[]     PROGMEM = "+CUR";
static char cmdSweep[]      PROGMEM = "+SWR";
static char cmdMrkStep[]    PROGMEM = "+CST";

static prog_char* at_cmd[] PROGMEM =
{
    cmdReset, cmdVersion, cmdFactory,
    cmdStoreCfg, cmdRestoreCfg, cmdMode,
    cmdFrequency, cmdModulation, cmdMarker,
    cmdSweep, cmdMrkStep
};

static s08 (*at_service_tab[]) (const char* prm) PROGMEM =
{
    ATReset, ATVersion, ATFactory,
    ATStoreCfg, ATRestoreCfg, ATMode,
    ATFrequency, ATModulation, ATMarker,
    ATSweep, ATMrkStep   
};

kde řetězce cmdXXX jsou vzory pro AT povely, at_cmd[] je tabulka pointerů na ně a at_service_tab je tabulka pointerů na funkce, které AT povely zpracovávají. Všechno leží v paměti FLASH spolu s programem. Přístup na tyto hodnoty je také poněkud jiný:
kód:

// --------------------- AT command processing ------------

s08 findATFunction(const char* cmd)
{
    for(u08 i = (u08)0; i < (u08)(sizeof(at_cmd)/sizeof(char*)); ++i)
    {
        PGM_P cmd_P = (PGM_P)pgm_read_word(at_cmd + i);
        if(strcasecmp_P(cmd, cmd_P) == 0)
        {
            return (s08)i;
        }
    }
    return (s08)-1;
}

...
AT_SERVICE at_service;                                         // pointer to service function

        index = findATFunction(cmd);
        if(index != (s08)-1)
        {
               at_service = (AT_SERVICE)pgm_read_word_near(&at_service_tab[(u08)index]);
                u08 ret = at_service(prm);                     // find and run service function
         }



Funkce findATFunction() prohledává tabulku AT povelů pomocí pgm_read_word(at_cmd + i) a srovnává řetězce pomocí strcasecmp_P(). Podle nalezeného indexu se pak načte pointer na funkci pomocí pgm_read_word_near(). Takto je všechno konstantní v kódové paměti a ušetří se RAM.

Ad5) Ano, všechny ty hodnoty do 2D pole. Řádek odvozovat od číslice (písmene) namísto toho case, byte1 - byte5 načíst pak v cyklu z řádku do pole 5 byte.

Ad6) Máte pravdu, špatně jsem spároval závorky.


Naposledy upravil mtajovsky dne čt duben 09 2015, 8:22, celkově upraveno 1 krát.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Odeslat e-mail
Ladin



Založen: Apr 07, 2015
Příspěvky: 32

PříspěvekZaslal: čt duben 09 2015, 8:22    Předmět: Citovat

Shocked no pane jo, přečetl jsem to asi dvacetkrát a mám pocit, že když si teď kejchnu, rozletí se mě hlava a z krku vyteče písmenková polívka...

Takže jestli jsem to alespoň trochu pochopil, v prvním příkladu mcu určíte pomocí ukazatelů "sadu" příkazů, tedy zřejmě vždy číslo registru paměti programu kde se ten řetězec nachází? ... a podobně pak určíte funkce.. ve finále pak jde volat a různě kombinovat příkazy a funkce... už možná začínám tušit, v basicu je to rozděleno na šest různých příkazů, pokud chci zapisovat do ram tak je to poke, číst z ram peek, zapisovat do eeprom DATA, číst READ, zapisovat do programové paměti TABLE, číst READTABLE.. a tady je to tedy rozlišeno pomocí ukazatelů *, je to tak?

Jdu si to ještě přečíst Idea
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
mtajovsky



Založen: Sep 19, 2007
Příspěvky: 3698
Bydliště: Praha

PříspěvekZaslal: čt duben 09 2015, 8:31    Předmět: Citovat

Podstatné je to PROGMEM. To určuje, že je proměnná situována do kódové paměti. Čtení z kódové paměti je pomocí pgm_read_word() a podobně.

PGM_P a prog_char* jsou ukázky, jak vypadá deklarátor pointeru na char v kódové paměti.

Možná je pro vás trochu nezvyklá syntaxe definice typu "pointer na funkci".
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Odeslat e-mail
Ladin



Založen: Apr 07, 2015
Příspěvky: 32

PříspěvekZaslal: čt duben 09 2015, 9:04    Předmět: Citovat

V MPLABU X IDE mi PROGMEM nejde(unexpected token), nevíte v jaké knihovně by to mohlo být?
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
mtajovsky



Založen: Sep 19, 2007
Příspěvky: 3698
Bydliště: Praha

PříspěvekZaslal: čt duben 09 2015, 10:01    Předmět: Citovat

To není rutina z nějaké knihovny, to je rozšířená syntaxe kompilátoru C pro tyto účely. Uvedl jsem příklad pro AVR gcc a WinAVR. Bohužel, s PIC nemám zkušenosti. PROGMEM atd. jsou makra a typy specifikovaná v hlavičkovém souboru <avr/pgmspace.h>, který je součástí balíku WinAVR:

#define PROGMEM __ATTR_PROGMEM__
a
#define __ATTR_PROGMEM__ __attribute__((__progmem__))

kde atribut __attribute__((__progmem__)) již rozeznává rovnou kompilátor (zobecněné atributy C++11).

#define PGM_P const char *
typedef char PROGMEM prog_char;

a další. Pokud kompilátor nalezne tuto syntaxi, tak umístí takto definovaná data do paměťového segmentu pro kód.

Pro vaše prostředí MPLABU budete muset najít v v dokumentaci, jaká je syntaxe příslušného atributu rozeznávaného kompilátorem a jestli hlavičkové soubory dodávané ke kompilátoru nebo k prostředí obsahují příslušná makra a definice typů (nebo si to napsat sám). Mohly by tam být i nějaké příklady. Podle toho pak musíte napsat do kódu potřebné atributy a typy v místech, kde jsem pro AVR použil PROGMEM a další. Předpokládám, že C kompilátor pro PIC to umí. Hledejte v dokumentaci něco jako "Data in Program Space".

http://www.microchip.com/forums/m166493.aspx
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Odeslat e-mail
Zobrazit příspěvky z předchozích:   
Přidat nové téma   Zaslat odpověď       Obsah fóra Diskuzní fórum Elektro Bastlírny -> Programování PIC, ATMEL, EEPROM a dalších obvodů Časy uváděny v GMT + 1 hodina
Jdi na stránku 1, 2, 3  Další
Strana 1 z 3

 
Přejdi na:  
Nemůžete odesílat nové téma do tohoto fóra.
Nemůžete odpovídat na témata v tomto fóru.
Nemůžete upravovat své příspěvky v tomto fóru.
Nemůžete mazat své příspěvky v tomto fóru.
Nemůžete hlasovat v tomto fóru.
Nemůžete připojovat soubory k příspěvkům
Můžete stahovat a prohlížet přiložené soubory

Powered by phpBB © 2001, 2005 phpBB Group
Forums ©
Nuke - Elektro Bastlirna

Informace na portálu Elektro bastlírny jsou prezentovány za účelem vzdělání čtenářů a rozšíření zájmu o elektroniku. Autoři článků na serveru neberou žádnou zodpovědnost za škody vzniklé těmito zapojeními. Rovněž neberou žádnou odpovědnost za případnou újmu na zdraví vzniklou úrazem elektrickým proudem. Autoři a správci těchto stránek nepřejímají záruku za správnost zveřejněných materiálů. Předkládané informace a zapojení jsou zveřejněny bez ohledu na případné patenty třetích osob. Nároky na odškodnění na základě změn, chyb nebo vynechání jsou zásadně vyloučeny. Všechny registrované nebo jiné obchodní známky zde použité jsou majetkem jejich vlastníků. Uvedením nejsou zpochybněna z toho vyplývající vlastnická práva. Použití konstrukcí v rozporu se zákonem je přísně zakázáno. Vzhledem k tomu, že původ předkládaných materiálů nelze žádným způsobem dohledat, nelze je použít pro komerční účely! Tento nekomerční server nemá z uvedených zapojení či konstrukcí žádný zisk. Nezodpovídáme za pravost předkládaných materiálů třetími osobami a jejich původ. V případě, že zjistíte porušení autorského práva či jiné nesrovnalosti, kontaktujte administrátory na diskuzním fóru EB.


PHP-Nuke Copyright © 2005 by Francisco Burzi. This is free software, and you may redistribute it under the GPL. PHP-Nuke comes with absolutely no warranty, for details, see the license.
Čas potřebný ke zpracování stránky 0.24 sekund