Programování uC Microchip v C

Pokud bys z každýho něco potřeboval vkládat, tak to máš špatně sestavený a dřív či později narazíš na problém. Jediný co můžeš v .c souboru potřebovat je jiný .h. Žádné vkládání .c souborů ani výkonný kód v .h nepřipadá v úvahu. Před sebou mám program sestavený z mých 31 souborů (moduly od výrobce mcu nepočítám, to by přidalo dalších 30) a není v tom žádný problém ani zmatek. To by se ale v žádném případě nedalo říct, kdyby byl projekt sestaven blbě. Pravděpodobnost, že by fungoval, by nebyla velká.

V souborech .h je pouze popis toho, co umí soubor .c. Soubor .c se smí v projektu nacházet POUZE 1x (vložení pomocí include vytváří jeho kopie), jinak si připravuješ velice těžko odhalitelné chyby v podobě překrytí proměnných, jejich viditelnosti a podobně.

Když tedy máš např. soubor uart.c, k němu patří soubor uart.h. Do .c poté, co ho vytvoříš, už nijak nevrtáš a taky by z něho nemělo být přímo nic vidět pro ostatní soubory. Vše, co uart.c poskytuje k dispozici musí být popsáno v uart.h.
Ten si poté když je potřeba vložíš do main.c a tomu to stačí. Nepotřebuje vědět, jak funkce pracuje, potřebuje znát pouze její parametry, návratovou hodnotu a jmého. O to, aby to vše nakonec fungovalo se postará linker. A právě linkeru můžeš vytvořit problém vkládáním .c souborů s kódem místo .h obsahujících pouze popis.

ZAsielam ten zazrak dost veci tam je odkomentovanych kedze musim prejst s HItec prekladasca na CCS. pripomienky uvitam… a pytat odomna definovanie DEVICE tak ze mi to neprelozi.
mc.rar (32.2 KB)

budes si to muset asi trochu jeste poopravit, moc sem to nestudoval ale kdyz mas pin nadefinovanej jako vstup tak … while(input(sdain)); v pripade vystupu bez LATx netusim

ten eror s DEVICE je kdyz mas vic *.C v Source Files…

me ten projekt od tebe nesel otevrit tak sem zalozil novej
1wire_PIC.rar (36.1 KB)

Soubory *.h nemají ochranu proti vícenásobnému vložení (doplněno).

Makra se píšou velkými písmeny (jinak je to nepřehledné).
Parametrická makra musejí být důsledně závorkována.

Neuškodilo by si zvyknout na jeden formátovací styl a ten dodržovat, tohle je celkem chaos.
Nic nevracející funkce (void) nemusí mít “return”, lze ho však použít např. pro předčasné ukončení fce.

Jsou-li některé definice globální (potřeb ve více souborech), je vhodné si je dát do samostatného .h souboru a dle potřeby ho vkládat (každý .h nemusí mít svůj .c).

V souborech se podívej po po textech “todo” - jsou tam nějaké komentáře a návrhy.
Soubor ddd.h není nikde použit (ani použití zakomentováno). Každopádně je v něm výkonný kód - ten tam nemá co dělat.
Soubor převeden na .c a vytvořen .h. Tento programový modul sám o sobě však nemá smysl - nepůjde přeložit, patrně byl součástí jiného souboru (využívá definice z 1wire_PIC.c - spouštěcího souboru).

Některé soubory mají globální proměnné definované v .h souborech. Zcela špatně. Když už musí být proměnná globální a viditelná ve všech souborech (rozhodně nedoporučuji), deklaruje se v patřičném .c a do .h souboru se vloží s prefixem “extern” (nevytvoří novou proměnnou v každém souboru, pouze jim řekne, že už někde je a linker si ji najde).

Tento rozoraný projekt nejspíš přeložit nepůjde. Možná by bylo vhodnější sem dát na inspekci něco jednoduššího a podle toho pak upravovat ten větší projekt (nemám nainstalováno vaše IDE a překladač abych to uvedl do přeložitelného stavu).
1wire_PIC.zip (10.4 KB)

Ok dakujem zatial, zajtra sa do toho pustim a zavesim tu nieco snad prelozitelne.

to co tet upravil piityy mas dany v projektu a jde to prelozit , priloha v prispevku 28 září 2012, 16:32

akorad je tam 27 hlaseni…

Uz som to nejako urobil aby to chodilo. Kontrolne otazky, ked chccem pridat nejake podprogramy ktore su v inom C subore, musim v hlavnom C nalinkovat H aj C, doteraz som bol v tom ze staci H, je pravda ze som maval C v zlozke source C.
CCS neumoznuje vypisovanie textu priamo z ROM ? ale musim zvlast kopirovat do ram pripadne ukladat priamo v ram ?.
By ma zaujimala nejaka vyhoda oproti Htech kompileru lebo zatial vidim same minus, vsetko sa robi komplikovane.

Vždy se vkládá pouze .h soubor. V něm jsou (musí být) všechna potřebná data pro použití veřejných funkcí vytvořených v .c.

Tak potom v h cku musi byt include jeho cecka?

Nemusí, ani “nesmí”. Překladač ví, že .h a .c se stejným jménem patří k sobě. Naopak .h soubor se vkládá do svého .c pokud je potřeba (bývají tam různé definice, které .c soubor potřebuje).

Tak to vysvetlite prekladacu ze to tak ma byt, v Hlavnom*.C musim mat #include “lcd.c” inak to nechodi… v lcd.C zasa #include “lcd.h”, a je aj ina moznost v hlavnom*.C mat lcd.h aj lcd.c

Vtom případě je to blbě napsaný nebo je blbě nastavený IDE (který volá překladač), případně není zdroják přidán v projektu a IDE o něm neví (vloží ho tam až preprocesor).
Že je vložen lcd.h v lcd.c je vpořádku.

a máš to lcd přidané do projektu? v source files

Nie lebo sa to nepaci prekladacu tam je len hlavne cecko, ked to troska upravim dam to sem.

Som spät… prosim navod, lebo tak sa robit neda neviem spojazdnit prerusenie na 16f628A pomocou TMR0.

Urobim take veci: inicalixacia

[code] SETUP_TIMER_0(T0_INTERNAL);
SETUP_TIMER_0(T0_DIV_256);

//hlavna slucka
CLEAR_INTERRUPT(INT_TIMER0);
ENABLE_INTERRUPTS(INT_TIMER0);
ENABLE_INTERRUPTS(GLOBAL);

delay_ms(300);
delay_ms(300);
delay_ms(300);
DISABLE_INTERRUPTS(INT_TIMER0);

//program prerusenia to ani neregistruje prekladac a na adrese 0x4 ma vyse nejaku slucku ci co …proste nechapem prikladam realizaciu prerusenia

void timer0interrupt (void)
{
if(INTERRUPT_ACTIVE(INT_TIMER0)) // Was this a timer overflow?
{
s=~s;
chybakomunikacie=1;
error=0;
CLEAR_INTERRUPT(INT_TIMER0);
}
}

[/code]
TAk ze ak niekto ma funkcnu rutinu pre prelladac PICC tak by som poprosil.

kdyz si otevres help a najdes si #INT_xxxx tak zjistis ze preruseni se pise #int_timer2 //timer0/timer1 void timer2interrupt() { }

ja blbec… ja som otvoril PDF od HItech compilera :blush:

Ahoj, nevím jak toto specifikovat do googlu.
Chci mezi sebu vynásobit 2 int čísla a výsledek by se mi měl uložit do proměnné long. Jenomže kompilátor C30 mi výsledek násobení ukládá jako int a horních 9 bitů výsledku zahodí.

unsigned int U_BAT;
unsigned long UBAT;
U_BAT = 740;

UBAT = U_BAT * 31439;

V MPLABu v okně Watch vidím, že mám UBAT reprezentován jako 32b registr, ale při vynásobení se naplní jen spodních 16b a zbytek se mi nikam neuloží a ztratí se.

Používám dsPIC33FJ16GS502
Děkuji

Možná by mohlo pomoct přetypování:

UBAT = (unsigned long)U_BAT * (unsigned long)31439;

no ,je to logicky , U_BAT je 8bit tak vysledek bude taky max 8bit
UBAT = (U_BAT * 31439); zapis to takle
U_BAT * 31439 -> vysledek se ti ulozi do U_BAT a ten pak do UBAT :bulb: