Komunikační rozhraní počítačů Seznámení s HW V rámci předmětu bude využíván vývojový kit STM3240G-EVAL společnosti ST Mictoelectronics, jež je osazen mikrokontrolérem STM32F457IG. Cílem cvičení je osvojit si znalost moderních, všeobecně používaných, sběrnic osobních počítačů a vestavných (embedded) zařízení z pohledu jejich vývojáře. V rámci cvičení si student prakticky osvojí práci s danou sběrnicí.
Použitý vývojový kit je na obrázku výše. Mikrokontrolér se k PC připojuje přes USB B konektor (na obrázku označen jako USB JTAG), pomocí kterého se programuje. Programátor je součástí PCB vývojového kitu a disponuje rozhraním JTAG a SWD. Z tohoto konektoru je možné vývojový kit i napájet. Dále je možné kit napájet i z externího síťového zdroje, zdroj napájení je třeba zvolit příslušným JUMPEREM na headeru označeném jako napájení. Pro napájení z USB konektoru je třeba použít propojku označenou STk, pro síťový napaječ použijte propojku PSU. GPIO LED označuje LED,
které je možné přímo řídit z aplikace a při vývoji je použijeme zejména pro účely ladění. Ladění je dále možné s použitím LCD. Pro naše aplikace dále využijeme konektory RJ-45 (označen jako Ethernet) a USB FS pro vývoj USB zařízení. LED je použita pro kontrolu připojení USB kabelu do konektoru. Pro práci s mikrokontrolérem použijeme především dva dokumenty – datasheet (popisuje elektrickou a hardwarovou část) a reference manual, který slouží programátorovi jako příručka pro práci s mikrokontrolérem. Dále je vhodné nahlédnout do schématu zapojení vývojového kitu a dokumentace ke knihovně pro ovládání periferií (GPIO, USB, USART, DMA, apod.) mikrokontroléru. Odkazy Vývojový kit: http://www.st.com/internet/evalboard/product/252216.jsp Stránky společnosti STM: http://www.st.com
Komunikační rozhraní počítačů Založení projektu Spusťte vývojové prostředí (IDE) IAR Embedded Workbench. Prostředí je volně šiřitelná verze, kterou je možné používat pro nekomerční účely. Jediné omezení této verze spočívá v nemožnosti generovat spustitelný kód větší než 32 kB, což je pro naši aplikaci zcela postačující.
Založte nový projekt volbou položky Project->Create New Project, budeme programovat v jazyce C a necháme si vygenerovat funkci main.
Uložte projekt do adresáře D:\USER_DATA\A4M38KRP\
\<projekt>\.ewp, název zvolte dle libosti.
Projekt je vytvořen, dále potřebujeme nastavit cílový procesor a parametry překladu programu. To učiníme pomocí volby Project->Options… Zvolte cílový procesor, ve verzi 6.4 zvolte podobný procesor, tedy STM32F405VG. Volbou procesoru zvolíme vhodný překladač a zároveň nastavení linkeru pro definici paměťových rozsahů.
Dále zvolíme Library: Normal, jedná se o hloubku implementace standardní knihovny C, především funkcí pro výpis. Vzhledem ke skutečnosti, že funkce printf je poměrně výpočetně náročná a na použitém MCU může dosti zdržovat, volíme úspornější variantu, která navíc ušetří místo v programové paměti. Velmi důležité je nastavení CMSIS, jedná se o inicializaci MCU prostřednictvím ASM souboru. Tento kód zajistí především volání funkce main po startu MCU a definuje vektor jednotlivých přerušení. My použijeme vlastní CMSIS, který získáme z webových stránek výrobce MCU. Z vlastního souboru (CMSIS) jednoduše vyčteme názvy přerušení, která jsou definována v příslušném vektoru.
Projekt je nakonfigurován, než však přejdeme k samotnému programování, přidáme do programu potřebné soubory. Jedná se o knihovnu pro obsluhu periferií a jádro CMSIS, obé je možno pořídit na webových stránkách výrobce mikrokontroléru, pro potřeby cvičení budou soubory dodány cvičícím. V projektu vytvořte novou skupinu souborů pomocí volby Project->Add Group… a přidejte do ní zdrojové soubory z adresáře STM32F4xx_StdPeriph_Driver/src a soubory
CMSIS/Device/ST/STM32F4xx/Source/Templates/iar/ startup_stm32f4xx.s CMSIS/Device/ST/STM32F4xx/Source/Templates/ system_stm32f4xx.c
Pravým tlačítkem myši nad danou skupinou souborů můžete dále přidávat soubory a podskupiny.
Komunikační rozhraní počítačů První program Nyní si představíme první program, ve kterém inicializujeme mikrokontrolér, nastavíme důležité periferie a demonstrujeme funkci na blikání LED diodami. Nejprve je třeba provést konfiguraci hodin mikroprocesoru a jeho periferií. To je provedeno v automaticky vygenerovaném souboru system_stm32f4xx.c, který jste již do projektu zahrnuli. Pro vlastní nastavení hodin může být tento soubor znovu vygenerován pomocí příslušné utility ze stránek výrobce mikrokontroléru. Z pedagogických důvodů zde ukážeme ruční konfiguraci hodin mikrokontroléru. Pro práci s mikrokontrolérem použijeme knihovnu periferií dodanou výrobcem. Pro pochopení struktury je ke knihovně dodán manuál, případně je možné používat komentovaný zdrojový kód a referenční příručku. Tento návod bude používat funkce bez jejich podrobnějších vysvětlení. V referenční příručce (Reference Manual) procesoru jsou hodiny popsány ve Figure 9. Clock Tree. Mikrokontrolér může být časován oscilátorem řízeným interním nebo externím krystalem. Externí krystal často bývá stabilnější, protože je vystárlý a díky větším rozměrům kmitá na nižším harmonickém kmitočtu. Sběrnici procesoru je možné časovat přímo kmitočtem oscilátoru řízeného interním (HSI) nebo externím (HSE) krystalem, případně je možné kmitočet upravit pomocí fázového závěsu (PLL). Od kmitočtu sběrnice procesoru (AHB) je odvozeno časování jednotlivých periferií, které jsou připojeny na sběrnice APB1 a APB2.
Další podstatný kmitočet je PLL48CK, který musí být 48 MHz. Tento kmitočet je určen pro časování USB periferie. Ve schématu je vyznačeno nastavení hodin, které použijeme v naší aplikaci. Nastavení hodin tedy znamená nastavit jednotlivé multiplexery, děličky a PLL.
V referenční příručce je možné nalézt vzorec pro výpočet jednotlivých hodin. Kmitočet fázověho závěsu je dán vztahem
na jehož základě je možné určit kmitočet AHB sběrnice
a kmitočet pro periferii USB
Jednotlivé konstanty , , a určují nastavení PLL. Vstupní frekvenci PLL je třeba zvolit na multiplexerem jako frekvenci odvozenou z externího krystalu. Dále ještě nastavení sběrnice AHB a APB
Konstanty
a
určují děličky pro časování sběrnic pro periferie.
Pro správnou funkci přidáme hlavičkový soubor #include "stm32f4xx_conf.h", který vkládá všechny hlavičkové soubory periferií. Zdrojový kód programu začneme voláním funkce RCC_HSEConfig s příslušným parametrem, který nastaví použití oscilátoru taktovaného externím krystalem. RCC_HSEConfig(RCC_HSE_ON); Dále je třeba nastavit děličky, které určí kmitočet sběrnic jednotlivých periferií. Jedná se o nastavení konstant a , přičemž je třeba respektovat maximální povolené frekvence jednotlivých sběrnic. Pro AHB je to 168 MHz, pro APB1 42 MHz a pro APB2 84 MHz. Parametry jednotlivých funkcí je možné nalézt v komentáři v souboru stm32f4xx_rcc.c. RCC_HCLKConfig( ??? ); RCC_PCLK1Config( ??? ); RCC_PCLK2Config(??? ); Dále je třeba nastavit PLL, pro určení konstant použijeme výše uvedené vzorce a opět se podíváme na komentář funkce. RCC_PLLConfig(RCC_PLLSource_HSE, ??? , ???, ???, ???);
Posléze povolíme PLL a počkáme na jeho stabilizaci. RCC_PLLCmd(ENABLE); while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == 0) ; Nakonec připojíme PLL na sběrnici AHB RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); Kmitočet krystalu určíme z jeho popisku, o který krystal se jedná zjistíme z elektrického schématu vývojového kitu. Dále je třeba nastavit periferie, které bude naše aplikace používat. Globálně je třeba periferie povolit. Pro to slouží funkce RCC_AHB1PeriphClockCmd, RCC_AHB2PeriphClockCmd, RCC_AHB3PeriphClockCmd, RCC_APB1PeriphClockCmd, RCC_APB2PeriphClockCmd. Popis jejich parametrů je opět možné nalézt v příslušném zdrojovém souboru, tedy stm32f4xx_rcc.c. Potřebujeme povolit periferie vstupně výstupních portů GPIOC, GPIOG a GPIOI, na kterých jsou připojeny LED, dále pak TIM2, což je časovač, který budeme využívat v naší aplikaci a dále GPIOA, což je brána, na které jsou piny USB periferie a samotná periferie USB pro komunikaci na Full-Speed OTG_FS. Volání bude vypadat následovně RCC_????PeriphClockCmd( ??? , ENABLE); Dále je třeba nastavit výstupní piny pro LED, na každý pin připojíme pull-up odpor a port nastavíme jako výstupní. Jedná se o piny G6, G8, I9 a C7. GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = ???; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init( ??? , &GPIO_InitStructure); Dále už pokračuje program v nekonečné smyčce, ze které nesmí nikdy vyskočit. LED si můžeme zkusit rozsvítit např. pomocí funkce
GPIO_WriteBit. V nekonečné smyčce potom můžeme pomocí aktivního čekání for (i=0; i??; i++) for (j=0; j??; j++) ; LED rozblikat. Aktivní čekání však zatěžuje procesor a ten nemůže provádět jiné operace, proto je vhodné v podobných aplikacích použít časovač, který nakonfigurujeme při inicializaci, posléze se bude pravidelně spouštět obsluha přerušení, ve které vždy změníme stav LED. Pro takovou to funkci nestačí pouze spustit časovač, ale zároveň je třeba nakonfigurovat přerušení. Pro přerušení naplníme strukturu NVIC_InitTypeDef NVIC_InitStructure; a zavoláme funkci NVIC_Init. Konfiguraci časovače provedeme pobně jako konfiguraci GPIO nastavením struktury TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; a voláním funkce TIM_TimeBaseInit. Dále již jen stačí povolit dané přerušení a spustit časovač TIM_ITConfig( ???, ???, ENABLE); TIM_Cmd( ??? , ENABLE); Implementace obsluhy přerušení od časovače probíhá ve funkci, jejíž název nalezneme v souboru startup_stm32f4xx.s. Hledáme IRQ Handler pro zvolený časovač. Funkce nemá žádný parametr a sama je typu void. V obluze přerušení je třeba krom změny stavu LED ještě ověřit, o jaké přerušení se týká (v našem případě jediné, nastavené ve funci TIM_ITConfig). Vynulováním určitého flagu je třeba procesoru oznámit, že jsme přerušení obsloužili a program může dále pokračovat v místě, kde byl přerušen. if (TIM_GetITStatus( ??? , ???) != RESET) { TIM_ClearITPendingBit(???, ???); // tady obsluha preruseni }