Nasiel som, preposielam
To je pěkné . Donedávna tam měli jen PICC s omezeními, tohle je pro domácí kutily bezva.
Já moc picy nemusim, třeba z důvodu tohohle, ale koukám že už dali freeware… sice oholenou verzi… dle mě v tom háček ale bude nějakej určitě
Snažej se dělat konkurenci atmelu, tak to dávaj free
Stejně dělám všechno v ASM a na tohle čučím jako vejr. Holt z vyšších jazyků snad BASIC, jinak mi to nic neříká.
Pěkně každej bitík a ne nějaké “void main(void)” - kdo tomu má rozumět, to asi nejde naučit samostudiem, jako můj oblíbený asm.
Vsechno jde, kdyz se chce a pro mcu stacej z C vpodstate jen zaklady.
To je sice pravda, jen kde ty základy vzít a najít si čas překousat se hromadou teorie.
PHP, WSH i JS jsem se učil za pochodu, skoušel jsem Wisual Basic i jiné dle knihy a nějak mi to nelezlo.
administrator: příspěvek byl upraven
Předchozí příspěvky se necitují.
Ale kolko casu na studium?
Vyzdvihuje sa tu, ze PIC ma malo instrukcii a tak sa lahko uci.
Podme to teda porovnat z najzakladnejsimi castami C, s ktorymi sa uz da urobit program. Budem mozno pouzivat obcas zvyklosti z GCC pre ATmega (velmi dobry procesor vo svojej triede )
ale budem sa snazit “nepreklepnut” sa
Ak sa ma nieco vykonat v C spolu v ramci jedneho bloku, tento je ohraniceny { } zatvorkami.
Z C staci pre zakladnu pracu vediet:
- komentare sa odclenuju znakmi:
// jednoriadkovy komentar
/*
viac riadkovy komentar. Pozor, viacriadkove komentare sa nedaju vnorovat
*/
1b)
#include
pomocou tohto zapisu prekladac vie, ze do programu ma na dane miesto vlozit uz existujuci subor, najcastejsie hlavickovy napr stdio.h
vyznam hlavickoveho suboru nemusis presne vediet, ale bude pre Teba
z neho dolezite vediet, co mas zapisat do programu, ak chces zmenit stav pinu procesora. Tato cast je pre kazdy prekladac individualna a s cistym C nema nic spolocne.
#define Ti umozni napr. miesto ciselnej konstatny v programe pouzivat jej “meno”, zatial nie je pre Teba nevyhnutne vediet, ale je to uzitocne
priklad
#define POCET_CYKLOV 10000
- prikazy
su zgrupovane do blokov a tie zase do funkcii. Kazdy program musi obsahovat prave jednu funkciu main(). Tou sa program vzdy zacina. Ten zapis pre procesor znamena iba tolko, ze TU ZACNI PROGRAM po RESTARTE.
Funkcii moze byt samozrejme viac a mozu sa navzajom volat, ale to pre uplneho zaciatocnika nie je podstatne.
V Tvojom C si pozri, ako sa maju nazyvat funkcie, ktore sa spustia ked pride k preruseniu - ak ho pouzivas, zatial experimentuj bez neho. Toto je tiez pre kazde C individualne a nema s cistym, C nic spolocne. Ak sa prechadza z jedneho kompilatora C na druhy, v tejto casti moze velmi pindat a treba sa mu prisposobit podla prislusnej dokumentacie
Nebudeme zatial riesit navratovu hodnotu funkcie, pokial zacnes programovat iba v ramci jednej funkcie main, zatial ta nemusi tato informacia trapit.
int main(void)
{
// v tomto bloku su potom jednotlive prikazy C
}
- datove typy
prekladac, ktory prelozi Tvoj text do instrukcii procesora musi vediet, ze ak chces pouzit premennu a, akeho typu tato premenna je. Teda, ci je jednobajtova, dvojbajtova, alebo viac. So znamienkom alebo bez, pripadne float (premenna vyjadrena v pohyblivej radovej ciarke)
to povies pri deklaracii premennych urcenim ich typu.
char a; // jednobajtova premenna (v 8bit jednocipoch, zatial sa implementacnymi rozdielmi na ine platformu nezatazuj)
int b, c, d; // dvojbajtova premenna so znamienkom (v 8bit jednocipoch, zatial sa implementacnymi rozdielmi na ine platformu nezatazuj)
char a[10] // pole s 10prvkami, pozor v C sa vzdy cisluju od nuly, takze k dispozicii mas prvky s indexami a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9])
typov moze byt viac, pre prvy funkcny program nie je nevyhnutne vediet
Samozrejma ako v ASM, i tu si musis davat pozor, aby si sa nesnazil narvat do jednobajtovej premennej dvojbajtovu. Slusne C Ta inak na to pri priamom priradeni bez pretypovania (zatial neskumaj) aspon upozorni.
Skratka na zaciatok nemiesaj hrusky s jablkami pokial sa to nenaucis.
- prikazy
3a)
zakladne matematicke prikazy
prikaz priradenia = a matematicke operacie +,- ,* /, &,|,~
& bitovy and
| bitovy or
~ bitova negacia
posun X o N bitov do lava X<<N; prikad 1<<7 je cislo 128
hodil som ich do jedneho vreca. Je ich viac (++;– i okolo ich inicializacie, ale zatial uplne staci toto
priklad:
int main(void)
{
int a, b, c;
a = 10;
b = 12;
c = a + b;
}
trochu k tomu patri i zapis cisel v roznych sustavach
a = 230; // vlozenie cisla 230 v dekadickom tvare do premennej a
a = 0x0a; // vlozenie cisla 10 v hexadecimalnom tvare
a = 0b01000001; // vlozenie cisla 65 v binarnom tvare
podmienka:
if(podmienka) {
// blok prikazov, ktore sa maju vykonat ak plati podmienka
// pre podmienku mozes pouzit >, <,>=,<=,
// == (zhodne, pozor nie iba = ), != (rozne), && (v inych jazykoch and),
// || (v inych jazykoch or)
// ! (negovana podmienka, nie bitovo, ale logicky)
}
priklad:
if (a > b) {
}
alebo aj:
if ((a <=b) && (c ==b)) {
}
else {
}
cyklus
uplne vystacis s cyklom while
a = 0
while (a < 100) {
a = a + 1;
// prikazy, ktore sa maju vykonat pri splneni podmienky
}
ale pre bloky, ktore sa maju opakovat vzdy presny pocet krat
mozes pouzit s takym istym vysledkom nasledovny zapis
for (a = 0; a < 100; a = a + 1) {
// prikazy, ktore sa maju vykonat v kazdom cykle
}
prikaz cyklu s podmienku while ma este svoj tvar s “do”, zatial nevyhnutne nepotrebujes, ale existuje
Dalej su tam switche, struktury, uniony, ukazatele, ternarny operator, prikaz skoku no skratka same uzitocne veci, ktore pre to, aby si zacal programovat v C nevyhnutne nepotrebujes, ale samostudiom napr. od Herouta alebo Kadleca, alebo niektoreho kurzu C z internetu pripadne inej knizky urcite casom nasajes.
Tak to zhrnme
#include
#define
// jednoriadkovy kmentar
/* viacriadkovy komentar */
hlavna funkcia:
int main(void) {}
deklaracia premennych:
char, int
matematicke operacie a priradenie:
=, +,-,*,/, &, |,~
podmienky pre riadenie zmeny chovania sa programu:
if(podmienka) {}
while(podmienka) {}
for(nastavenie, podmienka, cinnost pri prechode cez for) {}
napocital som 19 najzakladnejsich informacii.
Kam sa hrabe PIC s jeho 35 instrukciami?
Ako by vyzeral jednoduchy program “blikanie led”
je pisany pre GCC a ATmega32, neviem ako nazyva PICC svoje headre potrebne pre pracu s pinmi procesora.
Sa mi zda, ze blikanie LED je pre svet jednocipov nieco take, ako “Hello World” pre PC . Ale je to dobry priklad, lebu je tam priradenie, podmieneny cyklus, podmienene priradenie a praca s pinom procesora.
Vsetko na malom priestore a uz to “nieco” robi na rozdiel od toho “Hello World”, kde sa jedna o jednoduchy printf.
#include stdio.h
#include iom32.h
#define POCET_CYKLOV 10000
#define LED_NESVIETI 0
#define LED_SVIETI 1
#define PIN_PROCESORA_PRE_LED 0b0001000
int main(void)
{
char stav_led;
int pocitadlo;
// takyto zapis znamena, ze sa bude cyklus for donekonecna opakovat
for(; {
if (stav_led == LED_SVIETI) {
stav_led = LED_NESVIETI;
}
else {
stav_led = LED_SVIETI;
}
// slucka pre vytvorenie casoveho oneskorenia, ale led neblikala ako splasena
pocitadlo = POCET_CYKLOV;
while (pocitadlo > 0) {
pocitadlo = pocitadlo - 1; // da sa zapisat aj ako: pocitadlo--;
}
// nastavenie pinu procesora,
// rozhodol som sa pouzit bit 3 z portu C
// najprv nastavenie smeru pinu na vystup
// v DDRC bude pin 3 nastaveny na log.1
DDRC = DDRC | PIN_PROCESORA_PRE_LED;
// nastavenie stavu portu
if (stav_led > 0) {
// PORTC vyORje negovanou hodnotou PIN_PROCESORA_PRE_LED,
// to znamena, ze na mieste PIN_PROCESORA_PRE_LED bude log.1
PORTC = PORTC | PIN_PROCESORA_PRE_LED;
}
else {
// PORTC vyANDuje negovanou hodnotou PIN_PROCESORA_PRE_LED,
// to znamena, ze na mieste PIN_PROCESORA_PRE_LED bude log.0
PORTC = PORTC & ~PIN_PROCESORA_PRE_LED;
}
}
Pre jednoduche vysvetlenie programovania v C tento priklad myslim postaci.
Takze, ako uz bolo kde kade spomenute, nie je otazkou ci ASM alebo C, ale kedy to C. Jednoducha volba pri procesoroch, ktore nerobia instrukciu na 4 takty ale na 1-2 takty, a ktore za dobru cenu maju vela RAM a Flash. Ale i na PICoch sa to da.
Omluvam sa za zjednodusenia, ktore som hore uviedol, viem ze jazyk C je vyrazovo omnoho bohatsi a pestrejsi, ale snazil som sa priblizit laikom, ze pre jeho pouzivanie viac vediet nepotrebuju ako nevyhnutne minimum. To ze sa budu priebezne sami vzdelavat povazujem za samozrejmost.
Prosim preto nekamenujte ma, ale ak by ste mohli nieco doplnit a opravit v prospech zaciatocnikov, urobte to.
Martin
to samý jde bez problémů vytvořit v ASM… Akorát v Cčku je s tím víc práce, a navíc pokud program v C napíšeš jako prase, kompiler z toho pak udělá ještě větší prasárnu…
No ja musím Martinovi vrelo poďakovať za osvetlernie. Pokiaľ som ho vytočil a zpôsobil tým toto školenie, kľudne ho budem nasierať ďalej, len aby neprestal. V podstate všetko, až na ďalej uvedené body, už používam v JS, PHP, a dokonca i v tom ASM (DEFINE) a dosť dlho to používam (cykly for/next, if, datové typy a pod). Len som nevedel, že to takto funguje i v tom C-čku! Vždy, keď som začal niečo o tom “C” študovať tak sa autorom podarilo ma na prvých dvadsiatich stranách odstrašiť že som to zahodil a zanevrel na to. Vždy som, pri ASM premýšľal práve nad zložitými cyklami a podmienkami, ktoré sa mi tak dobre píšu v PHP alebo JS.
Čomu nerozumiem:
A) “int main(void)” - to “int” je niečo ako “function”? To “main” je len názov? A čo je to “void”?? Premenná, ktorou sa odovzdávajú funkcii parametre? Ako to prebieha?
B) include poznám a často používam. Len kde si vzal tie includované súbory? Kde to rastie? Ide o niečo podobné ako je definičný súbor (*.equ) do asm pre jednotlivé procesory? Tie vydáva microchip ku každému procesoru a stačí len zachovať ich “štábnu kultúru” a mám vystarané. Ako je to tu v tom C?
C) “pocitadlo”. odskok na “int pocitadlo” som asi pochopil, ale nenašiel som samotnú funkciu. Ak si ju len zabudol napísať, v poriadku, ale ak je to inak, prosím o vysvetlenie.
D) Ten “stav_led” ako premennú chápem, ale nešlo by to priamo meniť v porte? Ak si to dával takto zložito pre názornost tak je to OK, inak prosím vysvetliť.
E) To “PORTC” si vzal kde? To je v nejakom definičnom súbore? V tom includovanom??
Ja u svojich aplikácií (asi ako každý iný) pracujem s portami a jednotlivými bitmi, prípadne mením registre pre nejaký HW - ukladanie do EEPROM, PWM, A/D prevod a pod. Práve toto mi teraz (keď vidím, že s príkazmi a logikou už bežne robím) vŕta v hlave. Ale myslím, že by to šlo urobiť v ASM a includnúť na správne miesto. Uvažujem správne?
Ešte raz ďakujem za uvedenie do problému C.
Mohol by si kľudne napísať niečo ako školenie (základy), lebo to tvoje vysvetlenie ide viac po praxi ako po teórii, ktorú si v prípade potreby kľudne hocikto doštuduje. Myslím, že by ti tu na to radi dali dostatok priestoru (a ak nie, dám ti ho koľko chceš u mňa).
int je typ proměné… to sou právě ty prasečí jazyky jako je třeba PHP… Tam tě totiž typy proměnných zajímat nemusí… tady jo. int = integer (celé číslo + i -, rozshaz hlavy neznám)
void - já tomu říkám “nic”
CO je funkce předpokládám víš, parametry žádný nemá, proto tam to “void”. Návratová hodnota funkce je typu int.
Doporučuju prostudovat tohle: builder.cz/serial3.html a bude ti téměř všecko jasné… (mělo by), i když tutoriál neni zrovna podle mě jeden z nejlepších…
“int pocitadlo” znamena doslova promenny pocitadlo typu int. Proc by se na ni melo skakt? na promennou??
CO já vim, s PICy nedělám, ale třeba u AVR se stavy portů měnit dají přímo, pomocí instrukcí ASM.
PORTC - chápeš aspoň ten asm? Pak bys věděl že portC je prostě portC registr. Ovládá výstupy. v cčku do něj můžeš zapsat stylem třeba “PORTC = něco”
do toho cčka na začátek zdrojáku je logickly třeba includnout definiční soubor pro ten onen daný procík…
Doporučuju začít ASM, pořádně ho pochopit, a až pak to Cčko…
To Jan16:
Ano, ide to vytvoriť v ASM ale ak začneš robiť zložitejší prog začnú byť tie podmienky a matika značne neprehľadné. Tiež mám kopu vlastných rutín a používam ich, ale je to pracné a na dlhú dobu. Martin správne podotkol, že nie pre všeto sa “C” hodí a to samé (podľa mňa) platí i o ASM.
No a prasárnu vyrobí človek v akomkolvek prog jazyku, to nie je vlastnosť jazyka, ale človeka čo ho používa. Sebakriticky priznávam, že som vyrobil nejednu prasárnu.
A) int je datovy typ, pokud je pred jmenem funkce (zde main), pak to znamena, ze ta funkce vraci promennou typu int (cele cislo, rozsah zavisi na kompilatoru). Main je pouze nazev funkce, ovsem tato funkce musi byt v KAZDEM programu v C. Void je skutecne “nic”. V zavorce za nazvem funkce je soupis parametru, ktere ta funkce prebira (datovy typ + nazev promenne), zde void znamena, ze funkce zadne parametry neprebira. Void muzes pouzit i pred nazvem funkce, pak to znamena, ze funkce nic nevraci.
B)myslis si to spravne. jsou tam definovane konstanty, pojmenovane registry, ruzne funkce atd… napr. pokud budes chtit pouzivat matematicke funkce, budes potrebovat “math.h”. to “*.h” znamena hlavickovy soubor, ten ovsem primo dane funkce nenese, pouze jejich hlavicky. samotne funkce se nachazeji v souboru se stejnym nazvem ale priponou “.c”. Jeste jedna vec: funkce musi byt deklarovana VZDY drive, nez je pouzita. tzn. musi byt napr. zapsana pred funkci main, kdyz ji tam vyuzivas. Lze to take udelat tak, ze je tam pouze hlavicka a definice je potom niz (prekladaci hlavicka staci).
C) Zadny odskok na “pocitadlo” nevidim, kdyztak do dotazu vloz par okolnich radku, at vim V zapisu toho for je chybka - vlozilo to tam smajlika misto stredniku a zavorky, ale to jsi snad poznal - stejne jako php (ktere z C vychazi)
D) Jde to napsat jednoduseji na pohled, ale sloziteji na pochopeni, takze to bude spis pro nazornost
E) ano, “PORTC” je pojmenovana konstanta, zde nejspis v “iom32.h”. misto PORTC muzes psat jeho adresu (ktera se pod tim nazvem schovava), ale toto je prehlednejsi.
No ako učiteľa by som ťa veru asi nechcel, Jan16, iste o tom vieš hodne a ihneď ti je všetko jasné, to ovšem nie je môj prípad a to “int” mi hneď (ako začiatočníkovi v “C”) nedošlo. Predpokladal som, že v takomto príklade by sa dalo znázorniť aj použitie podprogramu. A “PORTC” v ASM mi je viac ako jasné a hlavne viem kde ho tam zoberiem, tu mi to z tohoto príkladu jasné nie je, tak som sa opýtal (inak je to typická “programátorská” otázka!). Vyvodiť s toho, že nerozumiem ASM sice môžeš, ale je to to samé ako ten môj odskok na premennú.
Ďakujem za vysvetlenie, ale dúfam, že Martin sa ozve. Neznalosť ešte neznamená hlúposť a po jeho odpovedi sa veru ako hlupák necítim…
Díky piityy, body A,C,D a E sú mi jasné (vrátane toho smajlíka), len v bode B mám trochu hokej a tuším, že tu príde na radu tá teoria, kde sa dozviem, čo vlastne všetko musím pred písaním samotného programu nadefinovať a aká je presne tá štábna kultúra.
Rozpísanie sa o tom bode B by bodlo, zdá sa mi to dosť neprehľadné - všelijaké tie includované súbory a čo v nich (a prečo) vlastne je…
Dnes už musím ísť do hajan, ráno vstávám na šichtu, ale těším sa na počteníčko a rady ako to “C” nainštalovať, naštartovať a vyrobiť v ňom hex súbor.
Dík predom.
nejsem naštvanej na tebe, ale mám dnesa už od rána blbou náladu… to proto, že sem vstával v 5 do školy, a eště to byl vopruz dneska (až na pár výjmečných hodin, jako FYZ, ANJ, MAT a podobně) > zejtra to už snad bude lepší
zejtra budu mít čas téměř celé odpoledne, tak ti s tím klidně helfnu, no problémo. Tady je hlavně problém, kdžy má nědo zažitý cosi jako php (skriptovací jazyk) a chce z toho přejít na klasiku programovací. V PHPčku je celá řada věcí, kterou kodér nemusí řešit (viz typy proměnných, optimalizace - no, i když), a u kontroléru je to nutnos mít všecko pod kontrolou. v PHPčku taky dělám jako amatér, a vím dobře co je to zač Programuju na kompu už hezkou hrstku let, a programovacích jazyků jsem stihnul vyzkoušet dost… od ASM pro 8051 (kontroléry, přes ASM x86 (PC), pascal, object pascal, freepascal (u toho se stále držím, suprový nástroj), dále se učím Cčko (ale pro kompy ), časem možná i pro AVRka, mimoto dělám občas v PhP, a jinak, jakousi základní znalost mám ještě v basicu, bashi, javascriptu. (možná bych vymyslel ještě něco, jenže o těhle mám jen jakousi “povrchovou znalost”.
C se sice ze začátku začátečníkům zdá lehké, ale pro pochopení je opravdu lepší ten ASM. Pokud ho máš kompletně zmáknutý, tak není problém přejít na něco “vyšího”. Problém je přejít z něčeho, co se podobá tomu novému. Tam se pak naseká plno chyb, protože je to sice podobné, ale ne stejné (např. zase to PHP vs. C).
Zatím brou noc, já du rači spát, abych zejtra vstal
DOřešíme to zítra, Honza
Jsme ve vlaknu microchipu, takze s tim ti moc vic nepomuzu, ty hlavickovy soubory se lisi podle prekladace. obcas delam neco s avr, s picC jsem nemel tu cest. Nicmene by ten prekladac mel mit dokumentaci, ve ktery bys mel potrebne veci najit.
Dal jsou obecne hlavickove soubory, ktere by mel mit kazdy prekladac podle ansi C (ale spolehat se na to neda, hlavne u mcu). jsou to naprikald stdio.h (vstup/vystup - napr. klavesnice, monitor - u mcu moc nevyuzijes), string.h (prace s retezci, mimochodem retezec v C neexistuje, pouze POLE ZNAKU a podle toho je treba s nim zachazet), math.h, stdlib.h (dynamické proměnné, náhodná čísla, řazení)…
Napr. pro praci s porty v avr staci jediny hlavickovy soubor - avrio.h a uz muzes vesele blikat a ruzny dalsi veci (definice pro konkretni mcu si avrstudio natahne samo, jakmile urcis, pro jakej mcu pises).
S picama ti zde zajiste pomuzou ostatni
Zdravim pani,
mam velku radost, ze moj prispevok podnietil taku bohatu a obsaznu haldu prispevkov. Myslim, ze tam odzneli vsetky odpovede na fiamove otazky. Urcite si ma nevytocil, ale sam som sa pred dvoma rokmi boril s podobnymi orazkami, tak to mam este trochu v hlave, tak pokial to nevyfuci, rad sa podelim.
K tomu bodu B pojdem trochu obklukou, preco C a preco treba potom niektore veci riesit zdanlivo skrabanim sa okolo celej hlavy ale stoji to zato.
Kazdy program, ktory sa da napisat v C sa da napisat aj v ASM. Kazdy program napisany vo VisualC++ sa da napisat aj v ASM. Je to preto, lebo text obsahujuci kod lubovolneho vyssieho programovacieho jazyka v konecnom dosledku prekladac (vynecham teraz interpretery pseudokodov, ktore su tiez velmi uzitocne, ale teraz nie…) prelozi do strojoveho kodu toho ktoreho jazyka a ten sa samozrejme da naspat prelozit do ASM daneho procesora.
Je ale v celku jasne, ze pre velmi vela uloh je to velmi neprakticke (zlozito udrzovatelny kod, velka spotreba priestoru pre abstraktne modelovanie v programatorovej hlave, atd.) a casovo velmi velmi narocne. Da sa to, mnohi namietnu, ze oni tak predsa robia a nemaju s vlastnymi programami problem a to ani po rokoch, skratka sw geroji v tom najlepsom slova zmysle, mam ich v ucte. Problem nastane pri udrzvani kodu v skupine a pri vacsom casovom odstupe.
Zapis vo vyssom programovacom jazyku je omhoho hutnejsi, zaberie menej riadkov na monitore a v dosledku toho je lahsie vizualne pochopitelnejsi (samozrejme pri znalosti jazyka a standartnom zapise zdrojaku), i chyby sa v nom odhaluju v dosledku vacsej prehladnosti rychlejsie.
Vyssi programovaci jazyk ma tu vyhodu, ze kopec prace za programatora odmaka prekladac, ktory programatorove literarne dielko cele precita, snazi sa mu porozumiet (na rozdiel od ineho publika v podobe kolegu, ci chapavej manzelky) a ak niecomu nerozumie, alebo ak narazi na uplny nezmysel, da to znat cez warningy a errory. Za to vsak treba zaplatit cenu v podobe dlhsieho (2-3x) a pomalsieho kodu (asi 2-3x) oproti vysledku od programatorskeho odbornika. Mam skusenosti na 8 bitoch len s ASM, ICC a GCC pre AVR a ASM pre PIC16, tak z nich vychadzam.
Vyrobcovia procesorov s tym pocitaju a ponukaju nam v coraz nizsej cene rychlejsie a pamatovo vybavenejsie procesory. Dokonca samotne jadra (AVR, PIC24, ale nie len tie) navrhuju tak, aby sa dal napisat efektivny prekladac z vyssieho jazyka do ASM daneho procesora.
Ak vam v PC nejaky progam ide pomaly, nie je snaha o optimalizovanie kodu, ale o dokupenie pamati, pripadne rychlejsieho procesora. Nad tym sa nikto nepozastavuje a je to v dnesnej dobe normalne. Robte tak aj s jednocipmi. Takyto pristup sa vam odmeni v podobe vacsieho mnozstva sikovnych a uzitocnych aplikacii, ktorymi potesite seba i svojich blizkych (aj sef sa da za urcitych velmi specifickych okolnosti povazovat za blizkeho, obcas i tretieho druhu).
Ine pochopenie bude mat pre vas konicek priatelka, pripadne jej upgrane na manzelu ak z pod vasich ruk bude kazdu chvilu vychadzat nova uzitocna aplikacia pre vase okolie, ako ked budete napr. 1/2 roka riesit zapis z/do FAT16 v ASM MMC karty.
Teraz sa niektori mozu ozvat, ze sa to vzdy neda, ze to C je pomale a ze im nestiha a ze sa aplikacia nevlezie do pamate a preto treba furt pouzivat ASM a najlepsie je treba nim zacat, lebo bez jeho dokladnej znalosti sa neda dobre pochopit co sa v procesore deje atd atd (Hlavne to posledne nie je pravda. Kazda znalost je samozrejme dobra a nezatracujem ju, ale ASM fakt nie je potrebne ovladat pre plne vyuzitie vlastnosti procesora. Co je treba ovladat a to velmi dobre, je architektura procesora. Do ktoreho registra mam co kedy zapisat, a co si mam kedy odkial nacitat. To ano. Ved kolko programatorov neovlada ASM PC-cka a aj tak vedia programovat aplikacie vyuzivajuce LPT ci UART?).
Su aplikacie, kde na vykone velmi velmi zalezi a neda/nechce sa pouzit vykonnejsi procesor. Ale ruku na srdce, kolko je takych? Robim aplikacie do priemyslu a zistil som, ze sa mi procesor 70% casu flaka (cakacie cykly) a to sa jedna uz o celkom rozsiahly riadiaci viacokruhovy program s PIDmi, archivaciou , komunikaciou i vratane obsluhy LCD displaya a klavesnice. A to je program napisany v C.
Ak treba niekde naozaj ASM (a urcite ze ano), spravme anketu, kolko percent statisticky na take aplikacie pripada. Sam som zvedany.
Ak sa zda program v C 3x pomalsi ako ASM, pouzite procesor, ktory nema instrukciu na 4 takty ale na menej (AVR, PIC24, …). Ak program v C je 2-3x vacsi pouzite procesor nie s 8kB Flash, ale s 32kB, pripadne 128kB. cenovy rozdiel je zanedbatelny, najma voci usetrenemu casu. Len uvediem z mojej oblasti: ATmega128 stoji 120,-Kc s danou pri kusovom mnozstve
ATmega644P (64kB flash/4kB RAM) v DIP puzdre 130,-Kc s danou, ATmega32 dokonca 90,-Kc (TME). Urcite sa najdu aj vhodne cenovo dostupne PICka.
Ako najzakladnejsi programovaci vyssi jazyk bol vybrany jazyk C nie pre preferovanie nejakym nadnarodnym monopolom, ale preto, ze najviac vyhovuje potrebam programatora, ktory potrebuje programovat rychle, svieze lahko modifikovatelne aplikacie, ktore maju co do cinenia i s HW zariadenia a hlavne mozu byt prenositelne medzi roznymi platformami, aby sa investicie (casovo finance) mohli lepsie vyuzit. Jazyk C bol navrhovany programatormi a pre programatorov. Pre prehladnost vyuziva strukturovane programovacie techniky, ale pri znacnej miere abstrakcie sa vie “logicky” dostat na hw zariadenia. To vedia i ine jazyky, napr Modula, BASIC (BASCOM), PASCAL (uPASCAL), ale C presiel pre tieto aplikacie ohnom prirodzeneho vyberu ako majoritny vitaz.
Preco C a nie Basic, alebo Pascal?
Lebo to su sice vyssie programovacie jazyky vyuzivajuce strukturovane programovacie techniky (i s preklinanym a zaroven vela krat oslavovanym prikazom GOTO [je aj v C ]), ale neobsahuju vo svojej kodifikacii (mozno niekto spravil nejaky ulet od normy, vylucit sa to neda) take konstrukcie, ktore umoznia prekladacu spravit vysledny kod co najefektivnejsi. V mojom pojednani o “zakladoch najzakladnejsich” pre pouzitie jazyka C som ich spomenul velmi velmi okrajovo a keby ich C nemalo, nebol by dovod pouzivat C miesto BASICa alebo PASCALu.
Jedna sa predovsektym o ukazatele, ktore z jazyka C robia mocny nastroj na generovanie uspornejsieho a efektivnejsieho kodu. Ked si tak spomeniem na pole ukazatelov na funkcie vracajuce ukazatele na polia premennych - efektivne, rychle, prehladne.
Ak vsak niekto ukazatele v programe pouzije prasacim sposobom, bude hladat chyby omnoho dlhsie, ako keby celu aplikaciu napisal v ASM.
Ukazatelov sa vsak nie je najmensi dovod dopredu sa obavat. Je to bezpecne asi ako pouzivat doma plynovy sporak. A vysledky su naozaj pekne. Samozrejme v ramci moznosti prekladaca, kod nebude nikdy tak maly a rychly, ako keby ho v ASM pisal programatorsky genius. Ja taky genius urcite nie som a nazdavam sa, ze to, co vygeneruje do ASM moj prekladac celkovo z niekolkych stovak az tisicok riadkov je rychlejsie a efektivnejsie, ako by som to napisal v ASM ja a este k tomu za mnohonasobne dlhsiu dobu. Na to nemam cas a ani to nie je moj konicek (pisat a odladovat nieco velmi dlhu dobu, nie programovat )
No a teraz navrat oblukom k bodu B. (konecne )
C je jazyk abstraktny, nezviazany so ziadnou konkretnou hw platformou.
Aby sa dal prelozit zdrojovy kod pre dany procesor, musi byt k dispozii k nemu vhodny prekladac.
A tak aby sa dal vobec pouzit, treba prekladacu vediet povedat, ako ma pristupovat k HW konkretneho procesora.
Prekladac sa tak zvacsa distribuuje ako balik suborov, kde okrem samotneho prekladaca obsahuje aj subory, v ktorych su definicie adries jednotlivych portov a inych periferii pre ten ktory procesor.
Tieto subory treba do samotneho programu (jeho zdrojoveho textu) vlozit
pomocou direktivy #include
V mojom pripade su to zo suboru iom32.h potrebne riadky:
/* Port C */
#define PINC _SFR_IO8(0x13)
#define DDRC _SFR_IO8(0x14)
#define PORTC _SFR_IO8(0x15)
tu su definovane fyzicke adresy portov.
Mohol by som ich tam jednoducho vpisat, ale pouzit riadok
#include “iom32.h”
je rychlejsie, pohodlnejsie a ak budem rozsirovat o funkcionalitu na dalsich pinoch inych portov, nemusim uz vkladat jednotlive #define, lebo prekladac uz vie, kde si ma co hladat.
V mojom pripade ma subor iom32.h 690 riadkov, tak takyto sposob je prehladnejsi. Nemusim rozumiet jeho obsahu, staci ze poznam nazvy mojich portov a o ostatne sa postara prekladac. Subor sa nazyva hlavickovy podla mojho nazoru preto, lebo sa takyto typ suboru sa vklada na zaciatok zdrojoveho kodu, teda kvazi do jeho hlavicky. Preto ten nazov *.h. Kludne by mohol mat priponu *.xyz, ale takto sa to pre prehladnost zauzivalo, tak ako subory so zdrojovymi kodmi C maju priponu *.c a textove subory *.txt alebo *.doc
pre iny prekladac a procesor sa bude prislusny subor bude volat inak, ale princip bude rovnaky.
Cast zapisu :
_SFR_IO8(0x13)
je zrozumitelna prekladacu GCC a ten vie, ze ma do vysledeho kodu vlozit adresu 0x13.
ICC uz to moze mat zapisane inak. Programatora to vsak trapit nemusi, len musi do programu spravit #include vhodneho suboru (dozvies sa z popisu prekladaca (kto by to cital ), ale najrychlejie je pozriet si nejaky vzorovy priklad dodany k prekladacu a robit to podla vzoru)
Takisto treba prekladacu povedat, aka velka je premenna s ktorou chces pracovat. Su jazyky, kde sa rozsah premennej nezadava, lebo je implicitne nastaveny na nejaku velku hodnotu. V PC zabera taka premenna niekolko bajtov. Tam je to lautr jedno, lebo PC aj tak spracovava naraz 4 pripadne 8 bajtov. Tak je vhodne, aby zakladna premenna mala takuto velkost. Pamate je dost.
V malych procesoroch je vsak miesto velmi dolezite, nevraviac o tom, ze ak chcem spravit pocitadlo cyklov a rezervoval by som na to premennu zaberajucu 4 bajty, okrem mnozstva pamate velmi spomalym bez programu, lebo tomu nestaci pouzit jednu instrukciu na dekrement bajtu, ale musi skontrolovat hodnotu vsetkych 4 bajtov.
Preto je vhodne urcit si, aku pamat ma ta ktora premenna zaberat. Okrem toho treba prekadacu povedat, ci ma mat premenna znamienko, alebo nie.
Iny vysledok bude pri spocitani cisel
-123 + 10
a pri spocitani
133 + 10
pritom 133 a -123 maju rovnaky binarny tvar vyjadreny v 8bitovom rozliseni (ak som to v rychlosti dobre spocital, ak nie opravte ma prosim)
preto treba povedat
int premenna;
char stav_led;
nejedna sa o skoky, jedna sa len o deklaraciu premennych, aby prekladac pre tieto premenne v pamati vytvoril prislusne miesto a vedel, ako ma s nimi narabat (t.j. aky asm kod ma vytvorit pre vyrazy, kde sa tieto premenne vyskytuju) v programe.
da sa to este zapisat ako
int premenna = 1000;
a to znamena presne to iste co predtym, len prvy krat po spusteni programu sa do premennej vlozi hodnota 1000. Schvalne teraz nepisem nic o lokalnych premennych, static, volatile, atd, lebo na to je ucebnica, ktoru nahradit nemozem a ani nechcem a pre jednoduchy zaciatok v C to v tomto rozsahu ani netreba vediet (ale casom urcite !!!)
funkcia musi mat v zdrojovom texte za sebou este zatvorky. Tak ju v zdrojaku poznas a podla toho ju pozna i prekladac.
funkcie v C maju taku vlastnost, ze ak ich zavolas, mozes do nich preniest ziaden, jeden, dva alebo i viac parametrov.
Funkcie v C mozu ako vysledok svojej cinnosti vratit do funkcie z ktorej bola volana ziadnu, alebo jednu premennu.
Ak sa jedna o ziadny parameter, prekladacu to treba dat nejak najavo, aby si on bol isty, ze programator parameter jednoducho nezabudol napisat. Pouziva s ak tomu slovo void, lebo nieco tam zapisat treba.
Ak nie je void, potom sa napise typ prenasanej premennej. Typy premennych sa pisu iba pri definicii, pripadne deklaracii funkcii. Tu uz by som velmi nerad zacal suplovat ucebnice C-cka, lebo v nich je to vysvetlene velmi dobre a aj s prikladmi.
takze este na zaver mensi napriklad funkcii (viem, ze je velmi jednoducha az to vedie k pochybnosti o jej zmysle, ale jej zmysel je cisto didakticky, ako to pouzitie a nastavovanie premennej stav_led v predchadzajucom prispevku):
#include “stdio.h”
#include “iom32.h”
#define PIN_PRE_LED 0b00000100
// funkcia spocita dve cisla a vrati ich vysledok
int sucet(int x, int y)
{
return(x + y);
}
// funkcia rozsvieti LED, ak je z > 1000
void ovladanie_led(int z)
{
DDRC = PIN_PRE_LED;
if (z > 1000) {
PORTC = PIN_PRE_LED;
}
else {
PORTC = 0;
}
// kedze je navratova hodnota void, nevracia sa ziadna hodnota
return;
}
int main(void)
{
int a = 0, b = 10000, c;
for(; {
a++;
b = b - a;
c = sucet(a,b);
ovladanie_led©;
}
}
Da sa to cele zapisat C-ckarski jednoduchsie, ale toto som zvolil kvoli nazornosti - dufam, ze vhodne. V kazdom pripade treba po prvom rozblikani LED siahnut po najblizsej ucebnici C. Taketo popisy v konferencii ju nemozu nahradit.
Preco su v definicii funkcie sucet() uvedene premenne x a y a vo funkcii main() zrazu a a b, sa dozvies prave tam.
Zaverom si myslim, ze aj predchadzajuci prispievatelia casto velmi dobre zodpovedali fiamove otazky. Len si ich je mozno treba viac krat precitat a ujasnit. Viem ze to na prvy krat nie je jednoduche. Sam som tym presiel, a obcas trvalo kym som pochopil dnes uz pre mna trivialnu vec, trivialne mi vysvetlovanu. Namaha sa vsak iste vyplati.
Ak nejakou castou mojho textu v niekom vzbudim pohorsenie, dopredu sa omluvam, nie je to mojim zamerom.
Martin
No perfektné, páni Martin a piityy. Ďakujem, máte u mńa štamprdla .
Študujem i odkaz, ktorý sem dal Jan16 a zisťujem, že vlastne prevážnu väčšinu príkazov a konštrukcií poznám z PHP, JS a WSH. Sú to “len” skriptovacie jazyky, ale PHP má vlastne všetko z C, JS je zase prísny na syntax podobne ako WSH.
Musím tu pripomenúť, že príklon ku akejkoľvek činnosti má obvykle na svedomí práve učiteľ (to môže byť i autor knihy, inet kurzu apod). Napríklad ku PICom som sa dostal vlastne cez ATMELy. To som niečo chcel riešiť cez nejaký kontrolér a kúpil som si knihu (fakt neviem akú a kde ju mám) základov o 8051 a nejako som ju asi nepochopil, zdalo sa mi to hrozne zložité, odpálil som svoj prvý procesor a znechutene som to odložil. Potom sa mi dostala do ruky kniha o PIC a zrazu sa mi začalo rozsvecovať v hlave a čo viac: rozbehla sa prvá aplikácia (samozrejme nejaký vianočný blikač ) no a už som pri tých PICoch zostal. Možno sa od tej doby (1997) ATMEL zlepšil a možno aj microchip predbehol, ale všetko, čo chcem (HW) nájdem na stránkách microchipu a potrebujem minimum vonkajších súčiastok. V asm mi akurát pri zložitejších aplikáciach (roku 99 som si urobil dialkové ovládanie kúrenia vo firme cez mobil - ešte sa to váľa niekde v šuplíku) vadili tie dosť zložité konštrukcie a nemožnosť použiť vyšší jazyk - kompilátory boli len platené.
No a dnes sa situácia opakuje. Objavil sa volný prekladač z C a že to C v tom rozsahu, čo budem potrebovať, mi je hodne povedomé mi krásne ukázal MARTIN, piityy a David Růžička.
Dovolím si, pripomenúť Vám, že síce viem (jakž-takž) cykly, podmienky, polia, funkcie, rozumiem i #include a #define, ale stále neviem ako to všetko použiť práve pri programovaní PIC. A možno len nie som si istý a plaším sa zbytočne (práve inštalujem to voľné C do MPLABu a objednal som si ten 32 bitový kit) a bude stačiť ak si to rukami skúsim tak ako som kedysi začal s asm…
Čo mi teda nie je jasné, alebo nie som si istý správnym pochopením:
void ovladanie_led(int z)
{
DDRC = PIN_PRE_LED;
if (z > 1000) {
PORTC = PIN_PRE_LED;
}
To DDRC je asi v nejakom includovanom súbore definované ako register pre nastavenie portu C na vstup, alebo výstup a posielaš na neho takto dekadickú štvorku (binárne 00000100) čím nastavíš ten pin ako výstupný. Vzápätí ten pin (PORTC2)zapneš príkazom "PORTC = PIN_PRE_LED; ". Samozrejme len za podmienky že “z” je vačšie ako 1000.
Ide vlastne o podobné includovanie ako v asm, kde som prilinkoval súbor PICxxxx.inc a tieto veci tam boli definované od výrobcu čipu. Vydával ku každému konkrétnemu čipu jeden súbor. Predpokladám, že i u tohoto “C” to bude podobné, ak nie, prosím o vysvetlenie kde to vezmem napríklad pre PIC32MX360F512L. Ako som vyššie napísal, objednal som si PIC32MX starter kit a hneď ako dôjde ho zapíchnem do compu. Dovtedy chcem trénovať nasucho .
Nerobim sice s PICmi, ale urcite ten definicny subor pre kazdy typ procesoru bude v nejakom vhodnom adresari. Pozri si nejake vzorove programy, ktore su zvycajne pribalene pri kazdom prekladaci. Predpokladam ze kuknes a budes vidiet/vediet. Drzim palce.
Martin
Pochybuji že by uvolnili překladač pro řadu PIC32, tak maximálně pro řadu PIC10, 12, 16.
Takže asi definiční soubor pro PIC32 tam nenajdeš.