Zaslal: út duben 07 2015, 8:58 Předmět: textový string v XC8
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:
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?
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 ();
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
docela ziiiram
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]
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?
Založen: Sep 19, 2007 Příspěvky: 3698 Bydliště: Praha
Zaslal: st duben 08 2015, 18:48 Předmět:
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.
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
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...
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!
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 ale i tak a ještě jednou díky
Založen: Sep 19, 2007 Příspěvky: 3698 Bydliště: Praha
Zaslal: st duben 08 2015, 21:55 Předmět:
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:
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 ------------
...
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.
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?
Založen: Sep 19, 2007 Příspěvky: 3698 Bydliště: Praha
Zaslal: čt duben 09 2015, 10:01 Předmět:
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).
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".
Časy uváděny v GMT + 1 hodina Jdi na stránku 1, 2, 3Další
Strana 1 z 3
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
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.