Programování mikropočítačů Programování HCS08 v jazyku C
Mikropočítač M9S08GB60 Základní vlastnosti –8 bitová centrální procesní jednotka HCS08, taktovací frekvence max. 40MHz –60KB FLASH paměti –4KB RAM paměti –56 vstupně/výstupních linek na 7 portech (porty A-G) –5 kanálový TPM2 časovač –3 kanálový TPM1 časovač –1x Synchronní sériové periferní rozhraní (SPI) –1x I2C rozhraní –2x Asynchronní sériové komunikační rozhraní (SCI)
Mikropočítač M9S08GB60 Základní vlastnosti – pokračování Interní generátor hodinového kmitočtu s FLL obvodem (32KHz – 20MHz frekvence sběrnice) 8 kanálový, 10 bitový A/D převodník COP watchdog systém s nastavitelnou časovou prodlevou na 2 18 nebo 2 13 cyklů sběrnice Systém kontroly napájecího napětí umožňující detekovat pokles napětí pod stanovenou mez Podpora režimů se sníženou spotřebou umožňující nasazení v bateriově napájených aplikacích BDM rozhraní pro pokročilé ladění a programování aplikací přímo v aplikaci
Paměťová mapa Chráněná FLASH s programem „Monitor“ Uživatelské vektory přerušení Uživatelská flash paměť Registry periferních obvodů Flash paměť Interní paměť RAM Registry periferních obvodů $0000 $007F $0080 $107F $1080 $17FF $1800 $182B $182C $FBCB $FBCC $FBFF $FC00 $FFFF 4KB 1920B 57KB
Programování mikropočítače HCS-08 Vytvoření programu na PC Překlad (kompilace) Nahrání do mikropočítače přes sériovou linku (RS232) Vývojové prostředí CodeWarrior for HC(S)-08 Dostupné zdarma na
Spuštění CodeWarrior IDE Vytvořit nový projekt
Vytvoření projektu v C 1. Vybereme C zde 2. Napíšeme jméno projektu 3. Vybereme umístění projektu
Výběr typu mikropočítače Výběr příslušného typu mikropočítače (GB60) a připojení 1.Výběr cílového mikropočítače 2.Výběr připojení mikropočítače 3.Kliknutím na „Dokončit“ ukončíme průvodce
Kostra programu v C Direktiva #include = vložení souboru Funkce main = hlavní program
Program – aritmetické operace Definice proměnných Kód programu
Překlad a spuštění (ladění) programu Přeložit program Spustit a ladit program v simulátoru 1.Kompilace: překlad algoritmu zapsaného v programovacím jazyce do strojového kódu. 2.Spustit a ladit program: zavedení programu do cílového mikropočítače (nebo simulátoru) a jeho následné spuštění Sestavení (Make) Ladění (Debug)
Běh programu v simulátoru Tlačítka pro krokování programu Zdrojový kód Proměnné Kód v paměti Registry procesoru Obsah paměti
Program 2 – podmínky a cyklus void main(void) { int c1 = 5; int c2 = 3; int vetsi; int i; int M[5];// definice pole M o 5-ti prvcích EnableInterrupts; /* enable interrupts */ /* include your code here */ // ulozi vetsi z obou cisel do promenne vetsi if ( c1 > c2 ) vetsi = c1; else vetsi = c2; // Vynuluje pole M for ( i = 0; i< 5; i++ ) { M[i] = 0; // i-tý prvek pole M = 0 } for(;;) { __RESET_WATCHDOG(); /* feeds the dog */ } /* loop forever */ } Program Program určuje, které z čísel c1 a c2 je větší, to pak uloží do proměnné vetsi. Druhá část programu nuluje pole M o pěti prvcích.
Vývojový kit Slouží pro testování a ladění aplikací, pro výuku programování. Je osazen základními periferiemi jako LED diody, tlačítka, displej, sériová rozhraní Připojen přes sériovou linku RS 232 k PC, na kterém se program napíše a přeloží Program je poté odeslán do mikropočítače na kitu a spuštěn Je možno krokovat obdobně jako v režimu simulace
Vývojový kit Freescale M68EVB908GB60 COM1 sériový port COM2 sériový port Napájení 9V Tlačítko IRQTlačítko RESET LCD displej 2x16 znaků RS422/485 konektor Vypínač napájení 4x tlačítko SW1 – SW4 Potenciometr Bzučák 4x LED indikátor Mikropočítač M9S08GB60 Kontaktní nepájivé pole
Binární výstupy – LED diody LED diody jsou připojeny na port F LED1 – PTF0, LED2 – PTF1 LED3 – PTF2, LED4 – PTF3 Port je řízen pomocí 3 registrů: PTFD – datový registr portu F, při jeho načtení získáme stav pinů portu, zápisem změníme stav výstupních pinů. PTFDD – řídicí registr portu F, slouží pro konfiguraci jednotlivých pinů do vstupního nebo výstupního režimu. (0=vstupní, 1=výstupní režim) PTFPE – registr pro aktivaci interních „pull-up“ rezistorů (0=pull-up deaktivován, 1=pull-up aktivován).
Binární výstupy – LED diody Zjednodušené schéma zapojení: Port F PTFD_bit0 PTFD_bit1 PTFD_bit2 PTFD_bit3 +5V Ze schématu vyplývá, že LED dioda svítí, pokud je na příslušném pinu portu logická 0. Při logické 1 dioda nesvítí. LED4 LED3 LED2 LED1
Programová obsluha diskrétních vstupů a výstupů Definice registrů portů, časovače atd. viz #include „derivative.h“ -> #include Např. port F (LED), datový registr: PTFD = byte, tj. celý port F nebo PTFD_PTFD0, PTFD_PTFD1… = jednotlivé bity portu F Příklad použití: nastavit bit 0 portu F jako výstup. PTFDD = 0x01;// 0x01 = hexadecimální číslo = % nebo PTFDD_PTFDD0 = 1;
Program 3 - blikání LED Zadání: Vytvořte program, který bude blikat LED1. (LED1 je připojena na portu F, bit 0) Postup činnosti programu: 1)Nastavit bit 0 portu F jako výstup 2)Zapsat do něj 0 tj. rozsvítit LED 3)Počkat cca 0,5 s 4)Zapsat do bitu 0 portu F log. 1 tj. zhasnout LED
Vytvoření projektu 1.Výběr cílového mikropočítače 2.Výběr připojení mikropočítače 3.Kliknutím na „Dokončit“ ukončíme průvodce Vybereme připojení HCS08 Serial Monitor, protože program budeme nyní nahrávat do skutečného mikropočítače na vývojovém kitu.
Zdrojový kód – blikání LED void main(void) { PTFPE = 0;// vypnuti pull-up rezistoru PTFDD_PTFDD0 = 1; // bit 0 portu F jako vystup EnableInterrupts; /* enable interrupts */ while (1) { PTFD_PTFD0 = 0; // rozsvitime LED1 cekej(); PTFD_PTFD0 = 1; // zhasneme LED1 cekej(); cekej(); } for(;;) { __RESET_WATCHDOG(); /* feeds the dog */ } /* loop forever */ } // Cekaci smycka void cekej() { int i; for (i = 0; i < 0xFFFF; i++ ) __RESET_WATCHDOG(); } Program bliká LED1 Zpoždění je realizováno pomocí čekací smyčky ve funkci cekej().
Příklad: nahrání do kitu Postup: 1)Stiskneme a stále držíme tlačítko SW4 2)Stiskneme a ihned uvolníme tlačítko RESET 3)Uvolníme tlačítko SW4 4)Klikneme na ikonu „Debug“ ve vývojovém prostředí, tím se zahájí nahrávání programu do paměti FLASH mikropočítače
Příklad: ladění v kitu Po prvním spuštění ladícího prostředí budete vyzváni k výběru připojeného mikropočítače. Pro správnou funkci musí být zvolen MC9S08GB60.
Displej Displej – jakákoliv jednotka určená pro zobrazování požadovaných dat. Např. televizor, počítačový LCD monitor, atd. Vlastnosti displeje kitu M68EVB908GB60 LCD, 2 řádky, 16 znaků na každém řádku Matice 5x7 bodů pro každý znak Připojen na portu G a E (PTG3-7, PTE6-7) Až 8 uživatelsky programovatelných znaků
Programová obsluha displeje 2 možnosti programové obsluhy: A) Přímé řízeníB) Pomocí ovladače Ovladač: programové vybavení pro práci s hardware, sada podprogramů pro práci s HW zařízením. Ovladač Displej Náš program Registry displeje Zápis kódů požadavků a adres dat do registrů Displej Náš program Registry displeje Požadavky typu vypiš text, smaž displej atd. (podprogramy)
Funkce pro práci s displejem void dinit (void) – provede inicializaci displeje př.: dinit(); void dcls (void) – vymazání displeje př.: dcls(); void setcursor (char radek, char sloupec) – nastavení kurzoru na požadovanou pozici př.: setcursor(1,10); void douta (char znak) – výstup znaku na displej př.: douta('A'); void dtext (char* string) – výstup textového řetězce na displej př.: dtext("testovaci text");
Práce s displejem v C Zadání: Vytvořte program, který vypíše na displej text „Ahoj Svete“ a na druhý řádek pak znaky U, T, B na pozice 3, 6 a 9. Budeme potřebovat soubory ovladače: disp_gb60.asm – zdrojový kód v assembleru disp_gb60.h – hlavičkový soubor pro C Vytvoříme tzv. „mixed project“ - assembler a C. Hlavičkový soubor disp_gb60.h totiž pouze definuje prototypy pro funkce ovladače napsané v assembleru. Program z C tedy bude volat funkce v assembleru.
Projekt pro práci s displejem
Vložení souborů ovladače 1. Zde vybrat disp_gb60.h a disp_gb60.asm 2. Tlačítkem přidat vybrané soubory do projektu
Program 4 - displej void main(void) { char znak = 'U'; char* text = "ahoj svete"; EnableInterrupts; /* enable interrupts */ /* include your code here */ asm_main(); /* call the assembly function */ dinit();// Inicializace despleje dcls();// Smazani displeje dtext(text); // vypis textoveho retezce setcursor(2,3);// nastaveni kurzoru na 2 radek, 3 sloupec douta(znak);// vypis znaku setcursor(2,6); douta('T'); znak = 'B'; setcursor(2,9); douta(znak); while(1) __RESET_WATCHDOG(); } #include /* for EnableInterrupts macro */ #include "derivative.h" /* include peripheral declars */ #include "main_asm.h" /*interface to the assembly #include "disp_gb60.h" // ovladac displeje
Binární vstupy – tlačítka Tlačítka jsou připojena na port A SW1 – PTA4, SW2 – PTA5 SW3 – PTA6, SW4 – PTA7 Port je řízen pomocí 3 registrů: PTAD – datový registr portu A, při jeho načtení získáme stav pinů portu, zápisem změníme stav výstupních pinů. PTADD – řídicí registr portu A, slouží pro konfiguraci jednotlivých pinů do vstupního nebo výstupního režimu. (0=vstupní, 1=výstupní režim) PTAPE – registr pro aktivaci interních „pull-up“ rezistorů (0=pull-up deaktivován, 1=pull-up aktivován).
Binární vstupy – tlačítka Zjednodušené schéma zapojení: Ze schématu vyplývá, že při stisknutém tlačítku je z portu přečtena 0. POZOR, musejí být aktivovány interní „pull-up“ rezistory (ve schématu zakresleny červeně), jinak je při rozepnutém tlačítku stav portu nedefinován !!! Port A PTAD_bit7 PTAD_bit6 PTAD_bit5 PTAD_bit4 GND SW1 SW2 SW3 SW4 +5V
Přerušení Přerušení: způsob jak procesor přinutit reagovat na vnější podmět – např. signál od vnějších zařízení (připravenost dat, stisk klávesy apod.). V reakci na přerušení procesor přeruší provádění právě běžícího programu a provede speciální podprogram přiřazený danému přerušení nazývaný obsluha přerušení. Příklady využití přerušení: Detekce stisku tlačítka (změna logické úrovně na portu) Uplynutí určitého času – od časovače Příchod dat – od sériového rozhraní Dokončení převodu – od analogově digitálního převodníku
Příklad - tlačítka a přerušení Zadání: Vytvořte program, který při stisku tlačítka SW1 zapne nebo vypne LED1. Pro detekci stisku tlačítka využijte přerušení klávesnice (KBI). Poznámka: obsluha přerušení v C je funkce označená klíčovým slovem interrupt.
Registry pro řízení KBI KBI Status and control register (KBI1SC) Řídicí a stavový registr KBI. Význam jednotlivých bitů: KBIMOD – nastavení režimu detekce 1 = úroveň a hrana 0 = pouze hrana KBIE – povolení přerušení klávesnice 1 = přerušení povoleno 0 = přerušení není generováno KBACK – zápisem 1 vynulujeme příznak KBF KBF – příznak přerušení KBI 1 = byla detekována hrana/úroveň 0 = nebyla detekována hrana/úroveň KBEDGx – výběr hrany pro detekci, KBI bity 4 až 7 1 = náběžné hrany / vysoké úrovně (log.1) 0 = sestupné hrany / nízké úrovně (log.0)
Registry pro řízení KBI KBI pin enable register (KBI1PE) Každý bit nastavuje zda je odpovídající pin „vstupem klávesnice“ nebo běžným vstupem / výstupem. KBIPE0 až KBIPE7: 1 = vstup klávesnice 0 = běžný I/O
Postup v programu Nastavit bit 4 portu A jako vstup (tlačítko SW1) Nastavit bit 0 portu F jako výstup (LED1) Nastavit řídící registr modulu KBI – povolit přerušení (v registru KBI1SC) Povolit použití bitu 4 na portu A jako vstupu KBI Při stisku tlačítka bude obvod KBI generovat přerušení a provede se naše obsluha – funkce kbi_int().
Program 5 - tlačítko void cekej(void); void MCU_init(void); /* Device initialization function declaration */ // definujeme globalni promennou jako ukazatel na funkci // a to na dane misto pameti (na adresuvektoru preruseni) // Do teto promenne nastavime adresu nasi funkce kbi_int interrupt void kbi_int(void);// prototyp funkce obsluhy preruseni void (*const = kbi_int; void main(void) { PTADD_PTADD4 =0; // bit 4 portu A jako vstup PTAPE_PTAPE4 = 0;// pull-up pro bit 4 zapnut PTFD = 0xFF; // zhasneme LED diody PTFDD_PTFDD0 = 1;// bit 0 portu F jako vystup PTFPE = 0x00;// pull-up vypnuty KBI1SC = 0x06;// nast. ridiciho reg. KBI - preruseni povoleno KBI1PE = 0x10;// povol pouziti bitu 4 portu A pro KBI EnableInterrupts; /* enable interrupts */ for(;;) { __RESET_WATCHDOG(); /* feeds the dog */ } /* loop forever */ } interrupt void kbi_int(void) { // priznak zpracovani preruseni KBI1SC_KBACK = 1; // pokud LED sviti, zhasnout if ( PTFD_PTFD0 == 0 ) PTFD_PTFD0 = 1; else PTFD_PTFD0 = 0; // jinak rozsvitit }
A/D převodník u HCS08 - vlastnosti A/D převodník: Analogově-digitální převodník (Analog-To-Digital Converter (ATD)) = elektronický obvod pro převod analogového signálu na číslicový Vlastnosti ATD u HCS-08: Rozlišení 8 nebo 10 bitů Doba převodu 14 mikrosekund Nastavení příznaku nebo vyvolání přerušení po dokončení převodu (vektor přerušení na adrese $FFD0) Multiplexer pro 8 vstupních kanálů Funkce A/D převodníku je sdílena s portem B Režim jednoho převodu nebo kontinuální převod (single or continuous)
Analogově-Digitální převodník ATDC ATD1SC ATD1PE ATDRH ATDRL 0 7 Multiplexer A/D Registry A/D převodníku Vstup Např. 0 až 3.3V Výstup 0 až 1024 pro 10-bitový převodník Port B 1 Schéma A/D převodníku
Programová obsluha A/D převodníku Nastavení vstupů pro A/D převodník Nastavení převodníku (kanál, režim) a start převodu Čekání na dokončení převodu v případě, že není použita signalizace dokončení převodu pomocí přerušení Zpracování výsledku
Příklad – A/D převod Zadání: Vytvořte program, který rozsvítí 0 až 4 LED diody v závislosti na nastavení potenciometru na vývojovém kitu. Princip: Hodnotu nastavenou potenciometrem budeme snímat pomocí A/D převodníku ve smyčce a podle její velikosti rozsvítíme příslušný počet LED. Potenciometr je připojen na vstupu AD0 (kanál 0 A/D převodníku), tj. bit 0 portu B.
Program 6 – A/D převodník void cekej(void); void MCU_init(void); void main(void) { /* Uncomment this function call after using Device Initialization to use the generated code */ EnableInterrupts; /* enable interrupts */ /* include your code here */ PTFD = 0xFF; // zhasneme LED diody PTFDD_PTFDD0 = 1;// bity 0 az 3 portu F jako vystupy PTFDD_PTFDD1 = 1; PTFDD_PTFDD2 = 1; PTFDD_PTFDD3 = 1; PTFPE = 0x00;// pull-up vypnuty ATD1C = 0xE4; // zapnuti prevodniku, 8 bit vysledek ATD1PE = 1; // pin PTB0 prepneme do rezimu // vstupu A/D prevodniku // opakujeme v nekonecne smycce... while ( 1 ) { ATD1SC = 0;// start prevodu, jednorazovy, kanal 0 while (ATD1SC_CCF == 0) //(ATD1SC & 0x80)==0) ; // zpracuj vysledek prevodu (ATD1RH) PTFD = 0xFF; // zhasni vsechny LED if ( ATD1RH > 50 ) PTFD_PTFD0 = 0; // LED1 on if ( ATD1RH > 100 ) PTFD_PTFD1 = 0; // LED2 on if ( ATD1RH > 150 ) PTFD_PTFD2 = 0; // LED3 on if ( ATD1RH > 200 ) PTFD_PTFD3 = 0; // LED4 on cekej(); } for(;;) { __RESET_WATCHDOG(); /* feeds the dog */ } /* loop forever */ } // main void cekej(void) { int i; for ( i= 0; i<6000; i++ ) __RESET_WATCHDOG(); }
Náměty pro samostatné cvičení Program 1: Vypište na displej velikosti datových typů int a char. Použijte příkaz sizeof pro zjištění této velikosti, např. sizeof(char). Program 2: Vytvořte program, který při stisku tlačítka SW1 vypíše na displej text „stisknuto tl. 1“, při stisku SW2 text „stisknuto tl. 2“ atd. Použijte přerušení od klávesnice (KBI) jako v ukázkovém programu.
Konec Zvládli jste základy programování HCS08 v C