Statická globální proměnná (slovo “statická” zde nemá význam - je vždy v ram od spuštění programu) znamená že je přístupná jen v souboru, ve kterém je definována.
Další věc je, že není vhodné, aby do proměnných jednoho souboru mohl přímo rejpat jinej soubor - proměnné by měly být vidět pouze v souboru, ve kterém jsou definovány. To máš tedy správně, jen ten záznam v .h souboru zruš. Pointr si naplň třeba inicializační funkcí souboru s polem vracející právě adresu pole.
Aha takže v podstatě to mám udělat naopak. Pointr bude definován ve zpracování.h a bude globální, vyvedený pomocí extern, kde při inicializaci hodím adresu počátku pole.
Problém proč sem to spíš takto neudělal je že pracuji s 32bit AVRkem takže ty uint16_t by měli být teoreticky na jedné adrese dva a myslel sem si že se s tím překladač už nějak popere sám. Nevím teda jak udělat to ukládání hodnot. Napadá mě mít dočasnou 32bit proměnou do které sudou hodnotu skládat a posouvat o 16 bitů a pak až ukládat.
I to je samozřejmě možnost, ale původně jsem to myslel tak, že pointer necháš tam kde je a v souboru si vytvoříš inicializační funkci jež na začátku zavoláš a ta ti pointer naplní. Globální nemusíš mít vůbec nic, lze si vystačit s parametry a návratovou hodnotou.
Tvůj postup stále neřeší, že 1 soubor může přímo vrtat do proměnných jiného souboru. Tomu by ses měl pokud možno vyhnout. Programový modul by měl být autonomní celek, u kterého jsou vidět pouze jeho funkce (+ případné definice a datové typy).
Budeš-li chtít zpracovávat v zpracuj.c nějaká data, tato by sis měl předat pointerem (parametr zpracovávací funkce).
Stejně tak lze udělat obsluhu příjmu dat - v mainu budeš mít buffer a jeho adresu předáš při inicializaci (třeba uartu) té inicializační funkci. Ta funkce si onen pointer na data uloží a později ho použije pro zápis přijatých dat. Ale rozhodně bys to neměl dělat tak, že se z jednoho souboru budeš přímo odvolávat na proměnnou jiného souboru (značně to zhoršuje čitelnost a udržovatelnost kódu).
Jinak pointer je vždy adresa v paměti. Kolik se toho bude číst (jesli 1B nebo 4B) určuje typ pointeru a způsob práce s ním a dále jeho typ určuje chování při pointerové aritmetice.
Budeš-li indexovat pointer na byte, bude se adresa zvyšovat o 1. U pointeru na int32 se skáče o 4.
No ono to volání funkce zpracuj chodí ještě odjinud. Ty hodnoty se tam jen pravidelně ukládájí. Nějak nechápu jak to předat v konkrétním případě. Nějak takto nebo jsem úplně vedle ?
Popiš jak má program fungovat. Vždy, když voláš “zpracuj” tak řešíš nová data z místa volání nebo se mají zpracovávat data, která byla uložena dříve odjinud? Zatím netuším, o co přesně jde.
Program funguje tak že každých 10ms projede AD převodník nadefinované piny (v souboru mereni.c) zcela nezávisle na celém zbytku . Pak v souboru rozhodováni.c za určitých podmínek dojde k zavolani funkce zpracuj v souboru zpracovani.c a i nadále se s těmi daty pracuje. Nezáleží jestli jsou zcela aktuální. Jde o to aby si meření (odečítání hodnot) jelo svým životem. A zpracování do něj mělo přístup, respektive to potřebuji naopak. Ve zpracování vytvořené pole hodnot a měření do něj mělo přístup aby ho mohlo přepisovat.
Napsal jsem to jen v poznamkovym bloku. Kdybys to nedal dohromady, zbastlim funkční příklad. Předpokládám, že víš, že může být zpracování spuštěno na polovině starých a polovině nových dat a nevadí ti to (pokud si nedoděláš povolení přístupu k datům - hodila by se struktura, i třeba na indexy).[code]zpracuj.c
static uint16_t pole[xx]; // static = pole neni videt mimo soubor
uint16_t *getPtr(void){ return pole; } // + prototyp v .h, “pole” bez indexu ~~ pointer
/// … dalsi funkce[/code][code]mereni.c
#include “zpracuj.h”
void ulozData(void)
{
static uint16_t *pData = null; // static = promenna zustane i po ukonceni funkce
if(!pData) pData = getPtr(); // ze zpracuj
// prace s daty
pData[index] = zmerenaHodnota;
...
Díky, zřejmě tomu rozumím. Takže mi s polem “pole” vznikne i pole pointrů “pData”, chápu to dobře ?
Jinak k té funkci. Ono to nevadí, ty data z převodníku jsou na sobě nezávislá, takže pokud se to na tom nezasekne, tak o nic nejde.
“pole” (název pole) je sám o sobě pointer - adresa prvního prvku (sám je umístěn v paměti nezávisle na datech) a také pointer lze použít jako pole (s indexací). Jsou tam určité rozdíly, ale to není teď podstatné.
“uint16_t *getPtr(void)” je funkce bez parametru vracející pointer na uint16_t.
pData tedy ukazuje (stejně jako “data”) na první prvek a pData[x] pak vrací x-tý prvek (jako data[x]).
pData[0] je mimo jiné to samé jako *pData.