MIKROPROCESORY PRO VÝKONOVÉ SYSTÉMY Stručný úvod do programování v jazyce C 2.díl České vysoké učení technické Fakulta elektrotechnická A1B14MIS Mikroprocesory pro výkonové systémy 07 Ver.1.10 J. Zděnek, 20171
Programovací jazyk C - proměnné Proměnné: Pro realizaci určitého algoritmu potřebujeme nejen příkazy pro určení cesty výpočtu ale i data, která algoritmus zpracovává. Datům která se mohou měnit během realizace algoritmu se nezívají proměnné. Obyčejné proměnné které neovládají žádný hardware leží v paměti dat mikropočítače, programátor těmto proměnným zvolí symbolická jména a linker (na základě linker skriptu) sám zvolí místo kde budou proměnné v paměti dat uloženy. Programátor pak proměnné osloví pouze jejich symbolickým jménem Pro volbu symbolických jmen platí jednoduchá pravidla: Jméno proměnné se smí skládat z velkých a malých písmen, číslic a podtržítka ( _ ). Jméno proměnné nesmí začínat číslicí Pro každou proměnnou musí programátor udat její typ tj. jaké hodnoty do proměnné budou ukládány Proměnnou nutno nejdříve deklarovat (tj. zvolit její jméno a typ), teprve pak ji lze použít pro uložení dat. A1B14MIS Mikroprocesory pro výkonové systémy 07 2
Programovací jazyk C - proměnné Proměnné: Typ proměnné: nejčastěji používané typy proměnných: int pro celáčísla se znaménkem unsigned int (nebo stačí unsigned) pro celá čísla kladná double pro čísla racionální (necelá) Viz příklady deklarace a použití na dalších snímcích Doba života je další důležitou vlastností proměnných tj. zda existují po celou dobu běhu programu (jsou statické) nebo existují jen po dobu běhu programu danou funkcí (nebo vnitřním blokem funkce) říká se jim automatické. Statické proměnné: lze deklarovat tak aby deklarace ležela mimo všechny funkce, např. int prumerkruhu Nebo na začátku funkce nebo bloku doplněním typu o slovo static např. static int stavreseni A1B14MIS Mikroprocesory pro výkonové systémy 07 3
Proměnné: Programovací jazyk C - proměnné Doba života (pokračování): Automatické proměnné: lze deklarovat na začátku funkce nebo bloku bez slova static. Existují jen po dobu běhu funkce a vždy při dalším běhu se zakládají znovu (leží na zásobníku). Nelze tedy v těchto proměnných uchovat hodnotu mezi jednotlivým volám funkce. Formální parametry: stejné pravidlo jako pro automatické proměnné (tj. deklarované na začátku funkce nebo bloku) platí pro formální parametry funkce (tj. pro parametry v kulatých závorkách hlavičky funkce). Formální parametry se při volání funkce zakládají vždy znovu a kopíruje se do nich skutečná hodnota uvedená v daném volání funkce. A1B14MIS Mikroprocesory pro výkonové systémy 07 4
Proměnné: Programovací jazyk C - proměnné Viditelnost proměnných: vlastnost proměnné, kteráříká z jakéčásti programu jsou dané proměnné známé (viditelné). Globální proměnné: jsou viditelné z libovolné části programu. Globální proměnné se zakládají mimo všechny funkce a jsou zároveň statické. Pokud má být globální proměnná známá v jiném souboru programu (pokud je program členěný do více souborů) než je deklarována, tak v tomto souboru musí být označena slovem extern tedy extern int x Lokální proměnné: jsou viditelné pouze v bloku kde jsou deklarovány. Mezi lokální proměnné patří statické deklarované na začátku bloku (např. static int x) a automatické proměnné. Všechny dosud uvedené druhy proměnných musí být deklarovány před vlastním překladem kompilátorem. Existují ještě proměnné, které lze vyžádat při běhu programu, těm se říká dynamické. Těmi se zatím nebudeme zabývat. A1B14MIS Mikroprocesory pro výkonové systémy 07 5
Proměnné: Programovací jazyk C - proměnné Volba jmen proměnných: Pokud programátor dodrží pravidla o povolených znacích ve jménu proměnných je volba jména na něm. Dohoda o volbě jmen proměnných - je vhodné dodržovat dohodu mezi programátory a jméno volit mnemotechnicky (tedy tak, aby se ze jména poznalo jakých dat se obsah proměnné týká podstatně to zvyšuje čitelnost programu). Jedna často dodržovaná dohoda je shodná s volbou jmen funkcí. Tedy první mnemotechnickáčást jména začíná malým písmenem a každá další velkým. Např: prumerosykola. Zcela nevhodná volba jmen proměnných: Např. x1, x2, x3, y104, w, a, pokus, něco, nazdar atp. A1B14MIS Mikroprocesory pro výkonové systémy 07 6
Programovací jazyk C statické proměnné Statické proměnné známé v celém programu (globální) Statické proměnné známé jen uvnitř funkce (bloku)(lokální), zde v main A1B14MIS Mikroprocesory pro výkonové systémy 07 7
Programovací jazyk C viditelnost proměnných (visibility) Viditelné (známé) v celém programu (globální) Vidilelné (známé) jen ve funkci (bloku), kde jsou deklarovány) (lokální), zde v main A1B14MIS Mikroprocesory pro výkonové systémy 07 8
Programovací jazyk C automatické proměnné a formální parametry Automatické proměnné se zakládají při každém volání fce znovu a na konci fce zanikají Formální parametry se zakládají při každém volání fce znovu a na konci fce zanikají A1B14MIS Mikroprocesory pro výkonové systémy 07 9
Programovací jazyk C viditelnost proměnných (visibility) Viditelné (známé) pouze uvnitř funkce (bloku), jsou lokální Viditelné (známé) pouze uvnitř funkce (bloku), jsou lokální A1B14MIS Mikroprocesory pro výkonové systémy 07 10
Programovací jazyk C proměnné KRITICKÁ POZNÁMKA Proměnné: Správný programátorský přístup skrývá výpočetní proměnné funkcí před neautorizovaným přístupem z dalších funkcí (např. chybou programátora), tak aby výpočet nebyl zkreslen (použitím automatických proměnných). Dále pro předávání parametrů do funkcí používá formální a skutečné parametry. Výše řečené však NEPLATÍ pro v laboratoři použitý mikrokontrolér PIC18F87J11. Proč? Automatické proměnné (tj.lokální) a formální parametry se zakládají (a ruší) na zásobníku (stack). Platforma PIC18 má speciální zásobník s rychlým přístupem (tzv. hardware stack), ale zásobník je poměrně málo hluboký (31 položek). Pokud se kompilátor domnívá, že by mohlo dojít k přetečení zásobníku (a havárii programu) vloží automaticky dodatečný kód (ten programátor nevidí), který přesune obsah zásobníku do hlavní paměti a pak teprve zavolá funkci a na konci funkce přesune vše zpět. Program pak z logického pohledu pracuje správně, přesun zásobníku ale trvá nějaký dodatečný čas a velmi zpomalí např. reakci na žádost o přerušení. Co z toho plyne pro nás? Používejte globální nebo statické proměnné, které se nevytvářejí na zásobníku. Nepoužívejte automatické (lokální) proměnné a omezte použití formálních parametrů. A1B14MIS Mikroprocesory pro výkonové systémy 07 11
Programovací jazyk C - konstanty Konstanty: Číselné: 12 (desítková), 0xF4 (šestnáctková), 345.76 (reálná) 0b11001001 (binární) specialita našeho překladače Symbolické: #define UHEL_ALFA 456 Nekončí středníkem, je zvykem jméno psát velkými písmeny a mnemotechnické části oddělovat podtržítkem Výčtové: enum {FALSE, TRUE}; enum {ALFA, BETA, GAMA, DELTA} Symbolickým jménům se přiřazují celáčísla počínaje nulou. Tedy pozor FALSE musí být v enum první, aby se přiřadila nula (což v C znamená false) a true pak druhé, tomu se přířadí jedna což v C znamená true (tedy něco jiného než nula) Řetězcové (literál): Těmi se zatím nebudeme zabývat. Např. Nazdar V C nemají speciální proměnnou, nutno použit pole A1B14MIS Mikroprocesory pro výkonové systémy 07 12
Programovací jazyk C konstanty Symbolická konstanta Výčtová konstanta Binární konstanta A1B14MIS Mikroprocesory pro výkonové systémy 07 13
Výraz: Programovací jazyk C - výraz Výraz je programová konstrukce pro výpočet hodnoty Může se skládat z: Proměnných Konstant Operátorů (aritmetických, logických, bitových) Dvojic kulatých závorek (pro označení priority částí výpočtu) Dvojic kulatých závorek může být více dle potřeby Používejte kulaté závorky pro označení priority výpočtu, pak není třeba znát (a učit se) jakou vzájemnou prioritu mají operátory. Příklady výrazů: (x / y) * 3.14 // deleni a nasobeni z w r >> 8 // logicke OR // bitovy operator posunu vpravo A1B14MIS Mikroprocesory pro výkonové systémy 07 14
Příkaz přiřazení : Programovací jazyk C příkaz přiřazení Příkaz přiřazení (přiřazovací příkaz) používá znak = Přiřazuje hodnotu vypočtenou na pravé straně znaku = do proměnné uvedené na levé straně Na levé straně musí být proměnná reprezentovaná pozicí v paměti dat. Často se říká, že na levé straně musí být tzv. lvalue neboli location value což značí, že to musí být proměnná. Pokud je na pravé i levé straně shodná proměnná, tak se nejprve vypočítá výraz na pravé straně do dočasné proměnné (tu programátor nevidí) s použití původní hodnoty a pak se teprve nová hodnota přiřadí na levou stranu. Příklady přiřazení: x = (x / y) * 3.14 // x je na obou stranách =, to je ok u = z w m = r >> 8 A1B14MIS Mikroprocesory pro výkonové systémy 07 15
Programovací jazyk C operátory Operatory (výběr): Aritmetické: +, -, *, /, % / dělení. Pozor pokud jsou obě hodnoty okolo / celočíselné jedná se o celočíselné dělení (např. 2 / 3 = 0), pokud je alespoň jedna hodnota okolo / reálná jedná se o běžné dělení. % zbytek po dělení (např. 5 % 3 = 2). Logické:! - logické NOT. (Pozor!0 = 1;!234 = 0, atp.) - logické OR (např. 0 45 = 1) && - logické AND (např. 33 && 45 = 1)!= - logické XOR (např. 33!= 45 = 1) A1B14MIS Mikroprocesory pro výkonové systémy 07 16
Programovací jazyk C operátory aritmetické Celočíselné dělení Zbytek po dělení Normální dělení A1B14MIS Mikroprocesory pro výkonové systémy 07 17
Programovací jazyk C operátory logické Program jde sem Program jde sem Program jde sem Program jde sem A1B14MIS Mikroprocesory pro výkonové systémy 07 18
Programovací jazyk C operátory (pokračování) Operatory (výběr): Bitové: ~ (vlnovka) bitové NOT (Např. ~0xFF00 = 0x00FF atp.) - bitové OR (např. 0xFF00 0x00FF = 0xFFFF) & bitové AND (např. 0xFF00 & 0x 0x00FF = 0x0000) ^ (stříška) bitové XOR (např. 0xFF00 ^ 0xFFFF = 0x00FF) >> bitový posun vpravo (logický nikoliv aritmetický) (0x00FF >> 4 = 0x000F) << bitový posun vlevo (např. 0x00FF << 8 = 0xFF00) A1B14MIS Mikroprocesory pro výkonové systémy 07 19
Programovací jazyk C operátory bitové Bitové NOT Bitové OR Bitové AND Bitové XOR Bitový posun vpravo Bitový posun vlevo A1B14MIS Mikroprocesory pro výkonové systémy 07 20
Programovací jazyk C operátory (pokračování) Operatory (výběr): Relační (porovnávací): == rovná se (např. 75 == 75 = 1)!= nerovná se (např. 21!= 13 = 1) > větší než (např. 27 > 21 = 1) >= větší nebo rovno (34 >= 34 = 1) < menšíí než (14 < 23 = 1) <= menší nebo rovno (57 <= 57 = 1) A1B14MIS Mikroprocesory pro výkonové systémy 07 21
Programovací jazyk C operátory relační Program jde sem Program jde sem Program jde sem Program jde sem Program jde sem A1B14MIS Mikroprocesory pro výkonové systémy 07 22
Programovací jazyk C ovládání hardware PIC18F87J11 Ovládání (programování) hardware PIC18F87J11 z pohledu C je velmi jednoduché. Každý blok hardware má určitý počet ovládacích a stavových registrů Všechny registry jsou osmibitové Každý registr má jméno, některé registry lze programovat jednotlivě po bitech, pak i každý bit má svoje jméno. Jména registrů i bitů jsou uvedena v dokumentaci PIC18FJ87J11 Family Data Sheet. Číslo dokumentace je DS39778. Dokumentaci najdete na webu předmětu MIS nebo na webové stránce firmy Microchip. Aby bylo možné z C adresovat ovládací registry jejich jmény z dokumentace, je nutné dodefinovat do C určité proměnné. To učinil výrobce software (Microchip) a definice uložil do hlavičkového souboru p18f87j11.h, který je třeba do našeho programu zatáhnout příkazem #include (viz příklady v této presentaci). Dodefinované proměnné jsou typu struktura a union. Adresování ovládacích registrů používá metodu Namapování registrů do paměti dat (Memory Mapped Input/Output), pak se registry osloví (jejich jménem z dokumentace) jako každá jiná obyčejná proměnná (která neovládá žádný hardware) A1B14MIS Mikroprocesory pro výkonové systémy 07 23
Programovací jazyk C ovládání hardware PIC18F87J11 Ukázka dodefinování jmen ovládacích registrů dle dokumentace. Programátor nic v souboru p18f87j11 nemění, pouze ho zatáhne do svého programu příkazem #include. Ukázka níže zahrnuje dodefinování jmen ovládacího registru časovače 0 a jeho bitů.. A1B14MIS Mikroprocesory pro výkonové systémy 07 24
Programovací jazyk C ovládání hardware PIC18F87J11 A1B14MIS Mikroprocesory pro výkonové systémy 07 25
Programovací jazyk C ovládání hardware PIC18F87J11 Nastavení všech bitů ovládacího registru najednou Nastavení ovládacího bitu odděleně (za jméno registru se přidá bits a tečka) A1B14MIS Mikroprocesory pro výkonové systémy 07 26
Programovací jazyk C oživení systému přerušení U mikrokontroleru PIC18F87J11 lze použít buď jednoúrovňový (neprioritní) systém přerušení nebo dvouúrovňový systém (nižší a vyšší priorita). V laboratoři budeme používat dvouúrovňový systém (viz následující snímek) Tento mikrokontroler má mnoho zdrojů přerušení, ale jen dvě hladiny priority. Libovolný zdroj přerušení (např. časovač) lze připojit do libovolné z těchto dvou hladin priority. Pokud je do jedné hladiny připojeno více zdrojů přerušení v obsluze přerušení (ISR Interrupt Service Routine) je nutné programově testovat, který z připojených zdrojů žádá o obsluhu. IPEN - Dvouhladinový systém přerušení se zvolí nastavením bitu IPEN = 1 (viz. též následující snímek). xif - Každý zdroj přerušení má (v některém ovládacím registru) bit žádosti o přerušení. Jméno tohoto bitu končí na IF (Interrupt flag), bit se nastavuje harwareově, ale nulovat v ISR ho musí program. xip Tímto bitem se voli připojení do jedné ze dvou hladin priority xie (Interrupt Enable) povoluje přerušení od určitého zdroje GIEL, GIEH připojují povolené zdroje přerušení do prioritního kodéru. Oba bity musí být aktivní (tj. = 1) A1B14MIS Mikroprocesory pro výkonové systémy 07 27
Programovací jazyk C oživení systému přerušení High Priority Enable Priority System On Low Priority Enable Interrupt Priority Interrupt Enable Interrupt Flag (Request) A1B14MIS Mikroprocesory pro výkonové systémy 07 28
Programovací jazyk C příklad přerušení od TIMER0 Příklad na následujících snímcích demonstruje: Přerušení od TIMER0 Aktivní vyšší priorita Způsob vyplnění tabulky vektorů přerušení (1), (2). Vyplnění nelze použít přímo v C, provede se použitím tzv Inline assembleru kterému kompilátor C rozumí viz _asm _endasm Způsob deklarace ISR tj funkcí, které jsou volány pomocí přerušení (3) (4) Naprogramování zvoleného módu TIMER0 Připojení TIMER0 do vyšší hladiny přerušení Aktivace systému přerušení (GIEL, GIEH). Nastavení těchto dvou bitů musí být vždy poslední po nastavení všech ostatních parametrů Program na pozadí (background loop) je v tomto případě prázdný (main) a procesor čeká na žádost o přerušení od TIMER0 a v čase mezi tím nedělá nic (točí se v prázdné smyčce) Příznaky žádosti o přerušení se nastaví v hardware, nulovat se musí programově (viz ISR) A1B14MIS Mikroprocesory pro výkonové systémy 07 29
Programovací jazyk C příklad přerušení od TIMER0 Příklad 1 část A1B14MIS Mikroprocesory pro výkonové systémy 07 30
Programovací jazyk C příklad přerušení od TIMER0 Příklad 2 část A1B14MIS Mikroprocesory pro výkonové systémy 07 31
Programovací jazyk C příklad přerušení od TIMER0 Příklad 3 část ISR pro vyšší a nižší prioritu přerušení Tabulka vektorů přerušení A1B14MIS Mikroprocesory pro výkonové systémy 07 32
MIKROPROCESORY PRO VÝKONOVÉ SYSTÉMY Stručný úvod do programování v jazyce C 2.díl KONEC České vysoké učení technické Fakulta elektrotechnická A1B14MIS Mikroprocesory pro výkonové systémy 07 33