naplnění statické proměné přes pointer

Zdravím,

potřeboval bych poradit jak naplnit statické pole uintů, deklarované v souboru zpracovani.c… nějak se s tím nemůžu poprat.

vyzkoušel sem toto a bude tu někde chyba:

mereni.c
include zpracovani.h

uint16_t *pHodnota = NULL;

void kazdych10ms (void)
{
pHodnota = &hodnota[0];
*pHodnota = adc_get_value(adc, 0);
}

zpracovani.h
static uint16_t hodnota[4];

zpracovani.c
static uint16_t hodnota[4]= {0,0,0,0};
void zpracuj (void)
temp = hodnota[0];

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.

Jo tak sem zase jenom fantazíroval a ono to ve skutečnosti tak není. Už to funguje jak má. Díky piityy.

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 ?

zpracuj.c
uint_16t *adresa inicializujpointer (void)
return &hodnota[0]

mereni.c

uint16t *phodnota = inicializujpointer();

void kazdych10ms (void)
{
*phodnota = 200;
phodnota +=1;
*phodnota = 300;
}

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;
...

}
[/code]

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.

Ještě si akorát nejsem jistý jestli se v řádku :

pData[index] = zmerenaHodnota; 

jedná o překlep, nebo je to jinak, asi takhle:

*pData[index] = zmerenaHodnota; 

Vyzkouším zítra. Díky moc.

“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.

Super už tomu rozumím. Vše funguje jak má. Patří ti velké DÍKY