Hlavní program
Hlavní program je uložen ve zdrojovém souboru main.c. První funkce, která je v hlavním programu volána, mcu_init(), provádí nejnutnější inicializaci mikrokotroléru, abychom mohli blikat LED diodou. Po inicializaci následuje nekonečný cyklus, který obsahuje příkaz pro přepnutí LEDky a volání funkce krátké prodlevy.
#include "lm3s800.h" #include "mcu_init.h" #include "helpers.h" #define BLINK_DELAY 1000000 #define LED_PIN_ADDR (GPIO_PORTA_BASE + GPIO_O_DATA + (GPIO_PIN_5 << 2)) int main (void) { mcu_init(); while (1) { MM_REG(LED_PIN_ADDR) = MM_REG(LED_PIN_ADDR) ? 0 : GPIO_PIN_5; short_delay(BLINK_DELAY); } return 0; }
Symbol GPIO_PORTA_BASE definuje bázovou adresu registrů GPIO portu A, symbol GPIO_O_DATA je offset datového registru. Oba symboly jsou definovány v hlavičkovém souboru lm3s800.h. Makro MM_REG je také definováno v hlavičkovém souboru lm3s800.h. Umožnuje nám číst nebo zapisovat do paměťově mapovaných registrů periferií mikrokontroléru. V souboru jsou definována tři podobná makra, pro přístup k celému 32-bitovému slovu, 16-bitovému půlslovu a bajtu.
/* Memory mapped register macro - 32-bit word */ #define MM_REG(addr) (*((volatile unsigned long *)(addr))) /* Memory mapped register macro - 16-bit halfword */ #define MM_REGH(addr) (*((volatile unsigned short *)(addr))) /* Memory mapped register macro - 8-bit byte */ #define MM_REGB(addr) (*((volatile unsigned char *)(addr)))
Funkce mcu_init(), kterou inicializujeme mikrokontrolér, je uložena v samostatném zdrojovém souboru mcu_init.c. Nejdříve funkce provede nastavení hodinového signálu procesoru a potom povolí používání GPIO portu A.
static void sysclk_init(void); static void gpio_init(void); void mcu_init(void) { sysclk_init(); gpio_init(); }
Aby byl zápis programu čitelnější, nadefinujeme si konstanty, které popisují obsah systémových řídících registrů. Adresy samotných registrů jsou definovány v hlavičkovém souboru lm3s800.h.
SYSCTL_RCC je Run Mode Clock Configuration (RCC) registr, kterým se konfiguruje generování hodinových pulsů procesoru.
/* SYSCTL_RCC register bit */ #define RCC_USESYSDIV 0x00400000 #define RCC_PWRDN 0x00002000 #define RCC_OEN 0x00001000 #define RCC_BYPASS 0x00000800 /* SYSCTL_RCC register values */ #define RCC_SYSDIV_4 0x01800000 #define RCC_XTAL_6MHZ 0x000002C0 #define RCC_OSCSRC_MAIN 0x00000000 /* SYSCTL_RCC register mask */ #define RCC_XTAL_M 0x000007C0 #define RCC_OSCSRC_M 0x00000030 #define RCC_SYSDIV_M 0x07800000
SYSCTL_RIS je Raw Interrupt Status (RIS) register, zobrazuje stav přerušení modulu System control. Budeme v něm testovat stav bitu, který indikuje restart PLL obvodu.
/* SYSCTL_RIS register bit */ #define RIS_PLLRIS 0x00000040
SYSCTL_RCGC2 je Run Mode Clock Gating Control Register 2 (RCGC2). Jeho bity zapínají periferie GPIO portů.
/* SYSCTL_RCGC2 register bit */ #define RCGC2_GPIOA 0x00000001